How to display date format using Python logging module - python

I am trying to setup a format for logging in python:
import logging,logging.handlers
FORMAT = "%(asctime)-15s %(message)s"
logging.basicConfig(format=FORMAT,level=logging.INFO)
logger = logging.getLogger("twitter")
handler = logging.handlers.RotatingFileHandler('/var/log/twitter_search/message.log', maxBytes=1024000, backupCount=5)
logger.addHandler(handler)
Basically, logging works, but without the date format...

You can add the datefmt parameter to basicConfig:
logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%Y-%m-%d %H:%M:%S')
Or, to set the format for the Rotating FileHandler:
fmt = logging.Formatter(FORMAT,datefmt='%Y-%m-%d')
handler.setFormatter(fmt)

Basic example:
import logging
logging.basicConfig(
format='%(asctime)s %(levelname)s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S'
)
logging.info('Just a random string...')
# 2030-01-01 00:00:00 INFO Just a random string...
If you want to adjust the line spacing between levelname and message change the %(levelname)s like the example:
... %(levelname)-10s ...
# 2030-01-01 00:00:00 INFO Just a random string...

Related

Microsecond do not work in Python logger format

For some reason my Python logger does not want to recognize microseconds format.
import logging, io
stream = io.StringIO()
logger = logging.getLogger("TestLogger")
logger.setLevel(logging.INFO)
logger.propagate = False
log_handler = logging.StreamHandler(stream)
log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',"%Y-%m-%d %H:%M:%S.%f %Z")
log_handler.setFormatter(log_format)
logger.addHandler(log_handler)
logger.info("This is test info log")
print(stream.getvalue())
It returns:
2023-01-06 18:52:34.%f UTC - TestLogger - INFO - This is test info log
Why are microseconds missing?
Update
I am running
Python 3.10.4
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye
The issue is that the formatTime method uses time.strptime to format the current time.time(), but since struct_time has no information about milliseconds and microseconds the formatter ignores the %f.
Also, note that the LogRecord calculates the milliseconds separately and stores them in another variable named msecs
To get what you're looking for we need a custom version of the Formatter class that uses a different converter than time.localtime and is able to interpret the microseconds:
from datetime import datetime
class MyFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
if not datefmt:
return super().formatTime(record, datefmt=datefmt)
return datetime.fromtimestamp(record.created).astimezone().strftime(datefmt)
...
log_format = MyFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S.%f %Z")
...
Should output:
2023-01-06 17:47:54.828521 EST - TestLogger - INFO - This is test info log
I found that the answer given by Ashwini Chaudhary to not be applicable for me and found a slightly simpler solution in creating a function with the formatting as done with datetime and changing the value of the logging.Formatter.formatTime method to this instead i.e.:
def _formatTime(self, record, datefmt: str = None) -> str:
return datetime.datetime.fromtimestamp(record.created).astimezone().strftime(datefmt)
log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',"%Y-%m-%d %H:%M:%S.%f %Z")
logging.Formatter.formatTime = _formatTime
And then generating your logger as normal

Why I can't use different log levels in Python?

I want to use different log levels. For example I need to log actions as INFO if everyting is OK, and WARNING when the required action is NOT proceeded OK (or ERROR, FATAl etc. it doesn't matter right now). How can I reach it? Basically I need just 2 levels, but unfortunately if I am trying to use 2 levels then my log file created as empty. Below is my code but it doesn't work and log file created empty.
class Logger:
#staticmethod
def info_logger(logLevel=log.INFO):
logger_name = inspect.stack()[1][3]
logger = log.getLogger(logger_name)
logger.setLevel(logLevel)
fh = log.FileHandler(log_file)
formatter = log.Formatter("%(asctime)s - %(levelname)s - %(message)s", datefmt='%m/%d/%Y %I: %M: %S %p')
fh.setFormatter(formatter)
logger.addHandler(fh)
return logger
#staticmethod
def warning_logger(logLevel=log.WARNING):
logger_name = inspect.stack()[1][3]
logger = log.getLogger(logger_name)
logger.setLevel(logLevel)
fh = log.FileHandler(error_log_file)
formatter = log.Formatter("%(asctime)s - %(levelname)s - %(message)s", datefmt='%m/%d/%Y %I: %M: %S %p')
fh.setFormatter(formatter)
logger.addHandler(fh)
return logger

Logging issues with python logging module

I am using python logging module. I am initialising file having following data
def initialize_logger(output_dir):
'''
This initialise the logger
:param output_dir:
:return:
'''
root = logging.getLogger()
root.setLevel(logging.INFO)
format = '%(asctime)s - %(levelname)-8s - %(message)s'
date_format = '%Y-%m-%d %H:%M:%S'
if 'colorlog' in sys.modules and os.isatty(2):
cformat = '%(log_color)s' + format
f = colorlog.ColoredFormatter(cformat, date_format,
log_colors={'DEBUG': 'green', 'INFO': 'green',
'WARNING': 'bold_yellow', 'ERROR': 'bold_red',
'CRITICAL': 'bold_red'})
else:
f = logging.Formatter(format, date_format)
#ch = logging.FileHandler(output_dir, "w")
ch = logging.StreamHandler()
ch.setFormatter(f)
root.addHandler(ch)
As there is only one streamHandler, But I am getting two prints on my console as
INFO:root:clearmessage:%ss1=00
2017-12-21 17:07:20 - INFO - clearmessage:%ss1=00
INFO:root:clearmessage:%ss2=00
2017-12-21 17:07:20 - INFO - clearmessage:%ss2=00
Every message is printed as Root and Info. Any idea Why I am getting two prints. In the above code you can ignore color code.
You have two handlers. Clear the handlers before you add a new one:
root.handlers = [] # clears the list
root.addHandler(ch) # adds a new handler

Python Logging. Messages are with the same date

I get log messages with the same date when I print them to the console (or logfile). But the time-out between messages is two seconds. Here is my code
folder = "logs"
log_name = {}.log
file_name = os.path.join(folder, log_name)
date_format = "%Y-%m-%d_%H:%M:%S"
name_format = "[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)s] - %(message)s"
log = logging.getLogger('')
log.setLevel(logging.DEBUG)
format = logging.Formatter(name_format, datetime.now().strftime(date_format))
console_handler = logging.StreamHandler(sys.stderr)
file_handler = handlers.RotatingFileHandler(filename=datetime.now().strftime(file_name.format(date_format)),
maxBytes=(1048576*5),
backupCount=7)
console_handler.setFormatter(format)
file_handler.setFormatter(format)
log.addHandler(console_handler)
log.addHandler(file_handler)
from time import sleep
log.info("1")
sleep(2)
log.info("2")
sleep(2)
log.info("3")
Here is output:
[2017-07-08_17:20:51] [INFO] [logs.py:112] - 1
[2017-07-08_17:20:51] [INFO] [logs.py:114] - 2
[2017-07-08_17:20:51] [INFO] [logs.py:116] - 3
have a look at the documentation of logging.Formatter(fmt=None, datefmt=None, style='%'). the second argument you need to pass is a datefmt ("%Y-%m-%d_%H:%M:%S" in your case). the logger will do the fmt.strftime(...) for you.
you are passing a string that represents datetime.now() in this format. as this is a str (e.g. '2017-07-08_17:20:51') the formatter does not complain but always prints this exact date: '2017-07-08_17:20:51'.strftime(...) will result in '2017-07-08_17:20:51' - there are no format specifiers to fill in.
what you should do is this:
fmt = logging.Formatter(name_format, date_format)
# instead of
# format = logging.Formatter(name_format, datetime.now().strftime(date_format))
(btw: format is a built-in; renamed your formatter to fmt such that the built-in is not overwritten).

Unable to add a timestamp to a logger in Python 3.5

My logger:
logging.basicConfig(filename="{}/log.log".format(config.log_dir), level=logging.DEBUG, format="%(asctime)s %(message)s", datefmt="%d-%b-%Y %I:%M:%S" )
And .. no timestamp is getting added:
logging.info("fdsfdsfds")
# => fdsfdsfds
This works for me
That's my output
import logging
FORMAT = '%(asctime)s %(message)s'
DATE = '%d-%b-%Y %I:%M:%S'
logging.basicConfig(filename="log.log",level=logging.DEBUG,format=FORMAT,datefmt=DATE)
logger = logging.getLogger('Stackoverflow log')
logger.info('Info 1')
If you still get no timestamp please add more code

Categories