Python stdoutへの印刷に 'Print'を使用するスクリプトがあります。最近、Python Loggerでログを作成したいと思います。したがって、ロギングが有効になっている場合、これらのprintステートメントはロガーに送られます。これらのprintステートメントを変更または削除したくありません。
「log.info( "some info msg")」を実行してログを記録できます。私はこのようなことをしたいです:
if logging_enabled:
sys.stdout=log.info
print("test")
ロギングが有効になっている場合、log.info( "test")を実行したかのように "test"を記録する必要があります。ロギングが有効になっていない場合、「test」が画面に出力されるだけです。
これは可能ですか?同様の方法でstdoutをファイルに送信できることを知っています( ログファイルへの出力のリダイレクト を参照)
次の2つのオプションがあります。
ログファイルを開き、sys.stdoutを関数ではなく、それで置き換えます。
log = open("myprog.log", "a")
sys.stdout = log
>>> print("Hello")
>>> # nothing is printed because it goes to the log file instead.
Printをログ関数に置き換えます。
# If you're using python 2.x, uncomment the next line
#from __future__ import print_function
print = log.info
>>> print("Hello!")
>>> # nothing is printed because log.info is called instead of print
もう1つの方法は、write
への呼び出しをロガーのlog
メソッドに変換するオブジェクトでロガーをラップすることです。
フェリーベンダーはまさにこれを行い、 GPLライセンスの下で提供されます in a post on 彼のウェブサイト :
import logging
import sys
class StreamToLogger(object):
"""
Fake file-like stream object that redirects writes to a logger instance.
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
filename="out.log",
filemode='a'
)
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
これにより、すべての出力を選択したロガーに簡単にルーティングできます。必要に応じて、sys.stdout
および/またはsys.stderr
後で復元する必要がある場合に置き換える前に、このスレッドで他の人が述べたように。
もちろん、次のように、標準出力に出力することも、ログファイルに追加することもできます。
# Uncomment the line below for python 2.x
#from __future__ import print_function
import logging
logging.basicConfig(level=logging.INFO, format='%(message)s')
logger = logging.getLogger()
logger.addHandler(logging.FileHandler('test.log', 'a'))
print = logger.info
print('yo!')
より簡単なオプション、
import logging, sys
logging.basicConfig(filename='path/to/logfile', level=logging.DEBUG)
logger = logging.getLogger()
sys.stderr.write = logger.error
sys.stdout.write = logger.info
ロガーを定義したら、これを使用して、印刷の複数のパラメーターがあっても、印刷をロガーにリダイレクトします。
print = lambda *tup : logger.info(str(" ".join([str(x) for x in tup])))
本当に別の方法でそれを行う必要があります。設定に応じて、print
ステートメントなどを使用するようにロギング構成を調整します。 print
の動作を上書きしないでください。将来導入される可能性のある設定の一部(たとえば、ユーザーまたはモジュールを使用する他のユーザー)が実際にstdout
に出力することがあります。問題が発生します。
ログメッセージを適切なストリーム(ファイル、stdout
またはその他のファイルに似たもの)にリダイレクトするハンドラーがあります。 StreamHandler
と呼ばれ、logging
モジュールにバンドルされています。
だから基本的にあなたがやるべきだ、あなたがしたくないと言ったことをやる:私の意見では、print
ステートメントを実際のログに置き換えます。