25

次のようなロギング機能があります。

logging.basicConfig(
    filename = fileName,
    format = "%(levelname) -10s %(asctime)s %(message)s",
    level = logging.DEBUG
)

def printinfo(string):
    if DEBUG:
        logging.info(string)

def printerror(string):
    if DEBUG:
        logging.error(string)
    print string

行番号、スタック情報にログインする必要があります。例えば:

1: def hello():
2:    goodbye()
3:
4: def goodbye():
5:    printinfo()

---> Line 5: goodbye()/hello()

Pythonでこれを行うにはどうすればよいですか?

解決した

def printinfo(string):
    if DEBUG:
        frame = inspect.currentframe()
        stack_trace = traceback.format_stack(frame)
        logging.debug(stack_trace[:-1])
    if LOG:
        logging.info(string)

まさに私が必要としているこの情報を教えてくれます。

DEBUG      2011-02-23 10:09:13,500 [
  '  File "/abc.py", line 553, in <module>\n    runUnitTest(COVERAGE, PROFILE)\n', 
  '  File "/abc.py", line 411, in runUnitTest\n    printinfo(string)\n']
4

8 に答える 8

20

現在の関数名、モジュール、および行番号は、フォーマット文字列を変更してそれらを含めるだけで実行できます。

logging.basicConfig(
    filename = fileName,
    format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s %(funcName)s %(message)s",
    level = logging.DEBUG
)

ほとんどの人は、例外をログに記録するときにのみスタックを必要としますlogging.exception()。それ以外のときにスタック情報が本当に必要な場合は、traceback モジュールを使用して、必要な追加情報を抽出する必要があります。

于 2011-02-23T16:01:06.380 に答える
19
import inspect
import traceback

def method():
   frame = inspect.currentframe()
   stack_trace = traceback.format_stack(frame)
   print ''.join(stack_trace)

スタック トレースに method/printinfo を含めないようにするには、stack_trace[:-1] を使用します。

于 2011-02-23T15:47:33.027 に答える
12

stack_info=TruePython 3.2 の時点で、これはフラグをlogging callsに渡すように簡略化できます。ただし、以前のバージョンでは上記の回答のいずれかを使用する必要があります。

于 2011-02-23T22:40:08.927 に答える
4

遅い答えですが、まあ。

別の解決策は、こちらのドキュメントで指定されているように、フィルターを使用して独自のフォーマッターを作成できることです。ヘルパー関数を使用する必要がなくなった (スタック トレースが必要な場所にヘルパー関数を配置する必要がない) ため、これは非常に優れた機能です。代わりに、カスタム フォーマットはそれをログ自体に直接実装します。

import logging
class ContextFilter(logging.Filter):
    def __init__(self, trim_amount)
        self.trim_amount = trim_amount
    def filter(self, record):
        import traceback
        record.stack = ''.join(
            str(row) for row in traceback.format_stack()[:-self.trim_amount]
        )
        return True

# Now you can create the logger and apply the filter.
logger = logging.getLogger(__name__)
logger.addFilter(ContextFilter(5))

# And then you can directly implement a stack trace in the formatter.    
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s \n %(stack)s')

注: 上記のコードでは、最後の 5 つのスタック フレームをトリミングしています。これは便宜上のものであり、Python ロギング パッケージ自体のスタック フレームを表示しないようにするためです (ロギング パッケージの異なるバージョンに合わせて調整する必要がある場合もあります)。

于 2014-10-31T19:33:39.623 に答える
3

これが私があなたを助けることができることを願っている例です:

import inspect
import logging

logging.basicConfig(
    format = "%(levelname) -10s %(asctime)s %(message)s",
    level = logging.DEBUG
)

def test():

    caller_list = []
    frame = inspect.currentframe()
    this_frame = frame  # Save current frame.

    while frame.f_back:
        caller_list.append('{0}()'.format(frame.f_code.co_name))
        frame = frame.f_back

    caller_line = this_frame.f_back.f_lineno
    callers =  '/'.join(reversed(caller_list))

    logging.info('Line {0} : {1}'.format(caller_line, callers))

def foo():
    test()

def bar():
    foo()

bar()

結果:

INFO       2011-02-23 17:03:26,426 Line 28 : bar()/foo()/test()
于 2011-02-23T16:06:33.290 に答える
3

tracebackモジュールを使用します。

logging.error(traceback.format_exc())
于 2011-02-23T15:46:44.773 に答える
0

traceback モジュールを見てください

>>> import traceback
>>> def test():
>>>     print "/".join( str(x[2]) for x in traceback.extract_stack() )
>>> def main():
>>>     test()
>>> main()
<module>/launch_new_instance/mainloop/mainloop/interact/push/runsource/runcode/<module>/main/test
于 2011-02-23T15:50:24.367 に答える