文章目录
LOG
日志相关概念
-
日志
- 日志是一种可以追踪某些软件运行时所发生事件的方法。软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。一个事件可以用一个可包含可选变量数据的消息来描述。此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)。
-
日志的级别
- 不同的用户关注不同的程序信息
- DEBUG
- INFO
- NOTICE
- WARNING
- ERROR
- CRITICAL
- ALERT
- EMERGENCY
-
IO操作不要太频繁
-
LOG的作用
- 调试
- 了解软件的运行状况
- 分析定位问题
通过log的分析,可以方便用户了解系统或软件、应用的运行情况;如果你的应用log足够丰富,也可以分析以往用户的操作行为、类型喜好、地域分布或其他更多信息;如果一个应用的log同时也分了多个级别,那么可以很轻易地分析得到该应用的健康状况,及时发现问题并快速定位、解决问题,补救损失。
简单来讲就是,我们通过记录和分析日志可以了解一个系统或软件程序运行情况是否正常,也可以在应用程序出现故障时快速定位问题。比如,做运维的同学,在接收到报警或各种问题反馈后,进行问题排查时通常都会先去看各种日志,大部分问题都可以在日志中找到答案。再比如,做开发的同学,可以通过IDE控制台上输出的各种日志进行程序调试。对于运维老司机或者有经验的开发人员,可以快速的通过日志定位到问题的根源。可见,日志的重要性不可小觑。 -
日志信息包括
- 时间
- 地点
- level
- 内容
-
成熟的第三方日志工具
- log4j
- log4php
- logging
logging模块
-
logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python模块都可以使用这个日志记录功能。所以,你的应用日志可以将你自己的日志信息与来自第三方模块的信息整合起来。
-
日志级别
-
级别可自定义
DEBUG 最详细的日志信息,典型应用场景是 问题诊断 INFO 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作 WARNING 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的 ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息 CRITICAL 当发生严重错误,导致应用程序不能继续运行时记录的信息
-
-
初始化/写日志实例需要指定级别,只有当级别等于或高于指定级别才别记录
-
使用方式
- 直接使用logging(封装了其他软件)
- Logging四大组件直接定制
其实,logging所提供的模块级别的日志记录函数也是对logging日志系统相关类的封装而已。
logging模块级别的日志
-
logging模块定义的模块级别的常用函数
logging.debug(msg, *args, **kwargs) 创建一条严重级别为DEBUG的日志记录 logging.info(msg, *args, **kwargs) 创建一条严重级别为INFO的日志记录 logging.warning(msg, *args, **kwargs) 创建一条严重级别为WARNING的日志记录 logging.error(msg, *args, **kwargs) 创建一条严重级别为ERROR的日志记录 logging.critical(msg, *args, **kwargs) 创建一条严重级别为CRITICAL的日志记录 logging.log(level, *args, **kwargs) 创建一条严重级别为level的日志记录 logging.basicConfig(**kwargs) 对root logger进行一次性配置
-
logging.basicConfig(**kwargs)
- 只在第一次调用的时候起作用
- 不配置logger则使用默认值
- 输出:sys.stderr
- 级别:WARNING
- 格式:level:log_name:content
上面这些都是一条日志记录中可能包含的字段信息,当然还可以包括一些其他信息,如进程ID、进程名称、线程ID、线程名称等。日志格式就是用来定义一条日志记录中包含那些字段的,且日志格式通常都是可以自定义的。
- 最简单的日志输出
import logging
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
- 也可以这样写:
logging.log(logging.DEBUG, "This is a debug log.")
logging.log(logging.INFO, "This is a info log.")
logging.log(logging.WARNING, "This is a warning log.")
logging.log(logging.ERROR, "This is a error log.")
logging.log(logging.CRITICAL, "This is a critical log.")
# 输出
WARNING:root:This is a warning log.
ERROR:root:This is a error log.
CRITICAL:root:This is a critical log.
-
为什么前面两条日志没有被打印出来
- 这是因为logging模块提供的日志记录函数所使用的日志器设置的日志级别是WARNING,因此只有WARNING级别的日志记录以及大于它的ERROR和CRITICAL级别的日志记录被输出了,而小于它的DEBUG和INFO级别的日志记录被丢弃了。
-
修改这些默认设置
- 在我们调用上面这些日志记录函数之前,手动调用一下basicConfig()方法,把我们想设置的内容以参数的形式传递进去就可以了。
- logging.basicConfig(**kwargs)
-
该函数可接收的关键字参数
filename 指定日志输出目标文件的文件名,指定该设置项后日志信心就不会被输出到控制台了 filemode 指定日志文件的打开模式,默认为'a'。需要注意的是,该选项要在filename指定时才有效 format 指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。logging模块定义的格式字段下面会列出。 datefmt 指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效 level 指定日志器的日志级别 stream 指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。需要说明的是,stream和filename不能同时提供,否则会引发 ValueError异常 style Python 3.2中新添加的配置项。指定format格式字符串的风格,可取值为'%'、'{'和'$',默认为'%' handlers Python 3.3中新添加的配置项。该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,不能同时出现2个或3个,否则会引发ValueError异常。
-
列举一下logging模块中定义好的可以用于format格式字符串中字段
字段/属性名称 | 使用格式 | 描述 |
---|---|---|
asctime | %(asctime)s | 日志事件发生的时间–人类可读时间,如:2003-07-08 16:49:45,896 |
created | %(created)f | 日志事件发生的时间–时间戳,就是当时调用time.time()函数返回的值 |
relativeCreated | %(relativeCreated)d | 日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的) |
msecs | %(msecs)d | 日志事件发生事件的毫秒部分 |
levelname | %(levelname)s | 该日志记录的文字形式的日志级别(‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’) |
levelno | %(levelno)s | 该日志记录的数字形式的日志级别(10, 20, 30, 40, 50) |
name | %(name)s | 所使用的日志器名称,默认是’root’,因为默认使用的是 rootLogger |
message | %(message)s | 日志记录的文本内容,通过 msg % args计算得到的 |
pathname | %(pathname)s | 调用日志记录函数的源码文件的全路径 |
filename | %(filename)s | pathname的文件名部分,包含文件后缀 |
module | %(module)s | filename的名称部分,不包含后缀 |
lineno | %(lineno)d | 调用日志记录函数的源代码所在的行号 |
funcName | %(funcName)s | 调用日志记录函数的函数名 |
process | %(process)d | 进程ID |
processName |