2013-07-09 7 views
46

私の現在のフォーマット文字列は次のとおりです。Pythonのログフォーマット文字列にカスタムフィールドを追加するにはどうすればいいですか?

formatter = logging.Formatter('%(asctime)s : %(message)s') 

と私は、このフォーマッタが含まれている各スクリプトに別の値を持つことになりますAPP_NAMEと呼ばれる新しいフィールドを追加したいとどの。

import logging 
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') 
syslog.setFormatter(formatter) 
logger.addHandler(syslog) 

しかし、私は、フォーマット文字列に補間するロガーにそのapp_name値を渡しするかどうかはわかりません。私は明らかにそれをログメッセージに表示することができますが、毎回それを渡すが、これは乱雑です。私が試した

logging.info('Log message', app_name='myapp') 
logging.info('Log message', {'app_name', 'myapp'}) 
logging.info('Log message', 'myapp') 

が、どれも仕事。

+0

本当にこれをすべての 'log'呼び出しに渡しますか?もしそうなら、「この機能はLogRecordに独自の値を注入するのに使うことができる」と言うところの[the docs](http://docs.python.org/3.3/library/logging.html#logrecord-objects)を見てください。 "しかし、これは' logger = logging.getLogger( 'myapp') 'を使用し、' logger.info'呼び出しに焼き込むことの主要なケースのようです。 – abarnert

答えて

65

あなたはあなたがすべてのログ呼び出しで、余分な情報を渡す必要はありませんLoggingAdapterを使用することができます。

import logging 
extra = {'app_name':'Super App'} 

logger = logging.getLogger(__name__) 
syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') 
syslog.setFormatter(formatter) 
logger.setLevel(logging.INFO) 
logger.addHandler(syslog) 

logger = logging.LoggerAdapter(logger, extra) 
logger.info('The sky is so blue') 

ログ(ようなもの)

2013-07-09 17:39:33,596 Super App : The sky is so blue 

Filtersを使用してコンテキスト情報を追加することもできます。

import logging 

class AppFilter(logging.Filter): 
    def filter(self, record): 
     record.app_name = 'Super App' 
     return True 

logger = logging.getLogger(__name__) 
logger.addFilter(AppFilter()) 
syslog = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') 
syslog.setFormatter(formatter) 
logger.setLevel(logging.INFO) 
logger.addHandler(syslog) 

logger.info('The sky is so blue') 

は、同様のログレコードを生成する。

+1

'config.ini'ファイルでこれをどのように指定できますか?私は現在のホスト名 'socket.gethostname()'を追加したいと思います。 –

16

このようにするには、dictをパラメータとして渡す必要があります。

logging.info('Log message', extra={'app_name': 'myapp'}) 

証明:また

>>> import logging 
>>> logging.basicConfig(format="%(foo)s - %(message)s") 
>>> logging.warning('test', extra={'foo': 'bar'}) 
bar - test 

あなたは辞書を通過することなく、メッセージをログに記録しようとすると、ノートのように、それは失敗します。

>>> logging.warning('test') 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/logging/__init__.py", line 846, in emit 
    msg = self.format(record) 
    File "/usr/lib/python2.7/logging/__init__.py", line 723, in format 
    return fmt.format(record) 
    File "/usr/lib/python2.7/logging/__init__.py", line 467, in format 
    s = self._fmt % record.__dict__ 
KeyError: 'foo' 
Logged from file <stdin>, line 1 
+1

保存日: – Anish

+0

これは 'logging.info()'でも使えますか?私は最後に試したときに失敗しました。 :/ –

+0

私は@ mr2ert答えが好きです。 class CustomFormatter(logging.Formatter): def format(self、record): hasattr(record、 'foo')の場合は、追加のフィールドにデフォルト値を与えることができます。 : record.foo = 'default_foo' 戻りスーパー(CustomFormatter、self.format(レコード) H = loggin.StreamHandler() h.setFormatter(CustomFormatter( '%(FOO)S%(メッセージ)S') ロガー= logging.getLogger( 'バー') logger.addHandler(H) logger.error(、余分= { 'FOO': 'FOO'} 'ちょっと!') logger.error(「ちょっと! ') – loutre

関連する問題