1. ホーム
  2. python

[解決済み] Pythonのログ(関数名、ファイル名、行番号)を1つのファイルを使って記録する。

2022-05-17 05:20:38

質問

私は、アプリケーションがどのように動作するかを学ぼうとしています。そして、このために、私は関数の名前とログ出力にメッセージを送る行番号(コード内)を記録することを目的として、各関数の本体の最初の行としてデバッグコマンドを挿入しています。最後に、このアプリケーションは多くのファイルで構成されているので、アプリケーションの制御フローをよりよく理解するために、1つのログファイルを作成したいと思います。

以下は私が知っていることです。

  1. 関数名を得るために、私は function_name.__name__ を使うこともできますが、function_name は使いたくありません (そうすれば、一般的な Log.info("Message") をすべての関数本体にコピー&ペーストできるようにするため)。私は、これはCで以下を使用して行うことができることを知っています __func__ マクロを使用してCで行うことができることを知っていますが、私はパイソンについてはよくわかりません。

  2. ファイル名と行番号を取得するために、私は私のアプリケーションがPythonを使用していることを見ました(と私は信じています)。 locals() 関数を使用していますが、私が完全に認識していない構文で、例えば。 options = "LOG.debug('%(flag)s : %(flag_get)s' % locals()) のようなものを使って試してみました。 LOG.info("My message %s" % locals()) のようなものが生成されます。 {'self': <__main__.Class_name object at 0x22f8cd0>} . この件に関して何かご意見があればお願いします。

  3. 私はロギングを使用し、ファイルにログを記録するためにそれにハンドラを追加する方法を知っていますが、私はプロジェクト内の関数呼び出しの正しい順序ですべてのログメッセージを記録するために単一のファイルを使用できるかどうかわかりません。

私はどんな助けでも非常に感謝します。

ありがとうございます!

どのように解決するのですか?

ここにいくつかの関連する質問があります。

最も簡単なものから始めます。(3). 使用方法 logging を使うと、すべての呼び出しをひとつのログファイルや他の出力先に集約することができます:それらはプロセス内で発生した順番になります。

次は (2). locals() は現在のスコープの dict を提供します。したがって、他に引数のないメソッドでは self をスコープに入れ、そこに現在のインスタンスへの参照が含まれています。使用されているトリックで困っているのは、dict を使用して文字列のフォーマットを % 演算子の右辺に dict を使っていることです。 "%(foo)s" % bar の値は何にでも置き換えられます。 bar["foo"] の値で置き換えられます。

最後に、いくつかのイントロスペクションのトリックを使うことができます。 pdb で使用されるような、より多くの情報を記録することができるいくつかのイントロスペクションのトリックを使用することができます。

def autolog(message):
    "Automatically log the current function details."
    import inspect, logging
    # Get the previous frame in the stack, otherwise it would
    # be this function!!!
    func = inspect.currentframe().f_back.f_code
    # Dump the message + the name of this function to the log.
    logging.debug("%s: %s in %s:%i" % (
        message, 
        func.co_name, 
        func.co_filename, 
        func.co_firstlineno
    ))

これは渡されたメッセージと(オリジナルの)関数名、その定義が現れるファイル名、そのファイル内の行を記録します。次の例を見てください。 inspect - 生きたオブジェクトを検査する をご覧ください。

先ほどのコメントにもあったように、ドロップインで pdb という行を挿入することで、いつでも対話式デバッグプロンプトに入ることができます。 import pdb; pdb.set_trace() を挿入し、プログラムを再実行する。これにより、コードを段階的に実行し、選択したデータを検査することができます。