日志等级
| 日志等级(level) | 描述 |
|---|---|
| DEBUG | 最详细的日志信息,典型应用场景是 问题诊断 |
| INFO | 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作 |
| WARNING | 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的 |
| ERROR | 由于一个更严重的问题导致某些功能不能正常运行时记录的信息 |
| CRITICAL | 当发生严重错误,导致应用程序不能继续运行时记录的信息 |
import logginglogging.debug("debug_msg")logging.info("info_msg")logging.warning("warning_msg")logging.error("error_msg")logging.critical("critical_msg")
输出结果:
WARNING:root:warning_msgERROR:root:error_msgCRITICAL:root:critical_msg
结果包含:日志级别:记录器名:信息。
默认的日志级别为WARNING。
修改日志基础配置
logging.baseConfig()函数能够修改日志的基础配置
日志级别
传入参数level=logging.DEBUG来修改默认日志级别。
存入文件
传入参数filename='xxx.log'将日志存储至文件中,默认是以追加的方式filemode='a'写入。
可以传入参数filemode='w'来使日志先清空再写入。
定义日志输出格式
传入参数format="%(acstime)s %(message)s",传入多个下面表格中的格式,来设定输出的内容及格式。
如需要修改输出的日期格式,可以传入参数datefmt='%Y-%m-%d %H:%M:%S'
| 属性 | 格式 | 描述 |
|---|---|---|
| asctime | %(asctime)s | 日志产生的时间,默认格式为2003-07-0816:49:45,896 |
| msecs | %(msecs)d | 日志生成时间的亳秒部分 |
| created | %(created)f | time.tme)生成的日志创建时间戳 |
| message | %(message)s | 具体的日志信息 |
| filename | %(filename)s | 生成日志的程序名 |
| name | %(name)s | 日志调用者 |
| funcname | %( funcname)s | 调用日志的函数名 |
| levelname | %(levelname)s | 日志级別( DEBUG,INFO, WARNING, ‘ERRORCRITICAL) |
| levene | %( leveling)s | 日志级别对应的数值 |
| lineno | %(lineno)d | 日志所针对的代码行号(如果可用的话) |
| module | %( module)s | 生成日志的模块名 |
| pathname | %( pathname)s | 生成日志的文件的完整路径 |
| process | %( (process)d | 生成日志的进程D(如果可用) |
| processname | (processname)s | 进程名(如果可用) |
| thread | %(thread)d | 生成日志的线程D(如果可用) |
| threadname | %( threadname)s | 线程名(如果可用) |
高级应用
相关组件
| 名称 | 作用 |
|---|---|
| Loggers | 记录器,相当于’笔’,可以向文件,console,邮件等地方写,提供应用的调用接口 |
| Handlers | 处理器,将记录器产生的日志发送至目的地 |
| Filters | 过滤器,提供更好的粒度控制,决定哪些日志会被输出 |
| Formatters | 格式化器,设置日志内容的组成结构和消息字段 |
工作流程
loggers
- 提供应用程序的调用接口
logger=logging.getLogger(_name_)
- 决定日志记录的级别
logger.setLevel()
- 将日志内容传递到相关联的handlers中
logger.addHandIer()和logger.removeHandler()
handlers
它们将日志分发到不同的目的地。可以是文件、标准输出、邮件、或者通过 socke、htt等协议发送到任何地方setFormatter():设置当前Handler对象使用的消息格式
StreamHandler
标准输出分发器sh = logging.StreamHandler(stream=None)
FileHandler
将日志保存到磁盘文件的处理器fh = logging.FileHandler(filename,mode='a',encoding=None,delay=False)
其他
- BaseRotatingHandler
- Rotating Filehandler
- TimedRotatingfilehandler
- Sockethandler
- Dataaramhandler
- Smtphandler
- Sysloghandler
- Nteventloghandler
- Httphandler
- WatchedFilehandler
- Qutelehandler
- Nullhandler
Formatters
Formatter对象用来最终设置日志信息的顺序、结构和内容。
其构造方法为ft=logging.Formatter._init_(fmt=None,datefmt=None,style='%')
datefmt默认是%Y-%m-%d%H:%M:%S样式的。
style参数默认为百分符%,这表示%(<dictionarykey>)s格式的字符串例子
编程方式
```python记录器
logger = logging.getLogger(‘cn.cccb.applog’) logger.setLevel(logging.DEBUG)必须设置为两个handler中级别更低的
处理器handler
consoleHandler = logging.StreamHandler() consoleHandler.setLevel(logging.DEBUG)
没有给handler指定日志级别,将使用logger的级别
fileHandler = logging.FileHandler(filename=’addDemo.log’) consoleHandler.setLevel(logging.INFO)
formatter格式
formatter = logging.Formatter(“%(asctime)s|%(levelname)8s|%(filename)10s%lineno)s|%(message)s”)
里面的8,10实现了占位对齐
给处理器设置格式
consoleHandler.setFormatter(formatter) fileHandler.setFormatter(formatter)
记录器要设置处理器
logger.addHandler(consoleHandler) logger.addHandler(fileHandler)
定义一个过滤器
flt = logging.Filter(“cn.cccb”)
关联过滤器
logger.addFilter(flt)
fileHandler.addFilter(flt)
打印日志的代码
logging.debug()#不能使用这个了!!!会使用WARNING的版本,不会用之前的记录器
logger.debug(“姓名 %s, 年龄%d”,name,age) logger.debug(“姓名 %s, 年龄%d”,% (name,age)) logger.debug(“姓名 {}, 年龄{}”。format(name,age)) logger.debug(f”姓名{name}, 年龄{age}”)
<a name="H5ejx"></a>## 配置文件方式(推荐)<a name="cIkah"></a>### conf文件配置文件`logging.conf````python#./logging.conf#记录器:提供应用程序代码直接使用的接口#设置记录器名称,root必须存在!!![loggers]keys=root,applog#处理器,将记录器产生的日志发送至目的地#设置处理器类型[handlers]keys=fileHandler,consoleHandler#格式化器,设置日志内容的组成结构和消息字段#设置格式化器的种类[formatters]keys=simpleFormatter#设置记录器root的级别与种类[logger_root]level=DEBUGhandlers=consoleHandler#设置记录器applog的级别与种类[logger_applog]level=DEBUGhandlers=fileHandler,consoleHandler#起个对外的名字qualname=applog#继承关系propagate=0#设置[handler_consoleHandler]class=StreamHandlerargs=(sys.stdout,)level=DEBUGformatter=simpleFormatter[handler_fileHandler]class=handlers.TimedRotatingFileHandler#在午夜1点(3600s)开启下一个log文件,第四个参数0表示保留历史文件args=('applog.log','midnight',3600,0)level=DEBUGformatter=simpleFormatter[formatter_simpleFormatter]format=%(asctime)s|%(levelname)8s|%(filename)s[:%(lineno)d]|%(message)s#设置时间输出格式datefmt=%Y-%m-%d %H:%M:%S
Python代码:
import logging
import logging.config
logging.config.fileConfig('logging.conf')
#使用字典就能从任意格式文件进行配置,字典是一种接口格式
# logging.config.dictConfig({"loggers":"root,applog"})
rootLogger = logging.getLogger('applog')
rootLogger.debug("This is root Logger, debug")
logger = logging.getLogger('cn.cccb.applog')
logger.debug("This is applog, debug")
try:
int(a)
except Exception as e:
logger.exception(e)
json文件
{
"version":1,
"loggers":{
"root":{
"level":"WARNING",
"handlers":["error_console_handler"]
},
"fc_logger":{
"level":"DEBUG",
"handlers":["info_console_handler","info_file_handler"]
}
},
"handlers":{
"error_console_handler":{
"class":"logging.StreamHandler",
"level":"ERROR",
"formatter":"errorFormatter",
"stream":"ext://sys.stdout"
},
"info_console_handler":{
"class":"logging.StreamHandler",
"level":"INFO",
"formatter":"infoFormatter",
"stream":"ext://sys.stdout"
},
"info_file_handler":{
"class":"logging.handlers.TimedRotatingFileHandler",
"level":"INFO",
"formatter":"infoFormatter",
"filename":"./log/fc_check.log",
"when": "M",
"encoding": "utf8"
}
},
"formatters":{
"errorFormatter": {
"format":"%(asctime)s %(levelname)s %(filename)s line:%(lineno)d %(message)s",
"datefmt":"%Y-%m-%d %H:%M:%S"
},
"infoFormatter":{
"format":"%(asctime)s %(message)s",
"datefmt":"%Y-%m-%d %H:%M:%S"
}
}
}
代码如下:
with open(r"config/log_config.json", "r") as config_json:
log_config = json.load(config_json)
logging.config.dictConfig(log_config)
fc_logger = logging.getLogger("fc_logger")
console_logger = logging.getLogger("root")
