Pythonでソースファイル名と行番号をログに記録する方法


123

ロギングメソッドが呼び出されたときに、ファイルとそれが呼び出された行番号またはおそらくそれを呼び出したメソッドもログに記録するように、Python標準のログシステムを装飾/拡張することは可能ですか?

回答:


227

確かに、ロギングドキュメントのフォーマッタを確認してください。具体的には、linenoおよびpathname変数。

%(pathname)s ロギング呼び出しが発行されたソースファイル完全パス名(利用可能な場合)。

%(filename)s パス名ファイル名部分。

%(module)s モジュール(ファイル名の名前部分)。

%(funcName)s ロギング呼び出しを含む関数名前。

%(lineno)d ロギング呼び出しが発行されたソース行番号(利用可能な場合)。

次のようになります。

formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')

1
そして、はい、変数の大文字/小文字の混乱を考慮する必要があります。
Tom Pohl、

1
それ以外の場合、「非常に不十分に実装されたキャメルケース」と呼ばれます。
ジョンスペンサー、

80

上にセブの非常に便利な答え、ここでは合理的なフォーマットでロガーの使用法を示し便利なコードスニペットは、次のとおりです。

#!/usr/bin/env python
import logging

logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG)

logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")
logger.critical("This is critical")
logger.error("An error occurred")

この出力を生成します:

2017-06-06:17:07:02,158 DEBUG    [log.py:11] This is a debug log
2017-06-06:17:07:02,158 INFO     [log.py:12] This is an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13] This is critical
2017-06-06:17:07:02,158 ERROR    [log.py:14] An error occurred

5
詳細については、これを使用してください:formatter = logging.Formatter( '%(asctime)s、%(levelname)-8s [%(filename)s:%(module)s:%(funcName)s:%(lineno)d]) %(message)s ')
Girish Gupta

ログメッセージが出力されるかどうかに関係なく、コードの上部の1か所だけを変更する方法はありますか?プログラムが正確に何を行うかを確認するために、多くの印刷物を備えた2つのモードが必要です。1つ目は、出力が表示されない、十分に安定している場合です。
マリー。P.

3
@ Marie.P。コメントで別の質問をしないでください。答えは、ロギングレベルです。
bugmenot123

4

デバッグログを標準出力に送信する方法で上記を構築するには:

import logging
import sys

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

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
formatter = logging.Formatter(FORMAT)
ch.setFormatter(formatter)
root.addHandler(ch)

logging.debug("I am sent to standard out.")

上記をと呼ばれるファイルに入れるとdebug_logging_example.py、出力が生成されます。

[debug_logging_example.py:14 -             <module>() ] I am sent to standard out.

次に、ログアウトをオフにしたい場合はコメントアウトしroot.setLevel(logging.DEBUG)ます。

単一のファイル(クラスの割り当てなど)の場合、これはprint()ステートメントを使用するよりもはるかに優れた方法です。送信する前に、単一の場所でデバッグ出力をオフにできる場所。


1

PyCharmまたはEclipse pydevを使用している開発者の場合、次のようにすると、コンソールログ出力のログステートメントのソースへのリンクが生成されます。

import logging, sys, os
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(message)s | \'%(name)s:%(lineno)s\'')
log = logging.getLogger(os.path.basename(__file__))


log.debug("hello logging linked to source")

より長い議論と歴史については、EclipseコンソールのPydevソースファイルのハイパーリンクを参照してください。


0
# your imports above ...


logging.basicConfig(
    format='%(asctime)s,%(msecs)d %(levelname)-8s [%(pathname)s:%(lineno)d in 
    function %(funcName)s] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger(__name__)

# your classes and methods below ...
# An naive Sample of usage:
try:
    logger.info('Sample of info log')
    # your code here
except Exception as e:
    logger.error(e)

他の回答とは異なり、これにより、エラーが発生した可能性のあるファイルの完全パスと関数名がログに記録されます。これは、複数のモジュールと同じ名前の複数のファイルがこれらのモジュールに配布されているプロジェクトがある場合に役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.