Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging Handlers: How do I make sure I am not making two?

Tags:

python

logging

Edit: I ended up answering the beef of my question so that I can have a working logging module. However, I still have a related question. See my answer below.

I am trying to implement logging by always logging to the temporary directory of whatever os I am in. To do this I have written the following function.

import logging, tempfile, os, sys

def getlog(logname, filename = 'python.log', directory = None):
   '''returns a logger with logname that will print to filename and directoryname.'''
   if directory == None:
      fd, fname = tempfile.mkstemp()
      directory = os.path.dirname(fname)

   fullpath = directory + '/' + filename

   mylog = logging.getLogger(logname)
   hdlr = logging.FileHandler(fullpath)

   formatter = logging.Formatter('L:%(name)s M:%(module)s T:%(asctime)s > %(levelname)s: %(message)s')
   hdlr.setFormatter(formatter)
   mylog.addHandler(hdlr)
   mylog.setLevel(logging.INFO)
   mylog.info('NEW LOGGER STARTED')
   return mylog

if __name__ == '__main__':
   log = getlog('testing')
   log.info('working?')
   log.info('yes, seems to be working')

   log2 = getlog('testing')
   log2.info('still working?')

Here is the output:

L:testing M:easy_log T:2011-04-11 15:30:14,315 > INFO: NEW LOGGER STARTED
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: working?
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: yes, seems to be working
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: NEW LOGGER STARTED
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: NEW LOGGER STARTED
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: still working?
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: still working?

As you can see, it is now outputting double. However, the logging module is rather confusing, and I do not know of a way to find out if a log has already been instantiated, or if a log object already has a handler. Some help would be appreciated.

Edit: to add a little more detail, I am planning on calling this in several modules, essentially trying to replace the "logging.getLogger" call.

like image 855
Garrett Berg Avatar asked Nov 15 '22 00:11

Garrett Berg


1 Answers

I ended up answering my own question. Here is the code

global IS_SETUP 
IS_SETUP = False
def setuplogger(filename = 'python.log', directory = None, format = 'L:%(name)s M:%(module)s T:%(asctime)s > %(levelname)s: %(message)s'):
   global IS_SETUP
   if directory == None:
      fd, fname = tempfile.mkstemp()
      directory = os.path.dirname(fname)

   logging.basicConfig(filename = directory + '/' + filename, format = format)
   IS_SETUP = True

def getlog(logname, level = logging.INFO):
   '''returns a logger with logname that will print to filename and directoryname.'''
   if IS_SETUP == False:
      setuplogger()

   mylog = logging.getLogger(logname)

   mylog.setLevel(level)
   mylog.info('NEW LOGGER STARTED')
   return mylog

This avoids the double config. Also, apparently Basic config would work even if it were called multiple times.

If anyone knows how to check what handlers are on a log object, I would still like to know. It seems absolutely impossible.

like image 61
Garrett Berg Avatar answered Dec 25 '22 13:12

Garrett Berg