2011-07-26 22 views
1

ログモジュールにいくつかのログにコンテキスト情報を追加しようとしています。ログの各行の隣にprojectidを表示できるようにする必要があります。毎日20,000を超えるプロジェクトが作成されているので、このデータは本当に役立ちます。これを行うため、私はlogging.Filterモジュールの派生物を作成しました。djangoのlogging.filtersに動的要素を追加する1.3

import logging 

class MTFilter(logging.Filter): 

def __init__(self, projectid=0): 
    self.projectid = projectid 

def filter(self, record): 
    record.projectid = self.projectid 
    return True 

ここに私のLOGGING変数は、settings.py

LOGGING = { 
    'version': 1, 
    'disable_existing_loggers': True, 
    'filters': { 
     'project': { 
      '()': 'app.proj.logging.mtfilter.MTFilter', 
     }, 
    }, 
    'formatters': { 
     'projectformat': { 
      'format': '%(asctime)s %(levelname)8s PID[%(projectid)d] %(name)s[%(funcName)s]: %(message)s', 
     }, 
    }, 
    'handlers': { 
     'null': { 
      'level': 'DEBUG', 
      'class': 'django.utils.log.NullHandler', 
     }, 
     'project-log': { 
      'level': 'DEBUG', 
      'class': 'logging.handlers.RotatingFileHandler', 
      'formatter': 'projectformat', 
      'filename': os.path.join(SITE_ROOT, '../logs/django.log'), 
      'filters': ['project'], 
      'maxBytes': 1024*1024*16, #16Mb 
     }, 
    }, 
    'loggers': { 
     '': { 
      'handlers':  ['null'], 
      'level':  'DEBUG', 
      'propagate': True, 
     }, 
     'proj': { 
      'handlers': ['project-log'], 
      'level':  'DEBUG', 
     }, 
    } 
} 

でだと私の見解で、私はLogging.filtersに 'PROJECTID' の任意の値を入れないことで

logger = logging.getLogger('proj') 
logger.info('Log Message') 

次を使用します.project私はデフォルトのフォーマット値を取得します。これは '0'です。ログ結果は以下のようになります。私が何をしたいのですがどのような

2011-07-26 02:41:44,488  INFO PID[0] proj[view]: Log Message 

は例えば、動的に何とか「PROJECTID」の値をつかむです。ロガーオブジェクトを作成したり、いくつかのミドルウェアを使用していましたが、どうやってそれを行うのか分かりません。誰にでも提案はありますか?

+0

です。自身のログは、ログにコンテキスト情報を追加するために多くの方法を提供しています、例えば、 'LoggingAdapter'かしかし、あなたがソースにアクセスできない(例えば、サードパーティ製のライブラリで)ロギングコールにコンテキスト情報を追加したい場合は、提案したアプローチがあります。 –

答えて

2

私がしたいのは、何とか 'projectid'の値を何とか動的に取得することです。 ロガーオブジェクトを作成したり、いくつかのミドルウェアを使用していますが、私はちょうど の方法を知りません。

ロガーを作成するときは、1回限りの操作なので、これを行うのは適切ではありません。おそらく、フィルタに現在のプロジェクトIDを取得する方法を見つけることが必要です。たとえば、作成時にレコードをフィルタに渡す代わりに、フィルタが呼び出してプロジェクトIDを取得する呼び出し可能なデザインを使用することができます。たとえば:

class ProjectFilter(logging.Filter): 
    def __init__(self, func): 
     self.func = func 

    def filter(self, record): 
     record.projectid = self.func() 
     return True 

呼び出し可能なローカルの現在のコンテキスト(例えばスレッドからプロジェクトIDを取得する方法を知って何もすることができます - それはDjangoのコアチームによって承認されていないものの、それはスレッド地元の人々がのために発明されたものですFlaskなどの他のフレームワークでもうまく使用できます)。私はあなたのアプリケーションについて十分に知っていないので、呼び出し可能コードがどのように機能するかを示唆しています。

+0

Thanks Vinay私はそれが私の後ろだったので答えを受け入れました。PS - Love logging.py :) –

0

私はそれが最もエレガントな解決策ではないことを知っていますが、ログのソースを見直すと、「余分な」パラメータによってコンテキスト情報を追加できることがわかりました。

logger.info('A long entry', extra={'projectid': 1}) 

私は、ログエントリのメソッドをオーバーライドし、存在する場合は「余分な」パラメータを追加し、自分でロガーオブジェクトを導出ます。

私が使用LogAdaptorsに似ていますが、私が使用しているPythonのバージョンは、私はあなたのコメントを参照してください2.5倍:(

関連する問題