Making Python loggers output all messages to stdout in addition to log file











up vote
317
down vote

favorite
78












Is there a way to make Python logging using the logging module automatically output things to stdout in addition to the log file where they are supposed to go? For example, I'd like all calls to logger.warning, logger.critical, logger.error to go to their intended places but in addition always be copied to stdout. This is to avoid duplicating messages like:



mylogger.critical("something failed")
print "something failed"









share|improve this question
























  • Please check this answer stackoverflow.com/questions/9321741/…
    – SeF
    Feb 15 at 17:08















up vote
317
down vote

favorite
78












Is there a way to make Python logging using the logging module automatically output things to stdout in addition to the log file where they are supposed to go? For example, I'd like all calls to logger.warning, logger.critical, logger.error to go to their intended places but in addition always be copied to stdout. This is to avoid duplicating messages like:



mylogger.critical("something failed")
print "something failed"









share|improve this question
























  • Please check this answer stackoverflow.com/questions/9321741/…
    – SeF
    Feb 15 at 17:08













up vote
317
down vote

favorite
78









up vote
317
down vote

favorite
78






78





Is there a way to make Python logging using the logging module automatically output things to stdout in addition to the log file where they are supposed to go? For example, I'd like all calls to logger.warning, logger.critical, logger.error to go to their intended places but in addition always be copied to stdout. This is to avoid duplicating messages like:



mylogger.critical("something failed")
print "something failed"









share|improve this question















Is there a way to make Python logging using the logging module automatically output things to stdout in addition to the log file where they are supposed to go? For example, I'd like all calls to logger.warning, logger.critical, logger.error to go to their intended places but in addition always be copied to stdout. This is to avoid duplicating messages like:



mylogger.critical("something failed")
print "something failed"






python logging error-logging






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 18 at 7:56









Ben

619620




619620










asked Dec 27 '12 at 17:11









user248237dfsf

23.9k107261404




23.9k107261404












  • Please check this answer stackoverflow.com/questions/9321741/…
    – SeF
    Feb 15 at 17:08


















  • Please check this answer stackoverflow.com/questions/9321741/…
    – SeF
    Feb 15 at 17:08
















Please check this answer stackoverflow.com/questions/9321741/…
– SeF
Feb 15 at 17:08




Please check this answer stackoverflow.com/questions/9321741/…
– SeF
Feb 15 at 17:08












7 Answers
7






active

oldest

votes

















up vote
458
down vote



accepted










All logging output is handled by the handlers; just add a logging.StreamHandler() to the root logger.



Here's an example configuring a stream handler (using stdout instead of the default stderr) and adding it to the root logger:



import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)





share|improve this answer



















  • 3




    That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
    – user248237dfsf
    Dec 27 '12 at 17:27






  • 33




    @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
    – Martijn Pieters
    Dec 27 '12 at 17:28








  • 3




    @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
    – A.Wan
    Jan 12 '16 at 21:39






  • 1




    I'd suggest s/root/logger/g.
    – Dan
    Jun 7 '17 at 19:43






  • 1




    @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
    – Martijn Pieters
    Jun 7 '17 at 21:33


















up vote
362
down vote













the simplest way:



import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)





share|improve this answer



















  • 38




    Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
    – Weidenrinde
    May 7 '15 at 9:17






  • 29




    This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
    – phoenix
    Oct 11 '17 at 12:16






  • 1




    Probably the answer you need, but not what asked for :-P
    – Umang Gupta
    Oct 20 '17 at 23:03






  • 1




    @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
    – Sorin
    May 30 at 14:24






  • 2




    This is by far the best answer that did not answer the question. : )
    – Basil Musa
    Jul 31 at 9:32


















up vote
48
down vote













It's possible using multiple handlers.



import logging
import auxiliary_module

# create logger with 'spam_application'
log = logging.getLogger('spam_application')
log.setLevel(logging.DEBUG)

# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(fh)

# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
log.addHandler(ch)

log.info('creating an instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
log.info('created an instance of auxiliary_module.Auxiliary')

log.info('calling auxiliary_module.Auxiliary.do_something')
a.do_something()
log.info('finished auxiliary_module.Auxiliary.do_something')

log.info('calling auxiliary_module.some_function()')
auxiliary_module.some_function()
log.info('done with auxiliary_module.some_function()')

# remember to close the handlers
for handler in log.handlers:
handler.close()
log.removeFilter(handler)


Please see: https://docs.python.org/2/howto/logging-cookbook.html






share|improve this answer



















  • 4




    Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
    – The Unfun Cat
    Jun 23 '15 at 21:30


















up vote
32
down vote













You could create two handlers for file and stdout and then create one logger with handlers argument to basicConfig. It could be useful if you have the same log_level and format output for both handlers:



import logging
import sys

file_handler = logging.FileHandler(filename='tmp.log')
stdout_handler = logging.StreamHandler(sys.stdout)
handlers = [file_handler, stdout_handler]

logging.basicConfig(
level=logging.DEBUG,
format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
handlers=handlers
)

logger = logging.getLogger('LOGGER_NAME')





share|improve this answer



















  • 2




    IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
    – Tino
    Apr 3 at 19:31


















up vote
29
down vote













The simplest way to log to file and to stderr:



  import logging
logging.basicConfig(filename="logfile.txt")
stderrLogger=logging.StreamHandler()
stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
logging.getLogger().addHandler(stderrLogger)





share|improve this answer























  • This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
    – JahMyst
    Jan 20 '16 at 20:22








  • 1




    Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
    – Weidenrinde
    Jan 22 '16 at 8:26










  • Thanks, that's great !
    – JahMyst
    Jan 22 '16 at 17:00


















up vote
0
down vote













Here is a solution based on the dictConfig configuration function.
Instead of sending every log message to stdout, it sends messages with log level ERROR and higher to stderr and everything else to stdout.
This can be useful if other parts of the system are listening to stderr/stdout.



import logging
import logging.config
import sys

class _ExcludeErrorsFilter(logging.Filter):
def filter(self, record):
"""Filters out log messages with log level ERROR (numeric value: 40) or higher."""
return record.levelno < 40


config = {
'version': 1,
'filters': {
'exclude_errors': {
'()': _ExcludeErrorsFilter
}
},
'formatters': {
'my_formatter': {
'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
}
},
'handlers': {
'console_stderr': {
# Directs log messages with log level ERROR or higher to stderr
'class': 'logging.StreamHandler',
'level': 'ERROR',
'formatter': 'my_formatter',
'stream': sys.stderr
},
'console_stdout': {
# Directs log messages with log level lower than ERROR to stdout
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'my_formatter',
'filters': ['exclude_errors'],
'stream': sys.stdout
},
'file': {
# Directs all log messages to a file
'class': 'logging.FileHandler',
'level': 'DEBUG',
'formatter': 'my_formatter',
'filename': 'my.log',
'encoding': 'utf8'
}
},
'root': {
'level': 'NOTSET',
'handlers': ['console_stderr', 'console_stdout', 'file']
},
}

logging.config.dictConfig(config)





share|improve this answer




























    up vote
    0
    down vote













    Take a look to the loguru module.



    from loguru import logger

    logger.debug("That's it, beautiful and simple logging!")





    share|improve this answer




















      protected by coldspeed Jun 9 at 6:19



      Thank you for your interest in this question.
      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



      Would you like to answer one of these unanswered questions instead?














      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      458
      down vote



      accepted










      All logging output is handled by the handlers; just add a logging.StreamHandler() to the root logger.



      Here's an example configuring a stream handler (using stdout instead of the default stderr) and adding it to the root logger:



      import logging
      import sys

      root = logging.getLogger()
      root.setLevel(logging.DEBUG)

      handler = logging.StreamHandler(sys.stdout)
      handler.setLevel(logging.DEBUG)
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      handler.setFormatter(formatter)
      root.addHandler(handler)





      share|improve this answer



















      • 3




        That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
        – user248237dfsf
        Dec 27 '12 at 17:27






      • 33




        @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
        – Martijn Pieters
        Dec 27 '12 at 17:28








      • 3




        @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
        – A.Wan
        Jan 12 '16 at 21:39






      • 1




        I'd suggest s/root/logger/g.
        – Dan
        Jun 7 '17 at 19:43






      • 1




        @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
        – Martijn Pieters
        Jun 7 '17 at 21:33















      up vote
      458
      down vote



      accepted










      All logging output is handled by the handlers; just add a logging.StreamHandler() to the root logger.



      Here's an example configuring a stream handler (using stdout instead of the default stderr) and adding it to the root logger:



      import logging
      import sys

      root = logging.getLogger()
      root.setLevel(logging.DEBUG)

      handler = logging.StreamHandler(sys.stdout)
      handler.setLevel(logging.DEBUG)
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      handler.setFormatter(formatter)
      root.addHandler(handler)





      share|improve this answer



















      • 3




        That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
        – user248237dfsf
        Dec 27 '12 at 17:27






      • 33




        @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
        – Martijn Pieters
        Dec 27 '12 at 17:28








      • 3




        @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
        – A.Wan
        Jan 12 '16 at 21:39






      • 1




        I'd suggest s/root/logger/g.
        – Dan
        Jun 7 '17 at 19:43






      • 1




        @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
        – Martijn Pieters
        Jun 7 '17 at 21:33













      up vote
      458
      down vote



      accepted







      up vote
      458
      down vote



      accepted






      All logging output is handled by the handlers; just add a logging.StreamHandler() to the root logger.



      Here's an example configuring a stream handler (using stdout instead of the default stderr) and adding it to the root logger:



      import logging
      import sys

      root = logging.getLogger()
      root.setLevel(logging.DEBUG)

      handler = logging.StreamHandler(sys.stdout)
      handler.setLevel(logging.DEBUG)
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      handler.setFormatter(formatter)
      root.addHandler(handler)





      share|improve this answer














      All logging output is handled by the handlers; just add a logging.StreamHandler() to the root logger.



      Here's an example configuring a stream handler (using stdout instead of the default stderr) and adding it to the root logger:



      import logging
      import sys

      root = logging.getLogger()
      root.setLevel(logging.DEBUG)

      handler = logging.StreamHandler(sys.stdout)
      handler.setLevel(logging.DEBUG)
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      handler.setFormatter(formatter)
      root.addHandler(handler)






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 8 at 11:47

























      answered Dec 27 '12 at 17:12









      Martijn Pieters

      696k12924092247




      696k12924092247








      • 3




        That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
        – user248237dfsf
        Dec 27 '12 at 17:27






      • 33




        @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
        – Martijn Pieters
        Dec 27 '12 at 17:28








      • 3




        @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
        – A.Wan
        Jan 12 '16 at 21:39






      • 1




        I'd suggest s/root/logger/g.
        – Dan
        Jun 7 '17 at 19:43






      • 1




        @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
        – Martijn Pieters
        Jun 7 '17 at 21:33














      • 3




        That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
        – user248237dfsf
        Dec 27 '12 at 17:27






      • 33




        @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
        – Martijn Pieters
        Dec 27 '12 at 17:28








      • 3




        @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
        – A.Wan
        Jan 12 '16 at 21:39






      • 1




        I'd suggest s/root/logger/g.
        – Dan
        Jun 7 '17 at 19:43






      • 1




        @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
        – Martijn Pieters
        Jun 7 '17 at 21:33








      3




      3




      That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
      – user248237dfsf
      Dec 27 '12 at 17:27




      That's fine but if it's already redirected to a file how can I have it be printed to stdout in addition?
      – user248237dfsf
      Dec 27 '12 at 17:27




      33




      33




      @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
      – Martijn Pieters
      Dec 27 '12 at 17:28






      @user248237: By adding a new handler as illustrated. New handlers do not replace the existing handlers, they also get to process the log entries.
      – Martijn Pieters
      Dec 27 '12 at 17:28






      3




      3




      @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
      – A.Wan
      Jan 12 '16 at 21:39




      @PrakharMohanSrivastava I'd guess you can just add it to the string passed into logging.Formatter.
      – A.Wan
      Jan 12 '16 at 21:39




      1




      1




      I'd suggest s/root/logger/g.
      – Dan
      Jun 7 '17 at 19:43




      I'd suggest s/root/logger/g.
      – Dan
      Jun 7 '17 at 19:43




      1




      1




      @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
      – Martijn Pieters
      Jun 7 '17 at 21:33




      @Dan: what difference does that make? It's just the variable holding a reference to the root logging object (hence the name).
      – Martijn Pieters
      Jun 7 '17 at 21:33












      up vote
      362
      down vote













      the simplest way:



      import logging
      import sys
      logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)





      share|improve this answer



















      • 38




        Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
        – Weidenrinde
        May 7 '15 at 9:17






      • 29




        This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
        – phoenix
        Oct 11 '17 at 12:16






      • 1




        Probably the answer you need, but not what asked for :-P
        – Umang Gupta
        Oct 20 '17 at 23:03






      • 1




        @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
        – Sorin
        May 30 at 14:24






      • 2




        This is by far the best answer that did not answer the question. : )
        – Basil Musa
        Jul 31 at 9:32















      up vote
      362
      down vote













      the simplest way:



      import logging
      import sys
      logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)





      share|improve this answer



















      • 38




        Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
        – Weidenrinde
        May 7 '15 at 9:17






      • 29




        This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
        – phoenix
        Oct 11 '17 at 12:16






      • 1




        Probably the answer you need, but not what asked for :-P
        – Umang Gupta
        Oct 20 '17 at 23:03






      • 1




        @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
        – Sorin
        May 30 at 14:24






      • 2




        This is by far the best answer that did not answer the question. : )
        – Basil Musa
        Jul 31 at 9:32













      up vote
      362
      down vote










      up vote
      362
      down vote









      the simplest way:



      import logging
      import sys
      logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)





      share|improve this answer














      the simplest way:



      import logging
      import sys
      logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Feb 18 '15 at 3:56









      Soviut

      56.6k33142208




      56.6k33142208










      answered Jan 28 '15 at 14:39









      Eyal

      3,880197




      3,880197








      • 38




        Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
        – Weidenrinde
        May 7 '15 at 9:17






      • 29




        This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
        – phoenix
        Oct 11 '17 at 12:16






      • 1




        Probably the answer you need, but not what asked for :-P
        – Umang Gupta
        Oct 20 '17 at 23:03






      • 1




        @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
        – Sorin
        May 30 at 14:24






      • 2




        This is by far the best answer that did not answer the question. : )
        – Basil Musa
        Jul 31 at 9:32














      • 38




        Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
        – Weidenrinde
        May 7 '15 at 9:17






      • 29




        This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
        – phoenix
        Oct 11 '17 at 12:16






      • 1




        Probably the answer you need, but not what asked for :-P
        – Umang Gupta
        Oct 20 '17 at 23:03






      • 1




        @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
        – Sorin
        May 30 at 14:24






      • 2




        This is by far the best answer that did not answer the question. : )
        – Basil Musa
        Jul 31 at 9:32








      38




      38




      Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
      – Weidenrinde
      May 7 '15 at 9:17




      Hm, but this isn't logged to a file, right? The question was how to do logging to file and to console.
      – Weidenrinde
      May 7 '15 at 9:17




      29




      29




      This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
      – phoenix
      Oct 11 '17 at 12:16




      This might not be what the OP was asking, but it's exactly what I was looking for and the first hit on Google. +1
      – phoenix
      Oct 11 '17 at 12:16




      1




      1




      Probably the answer you need, but not what asked for :-P
      – Umang Gupta
      Oct 20 '17 at 23:03




      Probably the answer you need, but not what asked for :-P
      – Umang Gupta
      Oct 20 '17 at 23:03




      1




      1




      @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
      – Sorin
      May 30 at 14:24




      @TaylorEdmiston Yeah, but it's the stderr stream AFAIK. Try redirecting the output from the shell.
      – Sorin
      May 30 at 14:24




      2




      2




      This is by far the best answer that did not answer the question. : )
      – Basil Musa
      Jul 31 at 9:32




      This is by far the best answer that did not answer the question. : )
      – Basil Musa
      Jul 31 at 9:32










      up vote
      48
      down vote













      It's possible using multiple handlers.



      import logging
      import auxiliary_module

      # create logger with 'spam_application'
      log = logging.getLogger('spam_application')
      log.setLevel(logging.DEBUG)

      # create formatter and add it to the handlers
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

      # create file handler which logs even debug messages
      fh = logging.FileHandler('spam.log')
      fh.setLevel(logging.DEBUG)
      fh.setFormatter(formatter)
      log.addHandler(fh)

      # create console handler with a higher log level
      ch = logging.StreamHandler()
      ch.setLevel(logging.ERROR)
      ch.setFormatter(formatter)
      log.addHandler(ch)

      log.info('creating an instance of auxiliary_module.Auxiliary')
      a = auxiliary_module.Auxiliary()
      log.info('created an instance of auxiliary_module.Auxiliary')

      log.info('calling auxiliary_module.Auxiliary.do_something')
      a.do_something()
      log.info('finished auxiliary_module.Auxiliary.do_something')

      log.info('calling auxiliary_module.some_function()')
      auxiliary_module.some_function()
      log.info('done with auxiliary_module.some_function()')

      # remember to close the handlers
      for handler in log.handlers:
      handler.close()
      log.removeFilter(handler)


      Please see: https://docs.python.org/2/howto/logging-cookbook.html






      share|improve this answer



















      • 4




        Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
        – The Unfun Cat
        Jun 23 '15 at 21:30















      up vote
      48
      down vote













      It's possible using multiple handlers.



      import logging
      import auxiliary_module

      # create logger with 'spam_application'
      log = logging.getLogger('spam_application')
      log.setLevel(logging.DEBUG)

      # create formatter and add it to the handlers
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

      # create file handler which logs even debug messages
      fh = logging.FileHandler('spam.log')
      fh.setLevel(logging.DEBUG)
      fh.setFormatter(formatter)
      log.addHandler(fh)

      # create console handler with a higher log level
      ch = logging.StreamHandler()
      ch.setLevel(logging.ERROR)
      ch.setFormatter(formatter)
      log.addHandler(ch)

      log.info('creating an instance of auxiliary_module.Auxiliary')
      a = auxiliary_module.Auxiliary()
      log.info('created an instance of auxiliary_module.Auxiliary')

      log.info('calling auxiliary_module.Auxiliary.do_something')
      a.do_something()
      log.info('finished auxiliary_module.Auxiliary.do_something')

      log.info('calling auxiliary_module.some_function()')
      auxiliary_module.some_function()
      log.info('done with auxiliary_module.some_function()')

      # remember to close the handlers
      for handler in log.handlers:
      handler.close()
      log.removeFilter(handler)


      Please see: https://docs.python.org/2/howto/logging-cookbook.html






      share|improve this answer



















      • 4




        Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
        – The Unfun Cat
        Jun 23 '15 at 21:30













      up vote
      48
      down vote










      up vote
      48
      down vote









      It's possible using multiple handlers.



      import logging
      import auxiliary_module

      # create logger with 'spam_application'
      log = logging.getLogger('spam_application')
      log.setLevel(logging.DEBUG)

      # create formatter and add it to the handlers
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

      # create file handler which logs even debug messages
      fh = logging.FileHandler('spam.log')
      fh.setLevel(logging.DEBUG)
      fh.setFormatter(formatter)
      log.addHandler(fh)

      # create console handler with a higher log level
      ch = logging.StreamHandler()
      ch.setLevel(logging.ERROR)
      ch.setFormatter(formatter)
      log.addHandler(ch)

      log.info('creating an instance of auxiliary_module.Auxiliary')
      a = auxiliary_module.Auxiliary()
      log.info('created an instance of auxiliary_module.Auxiliary')

      log.info('calling auxiliary_module.Auxiliary.do_something')
      a.do_something()
      log.info('finished auxiliary_module.Auxiliary.do_something')

      log.info('calling auxiliary_module.some_function()')
      auxiliary_module.some_function()
      log.info('done with auxiliary_module.some_function()')

      # remember to close the handlers
      for handler in log.handlers:
      handler.close()
      log.removeFilter(handler)


      Please see: https://docs.python.org/2/howto/logging-cookbook.html






      share|improve this answer














      It's possible using multiple handlers.



      import logging
      import auxiliary_module

      # create logger with 'spam_application'
      log = logging.getLogger('spam_application')
      log.setLevel(logging.DEBUG)

      # create formatter and add it to the handlers
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

      # create file handler which logs even debug messages
      fh = logging.FileHandler('spam.log')
      fh.setLevel(logging.DEBUG)
      fh.setFormatter(formatter)
      log.addHandler(fh)

      # create console handler with a higher log level
      ch = logging.StreamHandler()
      ch.setLevel(logging.ERROR)
      ch.setFormatter(formatter)
      log.addHandler(ch)

      log.info('creating an instance of auxiliary_module.Auxiliary')
      a = auxiliary_module.Auxiliary()
      log.info('created an instance of auxiliary_module.Auxiliary')

      log.info('calling auxiliary_module.Auxiliary.do_something')
      a.do_something()
      log.info('finished auxiliary_module.Auxiliary.do_something')

      log.info('calling auxiliary_module.some_function()')
      auxiliary_module.some_function()
      log.info('done with auxiliary_module.some_function()')

      # remember to close the handlers
      for handler in log.handlers:
      handler.close()
      log.removeFilter(handler)


      Please see: https://docs.python.org/2/howto/logging-cookbook.html







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Apr 5 '17 at 13:03









      Vallentin

      11.4k42949




      11.4k42949










      answered Jul 27 '14 at 6:24









      Alok Singh Mahor

      2,21122036




      2,21122036








      • 4




        Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
        – The Unfun Cat
        Jun 23 '15 at 21:30














      • 4




        Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
        – The Unfun Cat
        Jun 23 '15 at 21:30








      4




      4




      Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
      – The Unfun Cat
      Jun 23 '15 at 21:30




      Wonderful answer, albeit a bit messy. Love how you show how to use different levels and formats for streams and files. +1, but +2 in spirit.
      – The Unfun Cat
      Jun 23 '15 at 21:30










      up vote
      32
      down vote













      You could create two handlers for file and stdout and then create one logger with handlers argument to basicConfig. It could be useful if you have the same log_level and format output for both handlers:



      import logging
      import sys

      file_handler = logging.FileHandler(filename='tmp.log')
      stdout_handler = logging.StreamHandler(sys.stdout)
      handlers = [file_handler, stdout_handler]

      logging.basicConfig(
      level=logging.DEBUG,
      format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
      handlers=handlers
      )

      logger = logging.getLogger('LOGGER_NAME')





      share|improve this answer



















      • 2




        IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
        – Tino
        Apr 3 at 19:31















      up vote
      32
      down vote













      You could create two handlers for file and stdout and then create one logger with handlers argument to basicConfig. It could be useful if you have the same log_level and format output for both handlers:



      import logging
      import sys

      file_handler = logging.FileHandler(filename='tmp.log')
      stdout_handler = logging.StreamHandler(sys.stdout)
      handlers = [file_handler, stdout_handler]

      logging.basicConfig(
      level=logging.DEBUG,
      format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
      handlers=handlers
      )

      logger = logging.getLogger('LOGGER_NAME')





      share|improve this answer



















      • 2




        IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
        – Tino
        Apr 3 at 19:31













      up vote
      32
      down vote










      up vote
      32
      down vote









      You could create two handlers for file and stdout and then create one logger with handlers argument to basicConfig. It could be useful if you have the same log_level and format output for both handlers:



      import logging
      import sys

      file_handler = logging.FileHandler(filename='tmp.log')
      stdout_handler = logging.StreamHandler(sys.stdout)
      handlers = [file_handler, stdout_handler]

      logging.basicConfig(
      level=logging.DEBUG,
      format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
      handlers=handlers
      )

      logger = logging.getLogger('LOGGER_NAME')





      share|improve this answer














      You could create two handlers for file and stdout and then create one logger with handlers argument to basicConfig. It could be useful if you have the same log_level and format output for both handlers:



      import logging
      import sys

      file_handler = logging.FileHandler(filename='tmp.log')
      stdout_handler = logging.StreamHandler(sys.stdout)
      handlers = [file_handler, stdout_handler]

      logging.basicConfig(
      level=logging.DEBUG,
      format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
      handlers=handlers
      )

      logger = logging.getLogger('LOGGER_NAME')






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jul 5 '17 at 5:08

























      answered Jun 26 '17 at 12:43









      Anton Protopopov

      14.5k34659




      14.5k34659








      • 2




        IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
        – Tino
        Apr 3 at 19:31














      • 2




        IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
        – Tino
        Apr 3 at 19:31








      2




      2




      IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
      – Tino
      Apr 3 at 19:31




      IMHO the best answer. It is good formatted, easy to understand, the code is not too long, covers the whole question and .. is correct!
      – Tino
      Apr 3 at 19:31










      up vote
      29
      down vote













      The simplest way to log to file and to stderr:



        import logging
      logging.basicConfig(filename="logfile.txt")
      stderrLogger=logging.StreamHandler()
      stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
      logging.getLogger().addHandler(stderrLogger)





      share|improve this answer























      • This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
        – JahMyst
        Jan 20 '16 at 20:22








      • 1




        Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
        – Weidenrinde
        Jan 22 '16 at 8:26










      • Thanks, that's great !
        – JahMyst
        Jan 22 '16 at 17:00















      up vote
      29
      down vote













      The simplest way to log to file and to stderr:



        import logging
      logging.basicConfig(filename="logfile.txt")
      stderrLogger=logging.StreamHandler()
      stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
      logging.getLogger().addHandler(stderrLogger)





      share|improve this answer























      • This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
        – JahMyst
        Jan 20 '16 at 20:22








      • 1




        Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
        – Weidenrinde
        Jan 22 '16 at 8:26










      • Thanks, that's great !
        – JahMyst
        Jan 22 '16 at 17:00













      up vote
      29
      down vote










      up vote
      29
      down vote









      The simplest way to log to file and to stderr:



        import logging
      logging.basicConfig(filename="logfile.txt")
      stderrLogger=logging.StreamHandler()
      stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
      logging.getLogger().addHandler(stderrLogger)





      share|improve this answer














      The simplest way to log to file and to stderr:



        import logging
      logging.basicConfig(filename="logfile.txt")
      stderrLogger=logging.StreamHandler()
      stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
      logging.getLogger().addHandler(stderrLogger)






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 22 '16 at 8:25

























      answered May 7 '15 at 9:22









      Weidenrinde

      1,53811519




      1,53811519












      • This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
        – JahMyst
        Jan 20 '16 at 20:22








      • 1




        Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
        – Weidenrinde
        Jan 22 '16 at 8:26










      • Thanks, that's great !
        – JahMyst
        Jan 22 '16 at 17:00


















      • This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
        – JahMyst
        Jan 20 '16 at 20:22








      • 1




        Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
        – Weidenrinde
        Jan 22 '16 at 8:26










      • Thanks, that's great !
        – JahMyst
        Jan 22 '16 at 17:00
















      This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
      – JahMyst
      Jan 20 '16 at 20:22






      This doesn't show labels INFO, DEBUG, and ERROR before the logging message in the console. It does show those labels in the file. Any ideas to also show the labels in the console ?
      – JahMyst
      Jan 20 '16 at 20:22






      1




      1




      Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
      – Weidenrinde
      Jan 22 '16 at 8:26




      Thanks, @JahMyst, I added the Formatter. Unfortunately, it's not so short any longer, but still the simplest way. :-)
      – Weidenrinde
      Jan 22 '16 at 8:26












      Thanks, that's great !
      – JahMyst
      Jan 22 '16 at 17:00




      Thanks, that's great !
      – JahMyst
      Jan 22 '16 at 17:00










      up vote
      0
      down vote













      Here is a solution based on the dictConfig configuration function.
      Instead of sending every log message to stdout, it sends messages with log level ERROR and higher to stderr and everything else to stdout.
      This can be useful if other parts of the system are listening to stderr/stdout.



      import logging
      import logging.config
      import sys

      class _ExcludeErrorsFilter(logging.Filter):
      def filter(self, record):
      """Filters out log messages with log level ERROR (numeric value: 40) or higher."""
      return record.levelno < 40


      config = {
      'version': 1,
      'filters': {
      'exclude_errors': {
      '()': _ExcludeErrorsFilter
      }
      },
      'formatters': {
      'my_formatter': {
      'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
      }
      },
      'handlers': {
      'console_stderr': {
      # Directs log messages with log level ERROR or higher to stderr
      'class': 'logging.StreamHandler',
      'level': 'ERROR',
      'formatter': 'my_formatter',
      'stream': sys.stderr
      },
      'console_stdout': {
      # Directs log messages with log level lower than ERROR to stdout
      'class': 'logging.StreamHandler',
      'level': 'DEBUG',
      'formatter': 'my_formatter',
      'filters': ['exclude_errors'],
      'stream': sys.stdout
      },
      'file': {
      # Directs all log messages to a file
      'class': 'logging.FileHandler',
      'level': 'DEBUG',
      'formatter': 'my_formatter',
      'filename': 'my.log',
      'encoding': 'utf8'
      }
      },
      'root': {
      'level': 'NOTSET',
      'handlers': ['console_stderr', 'console_stdout', 'file']
      },
      }

      logging.config.dictConfig(config)





      share|improve this answer

























        up vote
        0
        down vote













        Here is a solution based on the dictConfig configuration function.
        Instead of sending every log message to stdout, it sends messages with log level ERROR and higher to stderr and everything else to stdout.
        This can be useful if other parts of the system are listening to stderr/stdout.



        import logging
        import logging.config
        import sys

        class _ExcludeErrorsFilter(logging.Filter):
        def filter(self, record):
        """Filters out log messages with log level ERROR (numeric value: 40) or higher."""
        return record.levelno < 40


        config = {
        'version': 1,
        'filters': {
        'exclude_errors': {
        '()': _ExcludeErrorsFilter
        }
        },
        'formatters': {
        'my_formatter': {
        'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
        }
        },
        'handlers': {
        'console_stderr': {
        # Directs log messages with log level ERROR or higher to stderr
        'class': 'logging.StreamHandler',
        'level': 'ERROR',
        'formatter': 'my_formatter',
        'stream': sys.stderr
        },
        'console_stdout': {
        # Directs log messages with log level lower than ERROR to stdout
        'class': 'logging.StreamHandler',
        'level': 'DEBUG',
        'formatter': 'my_formatter',
        'filters': ['exclude_errors'],
        'stream': sys.stdout
        },
        'file': {
        # Directs all log messages to a file
        'class': 'logging.FileHandler',
        'level': 'DEBUG',
        'formatter': 'my_formatter',
        'filename': 'my.log',
        'encoding': 'utf8'
        }
        },
        'root': {
        'level': 'NOTSET',
        'handlers': ['console_stderr', 'console_stdout', 'file']
        },
        }

        logging.config.dictConfig(config)





        share|improve this answer























          up vote
          0
          down vote










          up vote
          0
          down vote









          Here is a solution based on the dictConfig configuration function.
          Instead of sending every log message to stdout, it sends messages with log level ERROR and higher to stderr and everything else to stdout.
          This can be useful if other parts of the system are listening to stderr/stdout.



          import logging
          import logging.config
          import sys

          class _ExcludeErrorsFilter(logging.Filter):
          def filter(self, record):
          """Filters out log messages with log level ERROR (numeric value: 40) or higher."""
          return record.levelno < 40


          config = {
          'version': 1,
          'filters': {
          'exclude_errors': {
          '()': _ExcludeErrorsFilter
          }
          },
          'formatters': {
          'my_formatter': {
          'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
          }
          },
          'handlers': {
          'console_stderr': {
          # Directs log messages with log level ERROR or higher to stderr
          'class': 'logging.StreamHandler',
          'level': 'ERROR',
          'formatter': 'my_formatter',
          'stream': sys.stderr
          },
          'console_stdout': {
          # Directs log messages with log level lower than ERROR to stdout
          'class': 'logging.StreamHandler',
          'level': 'DEBUG',
          'formatter': 'my_formatter',
          'filters': ['exclude_errors'],
          'stream': sys.stdout
          },
          'file': {
          # Directs all log messages to a file
          'class': 'logging.FileHandler',
          'level': 'DEBUG',
          'formatter': 'my_formatter',
          'filename': 'my.log',
          'encoding': 'utf8'
          }
          },
          'root': {
          'level': 'NOTSET',
          'handlers': ['console_stderr', 'console_stdout', 'file']
          },
          }

          logging.config.dictConfig(config)





          share|improve this answer












          Here is a solution based on the dictConfig configuration function.
          Instead of sending every log message to stdout, it sends messages with log level ERROR and higher to stderr and everything else to stdout.
          This can be useful if other parts of the system are listening to stderr/stdout.



          import logging
          import logging.config
          import sys

          class _ExcludeErrorsFilter(logging.Filter):
          def filter(self, record):
          """Filters out log messages with log level ERROR (numeric value: 40) or higher."""
          return record.levelno < 40


          config = {
          'version': 1,
          'filters': {
          'exclude_errors': {
          '()': _ExcludeErrorsFilter
          }
          },
          'formatters': {
          'my_formatter': {
          'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
          }
          },
          'handlers': {
          'console_stderr': {
          # Directs log messages with log level ERROR or higher to stderr
          'class': 'logging.StreamHandler',
          'level': 'ERROR',
          'formatter': 'my_formatter',
          'stream': sys.stderr
          },
          'console_stdout': {
          # Directs log messages with log level lower than ERROR to stdout
          'class': 'logging.StreamHandler',
          'level': 'DEBUG',
          'formatter': 'my_formatter',
          'filters': ['exclude_errors'],
          'stream': sys.stdout
          },
          'file': {
          # Directs all log messages to a file
          'class': 'logging.FileHandler',
          'level': 'DEBUG',
          'formatter': 'my_formatter',
          'filename': 'my.log',
          'encoding': 'utf8'
          }
          },
          'root': {
          'level': 'NOTSET',
          'handlers': ['console_stderr', 'console_stdout', 'file']
          },
          }

          logging.config.dictConfig(config)






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 7:38









          Elias Strehle

          350216




          350216






















              up vote
              0
              down vote













              Take a look to the loguru module.



              from loguru import logger

              logger.debug("That's it, beautiful and simple logging!")





              share|improve this answer

























                up vote
                0
                down vote













                Take a look to the loguru module.



                from loguru import logger

                logger.debug("That's it, beautiful and simple logging!")





                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Take a look to the loguru module.



                  from loguru import logger

                  logger.debug("That's it, beautiful and simple logging!")





                  share|improve this answer












                  Take a look to the loguru module.



                  from loguru import logger

                  logger.debug("That's it, beautiful and simple logging!")






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 10 at 15:35









                  efirvida

                  1,84521840




                  1,84521840

















                      protected by coldspeed Jun 9 at 6:19



                      Thank you for your interest in this question.
                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                      Would you like to answer one of these unanswered questions instead?



                      Popular posts from this blog

                      List item for chat from Array inside array React Native

                      Thiostrepton

                      Caerphilly