2017-11-06 15 views
0

私のpython3プログラムでloggingモジュールを使用して、ログメッセージをログファイルに送信すると成功しました。例えば、/var/log/myprogram.logです。場合によっては、これらのメッセージのサブセットもstdoutに移動し、ログファイルに移動したときと同じ方法で自分のlogging.Loggerインスタンスでフォーマットします。python3/logging:オプションで複数のストリームに書き込む

私は私がメッセージのみ/var/log/myprogram.logに行くかどうかを選択できるようにloginstance.log(level, msg)周りのラッパーのいくつかの並べ替えを入れたいのですが、私のロガーインスタンスがloginstance呼ばれると仮定すると、または次のようにそれは、stdoutに存在しても行くかどうか:

# Assume `loginstance` has already been instantiated 
# as a global, and that it knows to send logging info 
# to `/var/log/myprogram.log` by default. 
def mylogger(level, msg, with_stdout=False): 
    if with_stdout: 
     # Somehow send `msg` through `loginstance` so 
     # that it goes BOTH to `/var/log/myprogram.log` 
     # AND to `stdout`, with identical formatting. 
    else: 
     # Send only to `/var/log/myprogram.log` by default. 
     loginstance.log(level, msg) 

私はフォーマットやその他のロギング動作を変更したい場合は、私が唯一の場所でこれを行う必要があるように私は、1でこれを管理するための単一logging.Loggerインスタンスをしたいと思います。

サブクラス化することには、logging.Loggerおよび/またはlogging.Formatterが含まれていると推測していますが、これを行う方法はわかりません。

ご協力いただきありがとうございます。

答えて

0

私はそれを行う方法を理解しました。それは単にその、その後...私のロガーをインスタンス化する場合、私はこれを行う...私はFileHandlerサブクラスを使用してlog()に追加の引数を渡すことmylogger機能を

logger = logging.getLogger('myprogram') 
logger.addHandler(MyFileHandler('/var/log/myprogram.log')) 

class MyFileHandler(logging.FileHandler): 
    def emit(self, record): 
     super().emit(record) 
     also_use_stdout = getattr(record, 'also_use_stdout', False) 
     if also_use_stdout: 
      savestream = self.stream 
      self.stream = sys.stdout 
      try: 
       super().emit(record) 
      finally: 
       self.stream = savestream 

が必要です私はこのようになります。上記:何かがlog関数のwiに渡されたので、これは動作します

def mylogger(level, msg, with_stdout=False): 
    loginstance.log(level, msg, extra={'also_use_stdout': with_stdout}) 

薄い場合、オプションのextraディクショナリは、最終的にemitに渡されるrecordオブジェクトの属性になります。

関連する問題