-1

I wanted to log messages from different module in python to a file. Also I need to print some messages to console for debugging purpose. I used logger module for this purpose . But logger module will log all the logs with given severity and above to file or console.

I wanted only some messages logged to file and it should not include the messages from the console.

Similarly the console messages should not contain messages logged to file.

My approach would be to have a singleton class which shares file write operation between various modules.

Is there any easier approach than this in python ?

EDIT: I am new to Python. Sample program I tried

logger = logging.getLogger('simple_example')
logger.setLevel(logging.INFO)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.CRITICAL)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

Console prints :

2015-02-03 15:36:00,651 - simple_example - ERROR - error message
2015-02-03 15:36:00,651 - simple_example - CRITICAL - critical message
#I don't want critical messages in console.
Knight71
  • 2,927
  • 5
  • 37
  • 63

2 Answers2

1

Here is a script that creates two loggers, use the one you wish to log to a file or stdout. The question is : on which criteria do you choose to log to stdout or file, knowing that (from your question) you don't want the criteria to be the log level (debug, error, critical...)

#!/usr/bin/python

import logging

logger_stdout = logging.getLogger('logger_stdout')
logger_stdout.setLevel(logging.DEBUG)
sh = logging.StreamHandler()
sh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger_stdout.addHandler(sh)
logger_stdout.debug('stdout debug message')

logger_file = logging.getLogger('logger_file')
logger_file.setLevel(logging.DEBUG)
fh = logging.FileHandler("foo.log")
fh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger_file.addHandler(fh)
logger_file.debug('file debug message')

And when I run this script:

D:\jrx\jrxpython                                                          
λ python essai.py                                                         
2015-02-03 11:12:07,210 - logger_stdout - DEBUG - stdout debug message    

D:\jrx\jrxpython                                                          
λ cat foo.log                                                             
2015-02-03 11:12:07,224 - logger_file - DEBUG - file debug message        

D:\jrx\jrxpython                                                          
λ   
Jérôme Radix
  • 10,285
  • 4
  • 34
  • 40
0

CRITICAL is higher than ERROR:

You can also verify yourself:

>>> import logging
>>> print logging.CRITICAL
50
>>> print logging.ERROR
40
>>> 

There are two cases in logging:

Logging the same process - you should have several handlers with different logging levels based on how verbose the logs should be. A higher level means less output. That's why DEBUG is the lowest predefined log level - it writes everything for debug purposes.

Logging different processes - you should have several loggers set up, they can be accessed from anywhere in your code using logging.getLogger(name). This gives the same logger every time, so that logger set-up persists through the code and only needs to be executed once.

The first case demonsrates that you can't have an "error but not critical" log, since this is the opposite of how logs should work. You can have a "critical but not error" log, that is less verbose. This is what you probably want.

Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
  • changing the level will make the log file to include both error and critical logs. – Knight71 Feb 03 '15 at 10:16
  • Reading the question it seems you're trying to log in different **levels** rather than **messages**. It's especially reflected through the last bit where you show what you considers to be erroneous (`CRITICAL` being logged). – Reut Sharabani Feb 03 '15 at 10:18