Python logging levels with rsyslog - python

I am trying to filter levels in rsyslog.d/conf files from the python logger but nothing is getting filtered.
import logging
import logging.handlers
if __name__ == "__main__":
logger = logging.getLogger()
logger.setLevel(logging.INFO)
fh = logging.handlers.RotatingFileHandler('./logtest.log', maxBytes=10240, backupCount=5)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.info('INFO')
logger.error('ERROR')
In my conf file I have:
*.=info -/var/log/info.log
But the info logs are not being logged to that file, any ideas why?

This has been solved. The issue did lie with syslog at all, I had issues in my program where is was not logging the levels correctly to the facility.
Aka: they were all being logged as warnings.

Related

Cannot log to stream in Python

I want to log to stream of io.StringIO, but end up with empty stream. Here is my code:
import logging, io
log_handler = logging.StreamHandler(stream)
log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log_handler.setFormatter(log_format)
log_handler.setLevel(logging.INFO)
logger.addHandler(log_handler)
logger.info("This is test info log")
print(stream.getvalue())
What am I doing wrong?
UPDATE
It seems to be working if I replace level with "Warning" like this
log_handler.setLevel(logging.WARNING)
logger.warning("This is test info log")
It also prints into console for some reason
Configure the root logger: logging.basicConfig(level=logging.DEBUG).
Then you can set log_handler.setLevel(logging.INFO) to whatever level you wish, it will capture logs to stream accordingly.

Python logger duplicate log messages

I have the following configuration for logger:
def setup_logger(self):
self.logger = logging.getLogger("root")
self.logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
logging.basicConfig(
format='%(asctime)s - %(message)s',
datefmt='%d-%b-%y %H:%M:%S'
)
self.logger.addHandler(ch)
I call the setup_logger() in the constructor(__init()) and I using the logger like
self.logger.info("Getting data from database")
Now the problem is, that it is showing the log message two times in the terminal when I execute the file. One is with the date and time and the other is without time. It is like the following screenshot
I only need to show the log message with the timestamp and don't need the other one. How can I get rid of the duplicate one? I tried to remove the self.logger.setLevel(logging.DEBUG), but then it is not showing any message. Please help.
import logging
logger = logging.getLogger("root")
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(message)s', '%d-%b-%y %H:%M:%S')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info("Getting data from database")
logger.info("Generating report for month - January")

python logs to both stdout and stderr

I am using python logging like this:
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger()
Everything works fine. only issue is that all log messages are printed to both stdout and stderr. stdout is formatted as I expect. stderr simply prints the message itself in error stream.
I see that log.handlers indeed contains 2 handlers. Removing the stderr one doesn't seem to have effect. Tried something like this:
for handler in log.handlers:
if handler.stream and handler.stream.name == '<stderr>':
log.handlers.remove(handler)
Any way around this issue?
You can use logging.StreamHandler()
like that:
logging.basicConfig(handlers=[logging.StreamHandler()], level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger()
If you also want to that certain level would go stderr (only Error or Error and Warning) and other stdout. you can do something like suggested here by #crosswired:
logger = logging.getLogger("__name__")
logger.setLevel(logging.DEBUG)
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(format)
h1 = logging.StreamHandler(sys.stdout)
h1.setLevel(logging.DEBUG)
h1.addFilter(lambda record: record.levelno <= logging.INFO)
h1.setFormatter(formatter)
h2 = logging.StreamHandler()
h2.setLevel(logging.WARNING)
h2.setFormatter(formatter)
logger.addHandler(h1)
logger.addHandler(h2)
logger.info("info")
logger.error("error")
Python logging split between stdout and stderr

How to create an error log file after an error in Python?

I'm writing a Python script and already use the logging library to log errors in my script, but I would like to create this error log file only after the error has appeared, can that be done?
Here's the code I have:
import logging
logger = logging.getLogger('my_app')
logger.setLevel(logging.INFO)
fh = logging.FileHandler("log.txt")
fh.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
try:
# my code
except:
logger.exception("my message")
import logging
formatter = logging.Formatter('%(asctime)s - %(message)s', datefmt='%d-%m-%y %H:%M:%S')
def setup_logger(name, log_file, setLevel):
"""To setup as many loggers as you want"""
handler = logging.FileHandler(log_file)
handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(level=setLevel)
logger.addHandler(handler)
return logger
error_log = setup_logger('error_logger', 'error.log', logging.ERROR)
err_log.error("ERROR YOU WANT TO PUT")
You can have the debug logger as logging.DEBUG and create as many logger with the function

Why is python ignoring my formatter in the console?

am working on a Python app that implements logger features
Here is my code which is taken form the official site:
import logging
#create logger
logger = logging.getLogger("simple_example")
logger.setLevel(logging.DEBUG)
#create console handler and set level to debug
fh = logging.RotatingFileHandler(MyFile, etc)
fh.setLevel(logging.DEBUG)
#create formatter
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s -
%(message)s")
#add formatter to fh
fh.setFormatter(formatter)
#add fh to logger
logger.addHandler(fh)
#"application" code
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
and here is the output in the File: which is perfect
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message
but here is the output in the terminal:
DEBUG: debug message
INFO: info message
WARNING: warn message
ERROR: error message
CRITICAL: critical message
that drives me crazy since i can not get to see the timestamp in the console...
I have tried too creating another handler:
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
and the adding it to logger...
but the only thing I get is that the logger in printing twice every msg in the console... one perfectly ok and the wrong one as I explained at begin
The console output can be adjusted separately using StreamHandler, for which you have to add the formatter as well:
#create console handler and set level to debug
fh = logging.RotatingFileHandler(MyFile, etc)
fh.setLevel(logging.DEBUG)
#create formatter
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s -
%(message)s")
#add formatter to fh
fh.setFormatter(formatter)
#add fh to logger
logger.addHandler(fh)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
logger.addHandler(ch)
Here is what I use for logging in a file and in the console:
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s\t%(message)s', datefmt='%m-%d %H:%M', filename=logfile, filemode='a')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
# set a format which is simpler for console use
formatter = logging.Formatter('%(asctime)s %(levelname)s\t%(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)
# Now, we can log to the root logger, or any other logger. First the root...
logging.info('LOGGING PATH: %s', logfile)
Then you can set the same output for both the file and the console.
A initialization in the basic configuration on the logger is necessary for that:
logging.basicConfig(streamä0sys.stdout, level=logging.INFO, format=myFormat)
where
myFormat= "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"

Categories