python日志

import os
import logging.config
from logging.handlers import TimedRotatingFileHandler

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'detailed': {
            'class': 'logging.Formatter',
            'format': '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'INFO',
            'formatter': 'detailed',
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO',
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
# 配置日志
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# 创建控制台处理程序
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 创建滚动文件处理程序,每达到10M就滚动
# file_handler = RotatingFileHandler('my_log.log', maxBytes=10*1024*1024, backupCount=5)

# 确保日志目录存在
log_directory = '/log/'
if not os.path.exists(log_directory):
    os.makedirs(log_directory)

# 创建按日期滚动的文件处理程序,每天生成新文件
date_file_handler = TimedRotatingFileHandler(os.path.join(log_directory, 'vncproject.log'), when='midnight', interval=1,
                                             backupCount=5)

# 配置日志格式
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s')
console_handler.setFormatter(formatter)
# file_handler.setFormatter(formatter)
date_file_handler.setFormatter(formatter)

# 将处理程序添加到日志记录器
logger.addHandler(console_handler)
# logger.addHandler(file_handler)
logger.addHandler(date_file_handler)

# 记录日志
logger.info('This is an info message')
 控制台上输出了两遍我项目的日志

在你的日志配置中,你添加了一个控制台处理程序 (console_handler) 和一个按日期滚动的文件处理程序 (date_file_handler)。因此,每个日志记录器 (logger) 都会通过这两个处理程序进行处理,导致在控制台上和日志文件中都输出了相同的日志。

如果你希望控制台只输出一份日志,你可以在日志记录器 (logger) 上添加一个处理程序,并设置不同的日志级别。例如,你可以设置控制台处理程序的级别为 DEBUG,而文件处理程序的级别为 INFO。这样,控制台处理程序将输出所有级别的日志,而文件处理程序只会输出 INFO 及以上级别的日志。

修改你的代码如下:

import os
import logging.config
from logging.handlers import TimedRotatingFileHandler

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'detailed': {
            'class': 'logging.Formatter',
            'format': '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',  # 设置控制台处理程序的级别为 DEBUG
            'formatter': 'detailed',
        },
        'file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join('/log/', 'vncproject.log'),
            'when': 'midnight',
            'interval': 1,
            'backupCount': 5,
            'level': 'INFO',  # 设置文件处理程序的级别为 INFO
            'formatter': 'detailed',
        },
    },
    'loggers': {
        '': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)

logger.info('This is an info message')

这样配置后,控制台上只会输出 DEBUG 及以上级别的日志,而文件中会输出 INFO 及以上级别的日志。

我想文件输出的只在文件,控制台只输出控制台自己的

你可以通过设置不同的日志记录器来实现这一点。以下是相应的修改:

import os
import logging.config
from logging.handlers import TimedRotatingFileHandler

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'detailed': {
            'class': 'logging.Formatter',
            'format': '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'detailed',
        },
        'file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join('/log/', 'vncproject.log'),
            'when': 'midnight',
            'interval': 1,
            'backupCount': 5,
            'level': 'INFO',
            'formatter': 'detailed',
        },
    },
    'loggers': {
        'console_logger': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,  # 防止日志传递给 root logger
        },
        'file_logger': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': False,  # 防止日志传递给 root logger
        },
    },
    'root': {
        'level': 'DEBUG',
        'handlers': ['console', 'file'],
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
console_logger = logging.getLogger('console_logger')
file_logger = logging.getLogger('file_logger')

console_logger.info('This is an info message for console')
file_logger.info('This is an info message for file')

这样配置后,console_logger 只会将日志输出到控制台,而 file_logger 只会将日志输出到文件。

我还想过滤掉所有第三方工具库的除了error级别的任何日志

可以通过在相应的 logger 上设置级别来实现。以下是修改后的配置:

import os
import logging.config
from logging.handlers import TimedRotatingFileHandler

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'detailed': {
            'class': 'logging.Formatter',
            'format': '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'detailed',
        },
        'file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join('/log/', 'vncproject.log'),
            'when': 'midnight',
            'interval': 1,
            'backupCount': 5,
            'level': 'INFO',
            'formatter': 'detailed',
        },
    },
    'loggers': {
        'console_logger': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,  # 防止日志传递给 root logger
        },
        'file_logger': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': False,  # 防止日志传递给 root logger
        },
        'twisted': {  # twisted 的 logger
            'handlers': ['file'],
            'level': 'ERROR',  # 设置级别为 ERROR
            'propagate': False,
        },
    },
    'root': {
        'level': 'DEBUG',
        'handlers': ['console', 'file'],
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
console_logger = logging.getLogger('console_logger')
file_logger = logging.getLogger('file_logger')

console_logger.info('This is an info message for console')
file_logger.info('This is an info message for file')

# twisted 会被过滤掉,不会输出到 file_logger
logger_twisted = logging.getLogger('twisted')
logger_twisted.info('This is an info message for twisted')  # 不会输出
logger_twisted.error('This is an error message for twisted')  # 会输出

在这个例子中,我为 twisted 设置了级别为 ERROR,这样 INFO 级别的日志就会被过滤掉。其他的 logger(比如 console_loggerfile_logger)仍然按照原有的级别进行输出。

是任何第三方工具库,除了error级别外,在控台和文本都不要输出

如果你想过滤掉所有第三方工具库的非 ERROR 级别的日志,可以使用一个自定义的过滤器。以下是一种可能的实现:

import os
import logging.config
from logging.handlers import TimedRotatingFileHandler

class NoThirdPartyInfoFilter(logging.Filter):
    def filter(self, record):
        # 如果是第三方模块的日志且级别为 INFO,则过滤掉
        return not (record.name.startswith('your_project') or record.levelno == logging.INFO)

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'detailed': {
            'class': 'logging.Formatter',
            'format': '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'detailed',
            'filters': ['no_third_party_info'],
        },
        'file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join('/log/', 'vncproject.log'),
            'when': 'midnight',
            'interval': 1,
            'backupCount': 5,
            'level': 'INFO',
            'formatter': 'detailed',
            'filters': ['no_third_party_info'],
        },
    },
    'loggers': {
        '': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
    },
    'filters': {
        'no_third_party_info': {
            '()': NoThirdPartyInfoFilter,
        },
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)

logger.info('This is an info message for both console and file')

在这个例子中,NoThirdPartyInfoFilter 类继承自 logging.Filter,它的 filter 方法控制是否允许特定的记录通过。在这里,我在过滤器中判断了日志记录的名称,如果是你的项目的日志或者是 ERROR 级别的日志,就允许通过,否则过滤掉。过滤器的名称 'no_third_party_info'handlers 部分和 filters 部分都要配置。

PIL.PngImagePlugin 还是包含了这部分,这些也不是我要的

如果你想要过滤掉特定模块的日志,可以使用 logging.Logger 对象的 propagate 属性。这个属性控制日志消息是否传播给父级 logger。通过设置 propagateFalse,你可以阻止消息传播到父级 logger。

以下是如何修改配置来过滤掉 PIL.PngImagePlugin 模块的日志的例子:

import os
import logging.config
from logging.handlers import TimedRotatingFileHandler

class NoThirdPartyInfoFilter(logging.Filter):
    def filter(self, record):
        # 如果是第三方模块的日志且级别为 INFO,则过滤掉
        return not (record.name.startswith('your_project') or record.levelno == logging.INFO)

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'detailed': {
            'class': 'logging.Formatter',
            'format': '%(asctime)s [%(levelname)s] %(name)s.%(funcName)s:%(lineno)d - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'detailed',
            'filters': ['no_third_party_info'],
        },
        'file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join('/log/', 'vncproject.log'),
            'when': 'midnight',
            'interval': 1,
            'backupCount': 5,
            'level': 'INFO',
            'formatter': 'detailed',
            'filters': ['no_third_party_info'],
        },
    },
    'loggers': {
        '': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
        'PIL.PngImagePlugin': {
            'handlers': ['file'],
            'level': 'ERROR',
            'propagate': False,  # 阻止消息传播到根 logger
        },
    },
    'filters': {
        'no_third_party_info': {
            '()': NoThirdPartyInfoFilter,
        },
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)

logger.info('This is an info message for both console and file')

在这个例子中,我在 loggers 部分添加了一个针对 PIL.PngImagePlugin 模块的配置,将 propagate 设置为 False。这样,该模块的日志就不会传播到根 logger。你可以根据需要添加其他模块的配置。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值