网上资料大多吧嗦,此处仅贴代码及效果,便于快速取用。更多设置请自行探索,官方文档见此。
1 基础用法
官方文档见此。
import logging
logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
注:第2行 encoding 参数 是Python 3.9及之后版本才有的。如果你的Python版本低于3.9,请使用2.1节和2.3节代码,支持UTF-8,可实现汉字正常显示。
输出:
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
ERROR:root:And non-ASCII stuff, too, like Øresund and Malmö
2 高级用法
官方链接见此。
2.1 日志输出到控制台
import logging
# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
# 控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
输出:
$ python simple_logging_module.py
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message
2.1 日志输出到文件
自己搜集整理:
# Python3,支持3.9之前版本和之后版本
import logging
logger = logging.getLogger("mylogger")
logger.setLevel(level = logging.DEBUG)
handler = logging.FileHandler("log.txt", mode='a', encoding="utf-8")
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
log.txt文件内容:
2017-07-25 15:02:09,905 - __main__ - INFO - Start print log
....等等
2.3 日志同时输出到文件和控制台
自己搜集整理:
# Python3,支持3.9之前版本和之后版本
import logging
# 设置日志的基本级别
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.DEBUG)
# 设置文件的日志格式和级别
handler = logging.FileHandler("log.txt", mode='a', encoding="utf-8")
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# 设置控制台日志输出级别
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
logger.addHandler(handler) # 输出到文件
logger.addHandler(console) # 输出到控制台
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
控制台和文件均显示如下内容:
2017-07-25 15:03:05,075 - __main__ - INFO - Start print log
...等等
3 项目中的用法
在多文件的项目中,可如此使用。
# 日志
# mylogger.py
import time
import logging
class MyLogger():
def __init__(self):
pass
def getLogger(self):
logger = logging.getLogger("mylogger")
logger.setLevel(level=logging.DEBUG)
# format
baseFormat = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' # 时间-logger名-级别-消息
funcFormat = '%(asctime)s - %(filename)s - %(funcName)s - %(lineno)d - %(message)s' # 时间-文件-函数-行号-消息
# 输出到文件
handler = logging.FileHandler("log.txt", mode='w', encoding="utf-8")
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
# 输出到控制台
console = logging.StreamHandler()
formatter = logging.Formatter(funcFormat)
console.setFormatter(formatter)
console.setLevel(logging.DEBUG)
logger.addHandler(console)
return logger
# 单例模式,全局独此一个对象,其他类直接使用此对象
logger = MyLogger().getLogger()
if __name__ == '__main__':
logger.info("hello")
其他的类使用日志时,如此使用:
from mylogger import logger
logger.info("=======================")
注意:如果其他类多次调用 MyLogger().getLogger() ,会出现日志重复的情况。因为 logger 的addHandler 多次执行时会重复添加handle,此时logger没有重复,但是logger的 handle在不断的重复添加,结果就是控制台和文件中的日志会出现多条一模一样的内容。
之所以在 MyLogger 类中创建logger对象并暴露在外,就是为了避免其他外部类再次调用 getLoger() 方法,外部类使用日志时直接使用暴露出来的 logger 即可。这样就保证 logger 仅有2个 handle,分别是控制台和文件。
logger.addHandler(handler)
logger.addHandler(console)
更多细节配置,参考: