Python Logging
创始人
2025-06-01 04:52:14

一、简介

Python的logging模块提供了一种灵活的方式来记录日志信息。使用logging模块,你可以将日志记录到文件、控制台、syslog等不同的目标中,还可以根据日志级别过滤日志信息。logging模块还支持多个日志处理器和多个日志过滤器,可以根据需要自定义日志记录方式。

1.1 功能

getLogger()方法:用于获取logger对象。如果多次调用getLogger()方法并传入相同的名称,将返回同一个logger对象。如果不传入名称,则返回root logger对象。

formatter:格式化器,用于将LogRecord对象转换为字符串。logging模块中提供了多种格式化器,如BasicFormatter、Formatter等。

handler:处理器,用于将日志记录发送到不同的目标,如文件、控制台、syslog等。logging模块中提供了多种处理器,如StreamHandler、FileHandler、SysLogHandler等。

getChild()方法:用于创建子logger对象。子logger对象的名称是父logger对象的名称加上一个后缀,后缀由getChild()方法的参数指定。子logger对象继承了父logger对象的所有属性,如日志级别、过滤器、处理器等。子logger对象还可以设置自己的属性,如日志级别、过滤器、处理器等。

logger:日志器,用于记录日志信息。logger对象可以有多个,每个logger对象可以有多个handler对象,用于将日志记录发送到不同的目标。logger对象还可以设置日志级别、过滤器等属性,用于控制日志记录的行为。

1.2 用途

  • 可以定义多种级别,按需记录
    如:debug,info,warning,error,critical
  • 可以配置多套日志方式,记录到多个文件中
    如:根据需求记录到多个文件中,app.log, task.log
  • 可以配置不同的Handler,控制日志以什么载体记录
    如:log文件,stdout,elasticsearch等

二、文本格式

日志具体以什么载体展示取决于formatter参数,例如:
formatter = logging.Formatter(“%(asctime)s %(levelname)s %(message)s”,“%Y-%m-%d %H:%M:%S”)

import logging
import json
from logging.handlers import RotatingFileHandler# 获取logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)# 日志格式
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s","%Y-%m-%d %H:%M:%S")# 根据业务的不同日志,定义不同的handler
ansible_handler = RotatingFileHandler('/tmp/ansible.log', maxBytes=100000000, backupCount=100)
ansible_handler.setLevel(logging.DEBUG)
ansible_handler.setFormatter(formatter)task_handler = RotatingFileHandler('/tmp/task.log', maxBytes=100000000, backupCount=100)
task_handler.setLevel(logging.INFO)
task_handler.setFormatter(formatter)app_handler = RotatingFileHandler('/tmp/app.log', maxBytes=100000000, backupCount=100)
app_handler.setLevel(logging.INFO)
app_handler.setFormatter(formatter)# 方法用于创建子记录器,从而更好地组织你的日志信息。子记录器会继承父记录器的配置,但是你可以为它们单独设置日志级别、处理器等。
logger.getChild('ansible').addHandler(ansible_handler)
logger.getChild('task').addHandler(task_handler)
logger.getChild('app').addHandler(app_handler)# 获取子记录器
ansibleLogger = logger.getChild('ansible')
taskLogger = logger.getChild('task')
appLogger = logger.getChild('app')# 写入日志
ansibleLogger.info('这是ansible运行日志')
taskLogger.info('这是后端任务运行日志')
appLogger.info('这是主程序运行日志')

运行日志

yuehua@yuehuadeMacBook-Pro ~$ cat /tmp/app.log
2023-03-21 17:11:29 INFO 这是主程序运行日志
yuehua@yuehuadeMacBook-Pro ~$ cat /tmp/task.log
2023-03-21 17:11:29 INFO 这是后端任务运行日志
yuehua@yuehuadeMacBook-Pro ~$ cat /tmp/ansible.log
2023-03-21 17:11:29 INFO 这是ansible运行日志

三、JSON格式

可以定义一个JsonFormatter类,继承logging.Formatter类,重写format
然后将 formatter 指向这个类的实例对象

import logging
import json
from logging.handlers import RotatingFileHandler# 获取logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)# 日志格式(JSON)
class JsonFormatter(logging.Formatter):def format(self, record):data = {'timestamp': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(record.created)),'level': record.levelname,'message': record.getMessage(),'module': record.module,'line': record.lineno,'function': record.funcName,'logger': record.name,}return json.dumps(data)
formatter = JsonFormatter()# 根据业务的不同日志,定义不同的handler
ansible_handler = RotatingFileHandler('/tmp/ansible.log', maxBytes=100000000, backupCount=100)
ansible_handler.setLevel(logging.DEBUG)
ansible_handler.setFormatter(formatter)task_handler = RotatingFileHandler('/tmp/task.log', maxBytes=100000000, backupCount=100)
task_handler.setLevel(logging.INFO)
task_handler.setFormatter(formatter)app_handler = RotatingFileHandler('/tmp/app.log', maxBytes=100000000, backupCount=100)
app_handler.setLevel(logging.INFO)
app_handler.setFormatter(formatter)# 方法用于创建子记录器,从而更好地组织你的日志信息。子记录器会继承父记录器的配置,但是你可以为它们单独设置日志级别、处理器等。
logger.getChild('ansible').addHandler(ansible_handler)
logger.getChild('task').addHandler(task_handler)
logger.getChild('app').addHandler(app_handler)# 获取子记录器
ansibleLogger = logger.getChild('ansible')
taskLogger = logger.getChild('task')
appLogger = logger.getChild('app')# 写入日志
ansibleLogger.info('这是ansible运行日志')
taskLogger.info('这是后端任务运行日志')
appLogger.info('这是主程序运行日志')

运行日志

yuehua@yuehuadeMacBook-Pro ~$ cat /tmp/app.log
{"timestamp": "2023-03-21 17:29:44", "level": "INFO", "message": "\u8fd9\u662f\u4e3b\u7a0b\u5e8f\u8fd0\u884c\u65e5\u5fd7", "module": "wlwlwl1", "line": 55, "function": "", "logger": "__main__.app"}
yuehua@yuehuadeMacBook-Pro ~$ cat /tmp/ansible.log
{"timestamp": "2023-03-21 17:29:44", "level": "INFO", "message": "\u8fd9\u662fansible\u8fd0\u884c\u65e5\u5fd7", "module": "wlwlwl1", "line": 53, "function": "", "logger": "__main__.ansible"}
yuehua@yuehuadeMacBook-Pro ~$ cat /tmp/task.log
{"timestamp": "2023-03-21 17:29:44", "level": "INFO", "message": "\u8fd9\u662f\u540e\u7aef\u4efb\u52a1\u8fd0\u884c\u65e5\u5fd7", "module": "wlwlwl1", "line": 54, "function": "", "logger": "__main__.task"}

四、ES

定义一个 ElasticsearchHandler 的处理器,继承 logging.Handler 类,将业务日志的handler指向这个ElasticsearchHandler的实例对象,并在初始化的时候,传入一个索引名称。

import logging
import json
import time
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulkes = Elasticsearch("http://localhost:9200")class ElasticsearchHandler(logging.Handler):def __init__(self, index_name):super().__init__()self.index_name = index_namedef emit(self, record):log = {'timestamp': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(record.created)),'level': record.levelname,'message': record.getMessage(),'module': record.module,'line': record.lineno,'function': record.funcName,'logger': record.name,}es.index(index=self.index_name, body=log)# 获取logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)# 根据业务的不同日志,定义不同的handler
ansible_handler = ElasticsearchHandler('ansible')
ansible_handler.setLevel(logging.DEBUG)task_handler = ElasticsearchHandler('task')
task_handler.setLevel(logging.INFO)app_handler = ElasticsearchHandler('app')
app_handler.setLevel(logging.INFO)# 方法用于创建子记录器,从而更好地组织你的日志信息。子记录器会继承父记录器的配置,但是你可以为它们单独设置日志级别、处理器等。
logger.getChild('ansible').addHandler(ansible_handler)
logger.getChild('task').addHandler(task_handler)
logger.getChild('app').addHandler(app_handler)# 通过子记录器获取日志对象
ansibleLogger = logger.getChild('ansible')
taskLogger = logger.getChild('task')
appLogger = logger.getChild('app')ansibleLogger.info('这是ansible运行日志')
taskLogger.info('这是后端任务运行日志')
appLogger.info('这是主程序运行日志')

获取日志

{"took": 4,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 1.0,"hits": [{"_index": "ansible","_type": "_doc","_id": "ymKhA4cBiDjJ60c3P1Wo","_score": 1.0,"_source": {"timestamp": "2023-03-21 18:05:10","level": "INFO","message": "\u8fd9\u662fansible\u8fd0\u884c\u65e5\u5fd7","module": "wlwlwl1","line": 50,"function": "","logger": "__main__.ansible"}}]}
}

相关内容

热门资讯

重大通报“新二号大厅到底是不是... 您好:新二号大厅这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在新二号大...
科技通报“ 无双大厅 有没有挂... 您好,无双大厅这个游戏其实有挂的,确实是有挂的,需要了解加客服微信【6676724】很多玩家在无双大...
玩家必看“新皇豪斗牛开挂透视软... 您好:新皇豪斗牛这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在新皇豪斗...
重大通报-"广客麻将... 您好:广客麻将这款游戏是可以开挂的,究竟有没有挂确实能开挂,了解请添加《75638038》(加我们微...
玩家必看“阿拉丁能不能开挂”附... 您好:阿拉丁这款游戏可以开挂,确实是有挂的,需要软件加微信【5951795】,很多玩家在阿拉丁这款游...