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
Argument 1 Has Unexpected Type 'Nonetype'
How to Use Pip with Python 3.X Alongside Python 2.X
Why Is Parenthesis in Print Voluntary in Python 2.7
How to Convert a Dataframe to a Dictionary
Isprime Function for Python Language
How to Interpret Conda Package Conflicts
Python Multiprocessing Safely Writing to a File
Using Python Iterparse for Large Xml Files
What Is the Internal Precision of Numpy.Float128
Read File Data Without Saving It in Flask
How to Make a Tkinter Window Jump to the Front
Why Do I Need 'B' to Encode a String with Base64
How to Decode Base64 Data in Python
Class Method Decorator with Self Arguments
How to Obtain the Element-Wise Logical Not of a Pandas Series