flybonzai
flybonzai

Reputation: 3931

Logging module not writing to file

I'm using logging module, and I've passed in the same parameters that I have on other jobs that are currently working:

import logging
from inst_config import config3

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] - %(message)s',
    filename=config3.GET_LOGFILE(config3.REQUESTS_USAGE_LOGFILE))
logging.warning('This should go in the file.')

if __name__ == '__main__':
    logging.info('Starting unload.')

Using this method to create the filename:

REQUESTS_USAGE_LOGFILE = r'C:\RunLogs\Requests_Usage\requests_usage_runlog_{}.txt'.format(
        CUR_MONTH)
def GET_LOGFILE(logfile):
    """Truncates file and returns."""
    with open(logfile, 'w'):
        pass
    return logfile

When I run it, however, it is creating the file, and then still outputting the logging info to the console. I'm running in Powershell.

Just tried putting it inside the main statement like this:

if __name__ == '__main__':
    logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] - %(message)s',
    filename=config3.GET_LOGFILE(config3.REQUESTS_USAGE_LOGFILE))

    logging.warning('This should go in the file.')

Still no luck.

Upvotes: 22

Views: 30407

Answers (5)

bhargav3vedi
bhargav3vedi

Reputation: 619

import logging

logging.basicConfig(filename="logs.log", filemode="w", format="%(asctime)s %(message)s", level=0, force=True)

for i in range(2):
    print(f"hello {i}")
    logging.info(f"hello {i}")

set level=0, filemode="a" or "w". if you set filemode w then it will overwrite previous logs but if you want to append logs, you must use filemode="a".

Upvotes: 0

Forge
Forge

Reputation: 6834

You can try running this snippet in your main file.

import logging 
logging.basicConfig(
    level=logging.INFO, 
    format='%(asctime)s [%(levelname)s] - %(message)s',
    filename='filename.txt')  # pass explicit filename here 
logger = logging.get_logger()  # get the root logger
logger.warning('This should go in the file.')
print logger.handlers   # you should have one FileHandler object

Upvotes: 10

Jen
Jen

Reputation: 71

In addition to Forge's answer on using logging.basicConfig(), as of Python 3.8 a parameter to basicConfig() got added. To quote the docs:

"""
This function does nothing if the root logger already has handlers 
configured, unless the keyword argument *force* is set to ``True``.
...
force     If this keyword  is specified as true, any existing handlers
          attached to the root logger are removed and closed, before
          carrying out the configuration as specified by the other
          arguments.
"""

This is why yue dong's answer to remove all handlers has worked for some as well as Alexander's answer to reset logger.handlers to [].

Debugging logger.handlers (as Forge's answer suggests) led me to see a single StreamHandler there (so basicConfig() did nothing for me until I used force=True as parameter).

Hope that helps in addition to all the other answers here too!

Upvotes: 4

Alexander Borochkin
Alexander Borochkin

Reputation: 4621

If you are using 'root' logger which is by default has name "", than you can do this trick:

logging.getLogger().setLevel(logging.INFO)    
logger = logging.getLogger('')
logger.handlers = []

In addition you may want to specify logging level as in code above, this level will persist for all descendant loggers.

If instead, you specified particular logger, than do

logger = logging.getLogger('my_service')
logger.handlers = []
fh = logging.FileHandler(log_path)
fh.setLevel(logging.INFO)
# create console handler
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
logger.addHandler(fh)
logger.addHandler(ch)
logger.info('service started')

The above code will create new logger 'my_service'. In case that logger has been already created it clears all handles. That it adds handles for writing in specified file and console. See official documentation as well.

You can also use hierarchical loggers. It is done directly.

logger = logging.getLogger('my_service.update')
logger.info('updated successfully')

Upvotes: 2

yue dong
yue dong

Reputation: 635

I add the following lines before the logging.basicConfig() and it worked for me.

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

Upvotes: 35

Related Questions