36

私はPythonが初めてで、1つのプロジェクトを開始したばかりです。私は Java での使用に慣れてlog4jおり、Java と同じようにすべてのモジュールとクラスを Python でログに記録したいと考えています。

log4j.propertiesJava では、次のような名前の src フォルダーに 1 つのログ構成ファイルがあります。

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で、すべてのクラスがコンソールとファイルにログを記録します。構成ファイルは、名前によって自動的にロードされます。例えば:

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 で書いたのと同じコードを再現することはできますか?

4

3 に答える 3

49

実際、Pythonではほとんど同じように見えます。それを行うにはさまざまな方法があります。私は通常、非常に単純なロガークラスを作成します。

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

次に、クラスまたはモジュールに何かを記録したい場合は、ロガーをインポートしてインスタンスを作成するだけです。クラス名を渡すと、クラスごとに1つのファイルが作成されます。その後、ロガーはデバッグ、情報、エラーなどを介してメッセージをファイルに記録できます。

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ロギングの使用方法をかなり変更しました。ほとんどの場合、グッドプラクティスに基づいて、アプリケーションの起動時に最初にロードされたモジュールにアプリケーション全体のログを一度設定し、次に各ファイルで個別のロガーを使用します。例:


# 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()

# 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__、ログを検査するときに、どのメッセージがどのモジュールに記録されたかを属性に基づいて簡単に識別できます。これにより、元の回答からボイラープレートが削除され、代わりlogging.configにPython標準ライブラリのモジュールが使用されます。

于 2012-08-13T01:57:27.577 に答える
15

ドキュメントは、複数のモジュールでロガーを使用するかなり良い例を提供します。基本的に、ログはプログラムの開始時に 1 回設定します。次に、ロギングが必要な場所にロギング モジュールをインポートして使用します。

myapp.py

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

import logging

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

この例は、非常に単純化されたロガーのセットアップを示していますが、さまざまな方法を使用してロギングを構成し、より高度なシナリオをセットアップすることは非常に簡単です。

于 2012-08-13T02:18:54.400 に答える
3

Python の組み込みのログ モジュールでは、log4j のような機能 (ファイル アペンダー、時間とサイズの両方に基づくファイル ローテーション) を構成するために、数行のコードが必要です。

コード内の機能をワンライナーで実装するには、パッケージを使用できますautopylogger

ここに基本があります。

1.パッケージをインストールする

pip install autopylogger

2.使い方

# import the package
from autopylogger import init_logging

# Initialise the logging module
mylogger = init_logging(log_name="myfirstlogger", log_directory="logsdir")

以上で、ロギング オブジェクトが初期化され、ファイルの書き込みとローテーション機能が有効になりました。

以下のコマンドでログを書き込むことができます。

# Write logs - DEBUG | INFO | WARNING | ERROR
mylogger.debug('This is a INFO log')
mylogger.info('This is a DEBUG log')
mylogger.warning('This is a WARNING log')
mylogger.error('This is a ERROR log')

autopylogger を使用する理由

  • ファイル アペンダー- デフォルトで有効になっています。

  • ログのローテーション- デフォルトで有効になっています。基本的なロギング ライブラリにないtime&の両方に基づいてローテーションを構成することもできます。size

  • 重要なログのメール送信機能- SMTP サーバーの資格情報でライブラリを初期化することにより、重要なログのメールを送信します。本番環境で便利です。

ドキュメントについては、Github 公式ページPyPI 公式ページを参照してください。

于 2020-07-16T19:12:10.820 に答える