I'm using Python's logging module to log some debug strings to a file which works pretty well. Now in addition, I'd like to use this module to also print the strings out to stdout. How do I do this? In order to log my strings to a file I use following code:
import logging import logging.handlers logger = logging.getLogger("") logger.setLevel(logging.DEBUG) handler = logging.handlers.RotatingFileHandler( LOGFILE, maxBytes=(1048576*5), backupCount=7 ) formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler)
and then call a logger function like
logger.debug("I am written to the file")
Thank you for some help here!
Use logging Module to Print Log Message to a File in Python getLogger(name) method. There is a convention to use __name__ variable as the name of the logger. Once we have created a new logger, we should remember to log all our messages using the new logger.info() instead of the root's logging.info() method.
StreamHandler() function to write logs to the console window in Python. By passing sys. stdout to the logging. StreamHandler() function, we can create a stream handler that can print the log message to the console window.
Python - Print Logs in a File. If you want to print python logs in a file rather than on the console then we can do so using the basicConfig() method by providing filename and filemode as parameter. The format of the message can be specified by using format parameter in basicConfig() method.
logging - Making Python loggers output all messages to stdout in addition to log file - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.
Just get a handle to the root logger and add the StreamHandler
. The StreamHandler
writes to stderr. Not sure if you really need stdout over stderr, but this is what I use when I setup the Python logger and I also add the FileHandler
as well. Then all my logs go to both places (which is what it sounds like you want).
import logging logging.getLogger().addHandler(logging.StreamHandler())
If you want to output to stdout
instead of stderr
, you just need to specify it to the StreamHandler
constructor.
import sys # ... logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
You could also add a Formatter
to it so all your log lines have a common header.
ie:
import logging logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s") rootLogger = logging.getLogger() fileHandler = logging.FileHandler("{0}/{1}.log".format(logPath, fileName)) fileHandler.setFormatter(logFormatter) rootLogger.addHandler(fileHandler) consoleHandler = logging.StreamHandler() consoleHandler.setFormatter(logFormatter) rootLogger.addHandler(consoleHandler)
Prints to the format of:
2012-12-05 16:58:26,618 [MainThread ] [INFO ] my message
logging.basicConfig()
can take a keyword argument handlers
since Python 3.3, which simplifies logging setup a lot, especially when setting up multiple handlers with the same formatter:
handlers
– If specified, this should be an iterable of already created handlers to add to the root logger. Any handlers which don’t already have a formatter set will be assigned the default formatter created in this function.
The whole setup can therefore be done with a single call like this:
import logging logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[ logging.FileHandler("debug.log"), logging.StreamHandler() ] )
(Or with import sys
+ StreamHandler(sys.stdout)
per original question's requirements – the default for StreamHandler is to write to stderr. Look at LogRecord attributes if you want to customize the log format and add things like filename/line, thread info etc.)
The setup above needs to be done only once near the beginning of the script. You can use the logging from all other places in the codebase later like this:
logging.info('Useful message') logging.error('Something bad happened') ...
Note: If it doesn't work, someone else has probably already initialized the logging system differently. Comments suggest doing logging.root.handlers = []
before the call to basicConfig()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With