python的日志管理代码

Python日志管理技巧

1:python的日志管理,可以通过修改日记管理的级别修改,打印日志和打印控制台的日志console可以修改console_level=None来修改输出的信息,注意在每一个类中使用log = logging.getLogger(“方法名或者类名”),这样是为了区分日志在个类或者方法输出哪里,方便快速定位问题

import logging
import os
from logging.handlers import TimedRotatingFileHandler


class MyLogFilter(logging.Filter):
    def filter(self, record):
        # 只允许特定名称的日志记录器通过
        return record.name.startswith(('main', 'opcua_worker', 'heartbeat', 'publisher', 'SubHandler', 'mqtt'))


def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, filename)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(lineno)d - %(threadName)s - %(message)s')

    file_handler = TimedRotatingFileHandler(log_path, when='midnight', interval=1, backupCount=30, encoding='utf-8')
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    root = logging.getLogger()
    root.setLevel(level)
    # root.setLevel(logging.WARNING)
    # logging.getLogger('mqtt').setLevel(logging.INFO)

    # logging.getLogger('opcua').setLevel(logging.WARNING)
    # logging.getLogger('paho').setLevel(logging.WARNING)
    # logging.getLogger('urllib3').setLevel(logging.WARNING)

    abs_log_path = os.path.abspath(log_path)
    if not any(isinstance(h, TimedRotatingFileHandler) and getattr(h, "baseFilename", None) == abs_log_path for h in
               root.handlers):
        root.addHandler(file_handler)
        # # 只为新添加的文件处理器添加过滤器
        # file_handler.addFilter(MyLogFilter())

    console_level = console_level if console_level is not None else level
    existing_console = None
    for h in root.handlers:
        if isinstance(h, logging.StreamHandler) and getattr(h, "stream", None) in (sys.stdout, sys.stderr):
            existing_console = h
            break

    if existing_console is None:
        console = logging.StreamHandler(sys.stdout)
        console.setFormatter(formatter)
        console.setLevel(console_level)
        root.addHandler(console)
        # # 只为新添加的控制台处理器添加过滤器
        # console.addFilter(MyLogFilter())
    else:
        existing_console.setFormatter(formatter)
        existing_console.setLevel(console_level)
        # # 只为现有控制台处理器添加过滤器
        # existing_console.addFilter(MyLogFilter())


class LogTest:
    def __init__(self):
        self.log = logging.getLogger("LogTest")
        self.log.info("Log module test1")

    def test_method(self):
        print("test_method")
        self.log.info("This is a debug message from test_method.")
        # 日记级别为level=logging.INFO不会打印debug信息
        self.log.debug("This is a debug message from test_method.")


if __name__ == '__main__':
    setup_logging(log_dir='logs', filename='Run_CX.log')
    log = logging.getLogger("main")
    logTest = LogTest()
    logTest.test_method()
    print("Logging is set up.")
    log.info("Log module test2")

2:生产的日志或者控制台太多的第三包日志,输出只打印自己代码中的日志,可以采取以下几种方法

最原始的日志代码

def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, filename)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(lineno)d - %(threadName)s - %(message)s')

    file_handler = TimedRotatingFileHandler(log_path, when='midnight', interval=1, backupCount=30, encoding='utf-8')
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    root = logging.getLogger()
    root.setLevel(level)

    abs_log_path = os.path.abspath(log_path)
    if not any(isinstance(h, TimedRotatingFileHandler) and getattr(h, "baseFilename", None) == abs_log_path for h in
               root.handlers):
        root.addHandler(file_handler)

    console_level = console_level if console_level is not None else level
    existing_console = None
    for h in root.handlers:
        if isinstance(h, logging.StreamHandler) and getattr(h, "stream", None) in (sys.stdout, sys.stderr):
            existing_console = h
            break

    if existing_console is None:
        console = logging.StreamHandler(sys.stdout)
        console.setFormatter(formatter)
        console.setLevel(console_level)
        root.addHandler(console)

    else:
        existing_console.setFormatter(formatter)
        existing_console.setLevel(console_level)

2-1:方法1:设置根日志记录器级别

def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    # ... 其他代码 ...
    
    # 设置根日志记录器的级别为 WARNING,这样只会显示 WARNING 及以上级别的日志
    root = logging.getLogger()
    root.setLevel(logging.WARNING)
    
    # 然后为你自己的日志记录器设置 INFO 级别
    # 在你的代码中使用特定名称的日志记录器

修改为

def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, filename)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(lineno)d - %(threadName)s - %(message)s')

    file_handler = TimedRotatingFileHandler(log_path, when='midnight', interval=1, backupCount=30, encoding='utf-8')
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    root = logging.getLogger()
    root.setLevel(level)
		
	#插入
    root.setLevel(logging.WARNING)
    logging.getLogger('mqtt').setLevel(logging.INFO)
    logging.getLogger('heartbeat').setLevel(logging.INFO)

    abs_log_path = os.path.abspath(log_path)
    if not any(isinstance(h, TimedRotatingFileHandler) and getattr(h, "baseFilename", None) == abs_log_path for h in
               root.handlers):
        root.addHandler(file_handler)

    console_level = console_level if console_level is not None else level
    existing_console = None
    for h in root.handlers:
        if isinstance(h, logging.StreamHandler) and getattr(h, "stream", None) in (sys.stdout, sys.stderr):
            existing_console = h
            break

    if existing_console is None:
        console = logging.StreamHandler(sys.stdout)
        console.setFormatter(formatter)
        console.setLevel(console_level)
        root.addHandler(console)

    else:
        existing_console.setFormatter(formatter)
        existing_console.setLevel(console_level)

2-2:方法2:为第三方库设置日志级别(常用),推荐使用此方法,因为它最简单且有效,可以精确控制哪些第三方库的日志显示。

def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    # ... 其他代码 ...
    
    root = logging.getLogger()
    root.setLevel(level)
    
    # 抑制第三方库的日志
    logging.getLogger('opcua').setLevel(logging.WARNING)
    logging.getLogger('paho').setLevel(logging.WARNING)
    logging.getLogger('urllib3').setLevel(logging.WARNING)
    
    # ... 其他代码 ...

修改为

def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, filename)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(lineno)d - %(threadName)s - %(message)s')

    file_handler = TimedRotatingFileHandler(log_path, when='midnight', interval=1, backupCount=30, encoding='utf-8')
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    root = logging.getLogger()
    root.setLevel(level)
		
	#插入
    logging.getLogger('opcua').setLevel(logging.WARNING)
    logging.getLogger('paho').setLevel(logging.WARNING)
    logging.getLogger('urllib3').setLevel(logging.WARNING)

    abs_log_path = os.path.abspath(log_path)
    if not any(isinstance(h, TimedRotatingFileHandler) and getattr(h, "baseFilename", None) == abs_log_path for h in
               root.handlers):
        root.addHandler(file_handler)

    console_level = console_level if console_level is not None else level
    existing_console = None
    for h in root.handlers:
        if isinstance(h, logging.StreamHandler) and getattr(h, "stream", None) in (sys.stdout, sys.stderr):
            existing_console = h
            break

    if existing_console is None:
        console = logging.StreamHandler(sys.stdout)
        console.setFormatter(formatter)
        console.setLevel(console_level)
        root.addHandler(console)

    else:
        existing_console.setFormatter(formatter)
        existing_console.setLevel(console_level)

2-3:方法3:使用日志过滤器

class MyLogFilter(logging.Filter):
    def filter(self, record):
        # 只允许特定名称的日志记录器通过
        return record.name.startswith(('main', 'opcua_worker', 'heartbeat', 'publisher', 'SubHandler', 'mqtt'))

def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    # ... 其他代码 ...
    
    root = logging.getLogger()
    root.setLevel(level)
    
    # 为所有处理器添加过滤器
    for handler in root.handlers:
        handler.addFilter(MyLogFilter())
    
    # ... 其他代码 ...

修改为

class MyLogFilter(logging.Filter):
    def filter(self, record):
        # 只允许特定名称的日志记录器通过
        return record.name.startswith(('main', 'opcua_worker', 'heartbeat', 'publisher', 'SubHandler', 'mqtt'))


def setup_logging(log_dir='logs', filename='Run_CX.log', level=logging.INFO, console_level=None):
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, filename)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(lineno)d - %(threadName)s - %(message)s')

    file_handler = TimedRotatingFileHandler(log_path, when='midnight', interval=1, backupCount=30, encoding='utf-8')
    file_handler.setFormatter(formatter)
    file_handler.setLevel(logging.INFO)

    root = logging.getLogger()
    root.setLevel(level)
		
	#插入

    abs_log_path = os.path.abspath(log_path)
    if not any(isinstance(h, TimedRotatingFileHandler) and getattr(h, "baseFilename", None) == abs_log_path for h in
               root.handlers):
        root.addHandler(file_handler)
        # 插入 只为新添加的文件处理器添加过滤器
        file_handler.addFilter(MyLogFilter())

    console_level = console_level if console_level is not None else level
    existing_console = None
    for h in root.handlers:
        if isinstance(h, logging.StreamHandler) and getattr(h, "stream", None) in (sys.stdout, sys.stderr):
            existing_console = h
            break

    if existing_console is None:
        console = logging.StreamHandler(sys.stdout)
        console.setFormatter(formatter)
        console.setLevel(console_level)
        root.addHandler(console)
        # 插入 只为新添加的控制台处理器添加过滤器
        console.addFilter(MyLogFilter())

    else:
        existing_console.setFormatter(formatter)
        existing_console.setLevel(console_level)
        # 插入 只为现有控制台处理器添加过滤器
        existing_console.addFilter(MyLogFilter())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值