回答:
logger.exception
エラーメッセージとともにスタックトレースを出力します。
例えば:
import logging
try:
1/0
except ZeroDivisionError as e:
logging.exception("message")
出力:
ERROR:root:message
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
@Paulo Checkは、「Python 3ではlogging.exception
、except
パーツのすぐ内側でメソッドを呼び出す必要があることに注意してください。このメソッドを任意の場所で呼び出すと、奇妙な例外が発生する可能性があります。ドキュメントに関する警告が表示されます。」
except Exception:
はまったく使用e
していないので、単に書くことができます;)
e
対話的にコードをデバッグしようとする場合は、検査することをお勧めします。:)これは私がいつもそれを含める理由です。
raise
、except
スコープの最後に追加することは理にかなっています。それ以外の場合は、すべてが問題なく実行されます。
約いいところlogging.exception
というSiggyFの答えは:あなたは、任意のメッセージを渡すことができるということです、そしてロギングがまだすべての例外の詳細との完全なトレースバックが表示されます表示されません。
import logging
try:
1/0
except ZeroDivisionError:
logging.exception("Deliberate divide by zero traceback")
エラーをsys.stderr
に出力するだけのデフォルト(最近のバージョン)のロギング動作では、次のようになります。
>>> import logging
>>> try:
... 1/0
... except ZeroDivisionError:
... logging.exception("Deliberate divide by zero traceback")
...
ERROR:root:Deliberate divide by zero traceback
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
''
メッセージを入力したくない場合は渡すことをお勧めします...ただし、関数は少なくとも1つの引数なしでは呼び出すことができないため、何かを指定する必要があります。
exc_info
エラーレベルを選択できるようにするために、オプションを使用する方が良い場合があります(を使用する場合はexception
、常にそのerror
レベルになります)。
try:
# do something here
except Exception as e:
logging.critical(e, exc_info=True) # log exception info at CRITICAL log level
logging.fatal
、ロギングライブラリ内の方法は?しか見えないcritical
。
critical
と同じように、warn
にありますwarning
。
アプリケーションが他の方法でログを記録している場合(
logging
モジュールを使用しない場合)はどうなりますか?
ここで、traceback
ここで使用できます。
import traceback
def log_traceback(ex, ex_traceback=None):
if ex_traceback is None:
ex_traceback = ex.__traceback__
tb_lines = [ line.rstrip('\n') for line in
traceback.format_exception(ex.__class__, ex, ex_traceback)]
exception_logger.log(tb_lines)
Python 2で使用します。
try:
# your function call is here
except Exception as ex:
_, _, ex_traceback = sys.exc_info()
log_traceback(ex, ex_traceback)
Python 3で使用します。
try:
x = get_number()
except Exception as ex:
log_traceback(ex)
ex_traceback
からである ex.__traceback__
Pythonの3の下で、しかしex_traceback
からであるsys.exc_info()
Pythonの2の下で
プレーンログを使用する場合、すべてのログレコードがこのルールに対応している必要がありますone record = one line
。このルールに従ってgrep
、ログファイルを処理するために他のツールを使用できます。
ただし、トレースバック情報は複数行です。だから私の答えは、このスレッドで上記のzangwによって提案されたソリューションの拡張バージョンです。問題は、トレースバック行が\n
内部にある可能性があることです。そのため、この行末を取り除くために追加の作業を行う必要があります。
import logging
logger = logging.getLogger('your_logger_here')
def log_app_error(e: BaseException, level=logging.ERROR) -> None:
e_traceback = traceback.format_exception(e.__class__, e, e.__traceback__)
traceback_lines = []
for line in [line.rstrip('\n') for line in e_traceback]:
traceback_lines.extend(line.splitlines())
logger.log(level, traceback_lines.__str__())
その後(ログを分析するとき)、必要なトレースバック行をログファイルからコピーして貼り付け、これを実行できます。
ex_traceback = ['line 1', 'line 2', ...]
for line in ex_traceback:
print(line)
利益!
この答えは、上記の優れたものから構築されます。
ほとんどのアプリケーションでは、logging.exception(e)を直接呼び出すことはありません。ほとんどの場合、次のようにアプリケーションまたはモジュールに固有のカスタムロガーを定義しています。
# Set the name of the app or module
my_logger = logging.getLogger('NEM Sequencer')
# Set the log level
my_logger.setLevel(logging.INFO)
# Let's say we want to be fancy and log to a graylog2 log server
graylog_handler = graypy.GELFHandler('some_server_ip', 12201)
graylog_handler.setLevel(logging.INFO)
my_logger.addHandler(graylog_handler)
この場合、ロガーを使用して、次のように例外(e)を呼び出します。
try:
1/0
except ZeroDivisionError, e:
my_logger.exception(e)
例外なくスタックトレースを記録できます。
https://docs.python.org/3/library/logging.html#logging.Logger.debug
2番目のオプションのキーワード引数はstack_infoで、デフォルトはFalseです。trueの場合、実際のロギング呼び出しを含むスタック情報がロギングメッセージに追加されます。これは、exc_infoを指定して表示されるものと同じスタック情報ではないことに注意してください。前者はスタックの一番下から現在のスレッドのロギング呼び出しまでのスタックフレームですが、後者は巻き戻されたスタックフレームに関する情報です。例外ハンドラーを検索しながら、例外を追跡します。
例:
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> logging.getLogger().info('This prints the stack', stack_info=True)
INFO:root:This prints the stack
Stack (most recent call last):
File "<stdin>", line 1, in <module>
>>>
少しのデコレータ処理(Maybeモナドとリフティングに非常に大まかに影響)。安全にPython 3.6タイプの注釈を削除し、古いメッセージフォーマットスタイルを使用できます。
fallible.py
from functools import wraps
from typing import Callable, TypeVar, Optional
import logging
A = TypeVar('A')
def fallible(*exceptions, logger=None) \
-> Callable[[Callable[..., A]], Callable[..., Optional[A]]]:
"""
:param exceptions: a list of exceptions to catch
:param logger: pass a custom logger; None means the default logger,
False disables logging altogether.
"""
def fwrap(f: Callable[..., A]) -> Callable[..., Optional[A]]:
@wraps(f)
def wrapped(*args, **kwargs):
try:
return f(*args, **kwargs)
except exceptions:
message = f'called {f} with *args={args} and **kwargs={kwargs}'
if logger:
logger.exception(message)
if logger is None:
logging.exception(message)
return None
return wrapped
return fwrap
デモ:
In [1] from fallible import fallible
In [2]: @fallible(ArithmeticError)
...: def div(a, b):
...: return a / b
...:
...:
In [3]: div(1, 2)
Out[3]: 0.5
In [4]: res = div(1, 0)
ERROR:root:called <function div at 0x10d3c6ae8> with *args=(1, 0) and **kwargs={}
Traceback (most recent call last):
File "/Users/user/fallible.py", line 17, in wrapped
return f(*args, **kwargs)
File "<ipython-input-17-e056bd886b5c>", line 3, in div
return a / b
In [5]: repr(res)
'None'
また、このソリューションを変更None
して、except
パーツからよりも意味のある何かを返すようにすることもできます(または、この戻り値をfallible
の引数で指定することにより、ソリューションを汎用的にすることもできます)。
追加の依存関係に対処できる場合は、twisted.logを使用します。エラーを明示的にログに記録する必要はありません。また、トレースバック全体と時間をファイルまたはストリームに返します。
twisted
良い提案ですが、この回答はあまり貢献しません。使用方法、標準ライブラリのモジュールよりtwisted.log
も優れている点、「エラーを明示的にログに記録する必要がない」logging
の意味については説明されていません。
それを行うためのクリーンな方法はformat_exc()
、関連する部分を取得するために出力を使用して解析することです:
from traceback import format_exc
try:
1/0
except Exception:
print 'the relevant part is: '+format_exc().split('\n')[-2]
よろしく
.split('\n')[-2]
行いで捨てるの結果から、行番号とトレースバックをformat_exc()
-あなたは通常欲しい有用な情報!しかも、それはさえの良い仕事しませんことを。例外メッセージに改行が含まれている場合、このアプローチでは例外メッセージの最終行のみが出力されます。つまり、例外クラスとほとんどの例外メッセージが失われ、さらにトレースバックが失われます。-1。
exception
この方法は、単純に呼び出しますerror(message, exc_info=1)
。exc_info
例外コンテキストからロギングメソッドのいずれかに渡すとすぐに、トレースバックが取得されます。