Making Python Loggers Output All Messages to Stdout in Addition to Log File

Making Python loggers output all messages to stdout in addition to log file

All logging output is handled by the handlers; just add a logging.StreamHandler() to the root logger.

Here's an example configuring a stream handler (using stdout instead of the default stderr) and adding it to the root logger:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)

Simplest way to set up python logging to stdout

If you just need to print the messages to the stdout, then logging.basicConfig is a handy shortcut for the configuration you listed. It will create a StreamHandler, attach the default Formatter to it and attach the handler to the root logger.

import logging

logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
logging.getLogger().info('hi')

Check out the docs for more configuration possibilities; for example,

logging.basicConfig(filename='some.log', level=logging.DEBUG)

will configure writing to file some.log instead of stdout.

Note that logging.basicConfig won't do a thing if the logger is already configured (meaning that there are handlers attached to the root logger already). So this code:

import logging

logging.getLogger().addHandler(logging.FileHandler(filename='some.log'))
logging.basicConfig(level=logging.DEBUG)

will not configure logging to stdout anymore; you will have to do it yourself.

logger configuration to log to file and print to stdout

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

Transfering logging output both to console and log file

Your logger setup is correct, but maybe you are not logging anything at log level INFO. Example, as below:


import logging
import sys
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.FileHandler("debug.log"),   # log to file
        logging.StreamHandler(sys.stdout)   # log to console
    ]
)
logging.debug("This is a debug message")
logging.info("This is an info message")
logging.warning("This is a warning message")
logging.error("This is an error message")
logging.critical("This is a critical message")
logging.shutdown()

This will display generated logs to stdout as well as save them to debug.log file.

Console output:

Debug.log file:

how to Create log file for all commands in one file using python

Instead using print, you can use logger. You can view the output in console and at the same time, Log will datewise will be generated in Log folder.

import logging
import logging.handlers as handlers
import subprocess
import datetime
import os

logger = logging.getLogger("PMAX-Lun-Allocation")
logger.setLevel(logging.DEBUG)

# maintains log file here # maintains log file here
Log = os.path.join(os.path.dirname(os.path.realpath(__file__)), "Log")
if not os.path.exists(Log):
os.mkdir(Log)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# logHandler = handlers.TimedRotatingFileHandler(os.path.join(Log, datetime.datetime.now(
# ).strftime('log_file_%Y_%m_%d.log')), when='midnight', backupCount=10)
logHandler = handlers.RotatingFileHandler(
os.path.join(Log, datetime.datetime.now().strftime("log_file_%Y_%m_%d.log")),
maxBytes=5000000,
backupCount=10,
)
logHandler.setLevel(logging.DEBUG)

# create a logging format
formatter = logging.Formatter(
"%(asctime)s: [%(thread)d]:[%(name)s]: %(levelname)s:[PMAX-Lun-Allocation] - %(message)s"
)
logHandler.setFormatter(formatter)
ch.setFormatter(formatter)

# add the handlers to the logger

logger.addHandler(logHandler)
logger.addHandler(ch)

logger.debug("Starting the PMAX Lun-Allocation scrict using Python............")
# step1
sid = input("Please enter the Array SID:")
prebackup = input("Please enter the backup which is to backed up before the process:")
logger.debug(f"Starting the backup Command is : symaccess -sid {sid} -f {prebackup}")
command1 = "symaccess -sid {sid} -f {prebackup} backup"
process = subprocess.run(command1, shell=True)
command1

# step2
logger.debug(f"Listing the all availble devices for sid {sid}............")
listfile = input(
"Please enter the text file name where the list of Luns should be stored"
)
logger.debug(
f"Starting the listing Command is : symdev -sid {sid} list -all > {listfile}"
)
command2 = f"symdev -sid {sid} list -all > {listfile}"
process = subprocess.run(command2, shell=True)
command2

# step3
logger.debug("creating Tdev")
tdevfile = input("Please enter Tdev file name:")
logger.debug(f"Running Command : symconfigure -sid {sid} -f {tdevfile} preview -v")
command3 = f"symconfigure -sid {sid} -f {tdevfile} preview -v"
process = subprocess.run(command3, shell=True)
command3

Python Logger : StreamHandler not controlling my terminal stdout?

It seems it is related to the fact that I have multiple modules - each module can have a logger to console, but the main script must remain in control and have its own logger set (which I did not have).
This page solved my problem: https://docs.python.org/3/howto/logging-cookbook.html#logging-to-multiple-destinations



Related Topics



Leave a reply



Submit