Making Python loggers output all messages to stdout in addition to log file
up vote
317
down vote
favorite
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
add a comment |
up vote
317
down vote
favorite
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
Please check this answer stackoverflow.com/questions/9321741/…
– SeF
Feb 15 at 17:08
add a comment |
up vote
317
down vote
favorite
up vote
317
down vote
favorite
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
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
python logging error-logging
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
add a comment |
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
add a comment |
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)
3
That's fine but if it's already redirected to a file how can I have it be printed tostdoutin 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 intologging.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
|
show 10 more comments
up vote
362
down vote
the simplest way:
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
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
|
show 2 more comments
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
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
add a comment |
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')
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
add a comment |
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)
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
add a comment |
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)
add a comment |
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!")
add a comment |
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)
3
That's fine but if it's already redirected to a file how can I have it be printed tostdoutin 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 intologging.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
|
show 10 more comments
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)
3
That's fine but if it's already redirected to a file how can I have it be printed tostdoutin 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 intologging.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
|
show 10 more comments
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)
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)
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 tostdoutin 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 intologging.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
|
show 10 more comments
3
That's fine but if it's already redirected to a file how can I have it be printed tostdoutin 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 intologging.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
|
show 10 more comments
up vote
362
down vote
the simplest way:
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
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
|
show 2 more comments
up vote
362
down vote
the simplest way:
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
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
|
show 2 more comments
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)
the simplest way:
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
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
|
show 2 more comments
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
|
show 2 more comments
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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')
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
add a comment |
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')
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
add a comment |
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')
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')
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
add a comment |
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
add a comment |
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)
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
add a comment |
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)
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
add a comment |
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)
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)
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
add a comment |
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
add a comment |
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)
add a comment |
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)
add a comment |
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)
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)
answered Nov 12 at 7:38
Elias Strehle
350216
350216
add a comment |
add a comment |
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!")
add a comment |
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!")
add a comment |
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!")
Take a look to the loguru module.
from loguru import logger
logger.debug("That's it, beautiful and simple logging!")
answered Dec 10 at 15:35
efirvida
1,84521840
1,84521840
add a comment |
add a comment |
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?
Please check this answer stackoverflow.com/questions/9321741/…
– SeF
Feb 15 at 17:08