Python logging and dynamic logfile name

Viewed 178

I'm trying to make a log per day in python3 using logging module.
I'm aware of the TimedRotatingFileHandler module but it doesn't work as I need, it stores the data in a fixed name file and renamed it based on a suffix.
I need to define the log filename for each message based on the date.
What I implemented does not work. The logfile is created with the right name, but next day, the new one is not created and logs still get written in the old file.
Here is what I do:

import logging ,coloredlogs,platform
import sys,os
from datetime import datetime
FORMATTER = logging.Formatter("%(asctime)s : %(hostname)s : %(name)s : %(levelname)s : %(message)s")
LOG_FILE = os.environ['RMQ_DISPACHER_LOGFILE']
NICKNAME = os.environ['LOGNICKNAME']

class HostnameFilter(logging.Filter):
    hostname = platform.node()
    def filter(self, record):
        record.hostname = HostnameFilter.hostname
        return True

def get_console_handler():
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.addFilter(HostnameFilter())
    console_handler.setFormatter(FORMATTER)
    return console_handler

def get_file_handler():
    file_handler = logging.FileHandler( "%s/%s_%s.log" % (LOG_FILE,NICKNAME,datetime.now().strftime('%Y%m%d')) )
    file_handler.addFilter(HostnameFilter())
    file_handler.setFormatter(FORMATTER)
    return file_handler

def get_logger(logger_name):
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(get_console_handler())
    logger.addHandler(get_file_handler())
    logger.propagate = False
    coloredlogs.install(logger=logger)
    return logger

I'm wondering whether it's possible to log to "%s/%s_%s.log" % (LOG_FILE,NICKNAME,datetime.now().strftime('%Y%m%d')) using the logging module.

Thanks.

1 Answers

You have to use TimedRotatingFileHandler, and set the when parameter.

tools/log.py module excerp:

import datetime, logging, platform
import logging.handlers

# set default rootdir for logs and the splitter win/linux, 
rootdir = None
splitter = None
if platform.os=='Windows':
    splitter = "\\"
    rootdir = "C:\\SharedArea\\reports"
else:
    rootdir = "/tmp"
    splitter = "/"

# add rotating filehandler when we need it
def add_rotating_handler(loggername:str, rootdir:str=rootdir, name:str="test.log", format="%Y%m%d%H%M", level:int=logging.DEBUG, when:str=None):
    """ add a timed rotating filehandler """
    if not when:
        when = 'D'
    fh = logging.handlers.TimedRotatingFileHandler(rootdir + splitter + name,  when=when)
    fh.suffix = format
    fh.setLevel(level)
    fh.setFormatter(logging.Formatter(file_fmt, datefmt))
    logging.getLogger(loggername).addHandler(fh)

test-program:

#!/usr/bin/env python3
import datetime, logging, os, time, tools.log

logname = 'root.tools.' + os.path.basename(__file__).split(',')[0]
tools.log.add_rotating_handler(logname, rootdir="c:\\temp\\", format="%Y%m%d%H%M", name="NICKNAME", when='M')
log = logging.getLogger(logname)
try:
    while True:
        log.info(f"time is now:{datetime.datetime.now()}")
        time.sleep(10)
except KeyboardInterrupt as e:
    pass

and in temp:

PS C:\temp> ls  
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        11/16/2021   4:43 PM            522 NICKNAME.202111161642
-a----        11/16/2021   4:44 PM            522 NICKNAME.202111161643
-a----        11/16/2021   4:45 PM            522 NICKNAME.202111161644
-a----        11/16/2021   4:46 PM            522 NICKNAME.202111161645
Related