日志等级
日志等级(level) | 描述 |
---|---|
DEBUG | 最详细的日志信息,典型应用场景是 问题诊断 |
INFO | 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作 |
WARNING | 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的 |
ERROR | 由于一个更严重的问题导致某些功能不能正常运行时记录的信息 |
CRITICAL | 当发生严重错误,导致应用程序不能继续运行时记录的信息 |
import logging
logging.debug("debug_msg")
logging.info("info_msg")
logging.warning("warning_msg")
logging.error("error_msg")
logging.critical("critical_msg")
输出结果:
WARNING:root:warning_msg
ERROR:root:error_msg
CRITICAL: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=DEBUG
handlers=consoleHandler
#设置记录器applog的级别与种类
[logger_applog]
level=DEBUG
handlers=fileHandler,consoleHandler
#起个对外的名字
qualname=applog
#继承关系
propagate=0
#设置
[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter
[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
#在午夜1点(3600s)开启下一个log文件,第四个参数0表示保留历史文件
args=('applog.log','midnight',3600,0)
level=DEBUG
formatter=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")