有没有一种方法使Python日志记录使用日志模块自动输出东西到标准输出除了日志文件,他们应该去哪里?例如,我希望所有的通话都记录在案。警告,记录器。关键,记录器。错误被复制到它们的预期位置,但总是被复制到标准输出。这是为了避免重复以下信息:
mylogger.critical("something failed")
print("something failed")
有没有一种方法使Python日志记录使用日志模块自动输出东西到标准输出除了日志文件,他们应该去哪里?例如,我希望所有的通话都记录在案。警告,记录器。关键,记录器。错误被复制到它们的预期位置,但总是被复制到标准输出。这是为了避免重复以下信息:
mylogger.critical("something failed")
print("something failed")
当前回答
所有日志输出都由处理程序处理;只需将logging.StreamHandler()添加到根日志记录器。
下面是一个配置流处理程序的例子(使用stdout而不是默认的stderr),并将其添加到根日志记录器:
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)
其他回答
您可以为文件和stdout创建两个处理程序,然后创建一个记录器,其中的handlers参数为basicConfig。如果两个处理程序有相同的log_level和format输出,这可能会很有用:
import logging
import sys
file_handler = logging.FileHandler(filename='tmp.log')
stdout_handler = logging.StreamHandler(stream=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')
记录文件和stderr的最简单方法:
import logging
logging.basicConfig(filename="logfile.txt")
stderrLogger=logging.StreamHandler()
stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
logging.getLogger().addHandler(stderrLogger)
我简化了我的源代码(其原始版本是OOP并使用配置文件),为您提供了@EliasStrehle的一个替代解决方案,而不使用dictConfig(因此最容易与现有源代码集成):
import logging
import sys
def create_stream_handler(stream, formatter, level, message_filter=None):
handler = logging.StreamHandler(stream=stream)
handler.setLevel(level)
handler.setFormatter(formatter)
if message_filter:
handler.addFilter(message_filter)
return handler
def configure_logger(logger: logging.Logger, enable_console: bool = True, enable_file: bool = True):
if not logger.handlers:
if enable_console:
message_format: str = '{asctime:20} {name:16} {levelname:8} {message}'
date_format: str = '%Y/%m/%d %H:%M:%S'
level: int = logging.DEBUG
formatter = logging.Formatter(message_format, date_format, '{')
# Configures error output (from Warning levels).
error_output_handler = create_stream_handler(sys.stderr, formatter,
max(level, logging.WARNING))
logger.addHandler(error_output_handler)
# Configures standard output (from configured Level, if lower than Warning,
# and excluding everything from Warning and higher).
if level < logging.WARNING:
standard_output_filter = lambda record: record.levelno < logging.WARNING
standard_output_handler = create_stream_handler(sys.stdout, formatter, level,
standard_output_filter)
logger.addHandler(standard_output_handler)
if enable_file:
message_format: str = '{asctime:20} {name:16} {levelname:8} {message}'
date_format: str = '%Y/%m/%d %H:%M:%S'
level: int = logging.DEBUG
output_file: str = '/tmp/so_test.log'
handler = logging.FileHandler(output_file)
formatter = logging.Formatter(message_format, date_format, '{')
handler.setLevel(level)
handler.setFormatter(formatter)
logger.addHandler(handler)
这是一个非常简单的测试方法:
logger: logging.Logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
configure_logger(logger, True, True)
logger.debug('Debug message ...')
logger.info('Info message ...')
logger.warning('Warning ...')
logger.error('Error ...')
logger.fatal('Fatal message ...')
你应该用t。配置应用程序写入标准输出,并运行
python3 app.py | tee log.txt
然后您将在stdout和log.txt中获得日志消息。
这里有一个非常简单的例子:
import logging
l = logging.getLogger("test")
# Add a file logger
f = logging.FileHandler("test.log")
l.addHandler(f)
# Add a stream logger
s = logging.StreamHandler()
l.addHandler(s)
# Send a test message to both -- critical will always log
l.critical("test msg")
输出将在stdout和文件中显示“test msg”。