python 日志类
简介
在所有项目中必不可少的一定是日志记录系统,python为我们提供了一个比较方便的日志模块logging,通常,我们都会基于此模块编写一个日志记录类,方便将项目中的日志记录到文件中。
logging
日志主要分为如下几个等级。
| 日志等级 | 描述 |
|---|---|
| DEBUG | 详细信息,通常仅在诊断问题时才有意义。 |
| INFO | 无异常时输出的日志,主要是确认程序是否正常按照预期进行的 |
| WARNING | 当出现一些异常信息(例如磁盘空间不足)时,但是不会影响程序的正常执行 |
| ERROR | 当出现问题时导致程序无法正常运行时 |
| CRITICAL | 当出现严重问题时导致程序无法继续运行时 |
import logging
logging.info("info")
logging.warning("warning")
logging.debug("debug")
logging.error("error")
logging.critical("critical")
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
由此可见,info,debug信息未输出,是因为默认的level等级是warning。
logging模块中的四个基本类和对应功能
| 名称 | 功能 |
|---|---|
| Loggers | 公开应用程序代码直接使用的接口。 |
| Handlers | 将日志记录(由记录器创建)发送到适当的目的地(标准输出、文件等)。 |
| Filters | 提供了更细粒度的工具来确定要输出哪些日志记录。 |
| Formatters | 指定最终输出中日志记录的布局。 |
日志输出到文件
使用basicConfig进行配置
logging.basicConfig(filename="test.log", level=logging.INFO)
logging.info("info")
logging.warning("warning")
logging.debug("debug")
logging.error("error")
logging.critical("critical")
INFO:root:info
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
由上述日志可得出:日志的组成
日志等级:日志记录器名称:日志内容
那么如何修改记录器名称?
通过如下方式可以实现记录器名称的修改
logger = logging.getLogger("test")
logging.basicConfig(filename="test.log", level=logging.INFO)
logger.info("info")
logger.warning("warning")
logger.debug("debug")
logger.error("error")
logger.critical("critical")
INFO:test:info
WARNING:test:warning
ERROR:test:error
CRITICAL:test:critical
由上述可见,虽然修改了记录器的名称,但格式还是不那么容易读懂的,因此需要修改一下日志的格式
如何修改日志输出的格式呢?
通过basicConfig中的format来修改
asctime:当前时间,levelname:等级名称,message:日志信息
logger = logging.getLogger("test")
logging.basicConfig(
filename="test.log",
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s",
)
logger.info("info")
logger.warning("warning")
logger.debug("debug")
logger.error("error")
logger.critical("critical")
Handler
处理器对象:将适当的日志消息(基于日志消息的严重性)分派到处理程序的指定目的地。 Logger 对象可以使用 addHandler() 方法向自己添加零个或多个处理程序对象。作为示例场景,应用程序可能希望将所有日志消息发送到日志文件,将所有错误或更高级别的日志消息发送到标准输出,并将所有关键消息发送到电子邮件地址。此方案需要三个单独的处理程序,其中每个处理程序负责将特定严重性的消息发送到特定位置。
handler主要有以下几种,此处列举出常用的几种。
| 名称 | 作用 |
|---|---|
| StreamHandler | 用于将日志记录直接在终端中输出 |
| FileHandler | 用于将日志记录输出到磁盘中 |
| NullHandler | 用于对日志记录不做任何输出 |
| RotatingFileHandler | 用于达到一定大小时,自动生成新的日志文件, 只适用于Linux |
| TimedRotatingFileHandler | 用于对每天的日志文件进行输出, 只适用于Linux |
Formatters
格式化对象:将日志转换成text并按照指定格式格式化输出日志字符串的格式。
常用的参数:fmt=None, datefmt=None
fmt:日志的展示格式,例如:
# 代表时间 日志等级 日志信息
%(asctime)s %(levelname)s %(message)s
主要有以下显示格式
%(name)s 记录器的名称(记录通道)
%(levelno)s 消息的数字日志级别(DEBUG、INFO、WARNING、ERROR、CRITICAL)
%(levelname)s 消息的文本记录级别 ("DEBUG", "INFO", WARNING、ERROR、CRITICAL)
%(pathname)s 记录日志的源文件的完整路径名已发出呼叫(如果可用)
%(filename)s 路径名的文件名部分
%(module)s 模块(文件名的名称部分)
%(lineno)d 发出记录调用的源行号(如果可供使用的话)
%(funcName)s 函数名
%(created)f 创建日志记录的时间 (time.time()返回值)
%(asctime)s 创建 LogRecord 的文本时间
%(msecs)d 创建时间的毫秒部分
%(relativeCreated)d 创建 LogRecord 的时间(以毫秒为单位),相对于加载日志模块的时间(通常在应用程序启动时)
%(thread)d 线程 ID(如果可用)
%(threadName)s 线程名称(如果可用)
%(process)d 进程 ID(如果可用)
%(message)s record.getMessage() 的结果,计算方式为 记录发出
datefmt:日志信息的时间格式,例如:
%Y-%m-%d %H:%M:%S
简单的日志记录类
import logging
def log():
# 创建一个日志对象
log = logging.getLogger("test")
# 设置记录器发给处理器handler的最低等级
log.setLevel(logging.DEBUG)
# 创建一个处理器用于设置日志对象
handler = logging.StreamHandler()
# 设置handler发送给目标的最低等级
handler.setLevel(logging.DEBUG)
# 创建格式器,设置输出日志格式
format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(format)
log.addHandler(handler)
return log
test_log: logging.Logger = log()
test_log.info("info")
test_log.debug("debug")
test_log.error("error")
test_log.critical("critical")
2022-07-12 17:19:23,396 - test - INFO - info
2022-07-12 17:19:23,396 - test - DEBUG - debug
2022-07-12 17:19:23,396 - test - ERROR - error
2022-07-12 17:19:23,396 - test - CRITICAL - critical
从配置文件中读取配置进行输出日志
import logging
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('simpleExample')
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
logging.conf
[loggers]
keys=root,simpleExample
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
2022-07-12 17:22:55,953 - simpleExample - DEBUG - debug message
2022-07-12 17:22:55,953 - simpleExample - INFO - info message
2022-07-12 17:22:55,953 - simpleExample - WARNING - warn message
2022-07-12 17:22:55,953 - simpleExample - ERROR - error message
2022-07-12 17:22:55,953 - simpleExample - CRITICAL - critical message
通过配置文件方式进行日志格式的处理与上述类似。
日志记录类
下面的日志记录类,可以方便在项目中进行直接使用或者简单修改一下使用。
类方式实现
import logging
import pathlib
class Log:
def __init__(self, file_name, logger_name=None):
self.file_name = file_name
self.logger = logging.getLogger(logger_name)
self.logger.setLevel(logging.DEBUG)
self.get_log()
def get_log(self):
# FileHandler: 将格式化的日志记录写入磁盘文件的处理程序类
# 将格式化的日志记录写入磁盘文件的处理程序
handler = logging.FileHandler(self.file_name)
handler.setLevel(logging.DEBUG)
formater = logging.Formatter(
"%(asctime)s:%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s"
)
handler.setFormatter(formater)
self.logger.addHandler(handler)
def info(self, msg):
self.logger.info(msg)
def debug(self, msg):
self.logger.debug(msg)
def warning(self, msg):
self.logger.warning(msg)
def error(self, msg):
self.logger.error(msg)
def critical(self, msg):
self.logger.critical(msg)
log_path = pathlib.Path(__file__).parent.joinpath("test.log")
log = Log(log_path)
log.info("info")
2022-07-12 17:51:14,069:logger.py:24:root:INFO:info
目前发现日志的对应行数是类中的行数,使用函数方式则不会出现此问题
函数方式
def Log2(file_name, logger_name=None):
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(file_name)
handler.setLevel(logging.DEBUG)
formater = logging.Formatter(
"%(asctime)s:%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s"
)
handler.setFormatter(formater)
logger.addHandler(handler)
return logger
log = Log2(log_path)
log.info("info")
2022-07-12 17:53:40,661:logger.py:59:root:INFO:info
参考
python 日志类的更多相关文章
- python 日志的配置,python对日志封装成类,日志的调用
# python 日志的配置,python对日志封装成类,日志的调用 import logging # 使用logging模块: class CLog: # --------------------- ...
- 简单实用的日志类CLog (Python版)
#coding: utf-8 import time ''' /***************************************************************** Fu ...
- python日志模块
许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系 统的运行状况进行跟踪.在.NET平台中,有非常著名的第三方开源日志组件log4net,c++中,有人们熟悉的log4c ...
- Python日志输出——logging模块
Python日志输出——logging模块 标签: loggingpythonimportmodulelog4j 2012-03-06 00:18 31605人阅读 评论(8) 收藏 举报 分类: P ...
- Python3自定义日志类教程
一.说明 Python3的logging功能是比较丰富的支持不同层次的日志输出,但或是我们想在日志前输出时间.或是我们想要将日志输入到文件,我们还是想要自定义日志类. 之前自己也尝试写过但感觉文档太乱 ...
- Python 日志输出中添加上下文信息
Python日志输出中添加上下文信息 除了传递给日志记录函数的参数(如msg)外,有时候我们还想在日志输出中包含一些额外的上下文信息.比如,在一个网络应用中,可能希望在日志中记录客户端的特定信息,如: ...
- 孤荷凌寒自学python第二十一天初识python的类
孤荷凌寒自学python第二十一天初识python的类 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 类是面向对象的编程语言非常重要的概念. 编程语言的进化史中从顺序编程到结构化编程,最后才 ...
- Python - 关于类(self/cls) 以及 多进程通讯的思考
Python-多进程中关于类以及类实例的一些思考 目录 Python-多进程中关于类以及类实例的一些思考 1. 背景 2. Python 类中的函数 - staticmethod / classmet ...
- [C#] 日志类
在程序发布到服务器上的时候,不能在像本地执行一样可以调试,在发生错误时候,往往不能很方便的查找错误.将错误信息写入文件是一种比较常用的处理方法.以下是一个日志类,实现以下功能: 1)按日期每天生产不同 ...
随机推荐
- 隐藏浏览器header中X-Powered-By: PHP信息
在php程序中,默认会在http请求响应头中输出php版本信息.如下: HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Date: Tue ...
- 一个关于 useState 的误解
一个关于 useState 的误解 本文写于 2020 年 11 月 17 日 前两天有人问了我一个问题,他有一段这样的代码: function App() { const [n, setN] = u ...
- 拯救一切强迫症 - 读《编写可维护的 JavaScript》(一)
拯救一切强迫症 - 读<编写可维护的 JavaScript>(一) 本文写于 2020 年 4 月 24 日 我在小学的时候就有接触过编程,所以读大一的时候 C 语言还算是轻车熟路.自然会 ...
- JWT 访问令牌
JWT 访问令牌 更为详细的介绍jwt 在学习jwt之前我们首先了解一下用户身份验证 1 单一服务器认证模式 一般过程如下: 用户向服务器发送用户名和密码. 验证服务器后,相关数据(如用户名,用户角色 ...
- 561. Array Partition I - LeetCode
Question 561. Array Partition I Solution 题目大意是,给的数组大小是2n,把数组分成n组,每组2个元素,每个组取最小值,这样就能得到n个值,怎样分组才能使这n个 ...
- linux篇-linux 下建立多个tomcat
第一步:复制,解压 将准备好的tomcat压缩包复制到你准备安装的目录,我的tomcat压缩包名字是tomcat.tar.gz,我的安 装目录是 /usr/java/tomcat 第二步:解压tomc ...
- 好客租房14-在jsx中使用javascript表达式的注意点
注意点 单大括号中可以使用任意的表达式 jsx自身也是js表达式 注意:js中的对是一个例外 写在style样式中 //导入react import React from "reac ...
- python之部分内置函数与迭代器与异常处理
目录 常见内置函数(部分) 可迭代对象 迭代器对象 for循环内部原理 异常处理 异常信息的组成部分 异常的分类 异常处理实操 异常处理的其他操作 for循环本质 迭代取值与索引取值的区别 常见内置函 ...
- 编程语言与python与pycharm的下载
目录 编程语言的发展史 编程语言的分类 python解释器 python解释器的下载与安装 环境变量 执行python程序方式 pycharm编辑器 编程语言的发展史 机器语言是最开始的编程语言,之后 ...
- 对TCP粘包拆包的理解
TCP的粘包与拆包 TCP是一种字节流(byte-stream)协议,所谓流,就是没有界限的一串数据. 一个完整的包会被TCP拆为多个包进行发送,也有可能把多个小包封装成一个大的数据包发送,这就是所谓 ...