首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Python中配置日志

如何在Python中配置日志
EN

Stack Overflow用户
提问于 2012-08-13 09:36:52
回答 2查看 40.9K关注 0票数 36

我是Python的新手,刚刚开始一个项目。我习惯于在Java语言中使用log4j,我想用Python语言记录所有的模块和类,就像我在Java语言中做的那样。

在Java中,我在src文件夹中有一个名为log4j.properties的日志配置文件,如下所示:

代码语言:javascript
复制
log4j.rootLogger=DEBUG, Console, fileout

log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %5p [%t] (%F:%L) - %m%n

log4j.appender.fileout=org.apache.log4j.RollingFileAppender
log4j.appender.fileout.File=servidor.log
log4j.appender.fileout.layout=org.apache.log4j.PatternLayout
log4j.appender.fileout.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} (%F:%L) %p %t %c - %m%n

它会记录到控制台和一个文件中。

在我的类中,我只需要导入log4j并添加一个静态属性来恢复加载了配置的log4j记录器,然后所有的类都将记录到控制台和文件中。配置文件通过名称自动加载。例如:

代码语言:javascript
复制
import org.apache.log4j.Logger;

public class Main {
    public static Logger logger = Logger.getLogger(Main.class);
    public static void main(String[] args) {
        logger.info("Hello");
    }
}

现在我在Python中设置日志时遇到了问题,我已经阅读了文档,但我找不到在许多模块/类中使用它的方法。我如何才能以一种简单的方式设置Python日志来记录我的模块和类,而不需要在每个模块/类中编写大量代码?有没有可能重现我用Python写的相同代码?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-13 09:57:28

实际上,在Python中,它看起来非常相似。有不同的方法可以做到这一点。我通常会创建一个非常简单的logger类:

代码语言:javascript
复制
import os
import logging 
import settings   # alternativly from whereever import settings  

class Logger(object):

    def __init__(self, name):
        name = name.replace('.log','')
        logger = logging.getLogger('log_namespace.%s' % name)    # log_namespace can be replaced with your namespace 
        logger.setLevel(logging.DEBUG)
        if not logger.handlers:
            file_name = os.path.join(settings.LOGGING_DIR, '%s.log' % name)    # usually I keep the LOGGING_DIR defined in some global settings file
            handler = logging.FileHandler(file_name)
            formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s %(message)s')
            handler.setFormatter(formatter)
            handler.setLevel(logging.DEBUG)
            logger.addHandler(handler)
        self._logger = logger

    def get(self):
        return self._logger

然后,如果我想在类或模块中记录一些东西,我只需导入记录器并创建一个实例。传递类名将为每个类创建一个文件。然后,记录器可以通过debug、info、error等将消息记录到其文件中:

代码语言:javascript
复制
from module_where_logger_is_defined import Logger

class MyCustomClass(object):

    def __init__(self):
        self.logger = Logger(self.__class__.__name__).get()   # accessing the "private" variables for each class

    def do_something():
        ...
        self.logger.info('Hello')

    def raise_error():
        ...
        self.logger.error('some error message')

更新的答案

这些年来,我对Python日志记录的使用方式做了很大的改变。主要基于良好的实践,我在应用程序启动期间首先加载的模块中配置整个应用程序的日志记录一次,然后在每个文件中使用单独的记录器。示例:

代码语言:javascript
复制
# app.py (runs when application starts)

import logging
import os.path

def main():
    logging_config = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
            },
        },
        'handlers': {
            'default_handler': {
                'class': 'logging.FileHandler',
                'level': 'DEBUG',
                'formatter': 'standard',
                'filename': os.path.join('logs', 'application.log'),
                'encoding': 'utf8'
            },
        },
        'loggers': {
            '': {
                'handlers': ['default_handler'],
                'level': 'DEBUG',
                'propagate': False
            }
        }
    }
    logging.config.dictConfig(logging_config)
    # start application ...

if __name__ == '__main__':
    main()
代码语言:javascript
复制
# submodule.py (any application module used later in the application)

import logging

# define top level module logger
logger = logging.getLogger(__name__)

def do_something():
    # application code ...
    logger.info('Something happended')
    # more code ...
    try:
        # something which might break
    except SomeError:
        logger.exception('Something broke')
        # handle exception
    # more code ...

以上是推荐的方法。每个模块都定义了自己的记录器,当您检查日志时,可以根据__name__属性轻松地识别哪个模块记录了哪条消息。这删除了我原始答案中的样板,而是使用Python标准库中的logging.config模块。

票数 47
EN

Stack Overflow用户

发布于 2012-08-13 10:18:54

文档provide a pretty good example of using your logger in multiple modules。基本上,您只需在程序开始时设置一次日志。然后,将日志记录模块导入到您想要进行日志记录的任何位置,并使用它。

myapp.py

代码语言:javascript
复制
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()

mylib.py

代码语言:javascript
复制
import logging

def do_something():
    logging.info('Doing something')

这个示例显示了一个非常简单的记录器设置,但是您可以很容易地使用various ways to configure logging来设置更高级的场景。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11927278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档