Python Logging

一、简介

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": "<module>", "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": "<module>", "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": "<module>", "logger": "__main__.task"}

四、ES

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

import logging
import json
import time
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk

es = Elasticsearch("http://localhost:9200")

class ElasticsearchHandler(logging.Handler):
    def __init__(self, index_name):
        super().__init__()
        self.index_name = index_name

    def 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": "<module>",
                    "logger": "__main__.ansible"
                }
            }
        ]
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值