2

XMLRPCリクエストを処理するためのサーバーアプリケーションがあります。各接続は独自のスレッドを作成します。スレッド/接続固有の情報がログに記録されるように、ログを設定したいと思います。私は次のようなことをすることができます:

import logging

@add_unique_request_id
def thread_top(request_id):
    logging.info('thread %d says: hello'%request_id)
    logging.error('thread %d says: darn!!'%request_id)

必要に応じてグローバルルートロガーを設定しますが、このソリューションは好きではありません。代わりに次のようにしたいと思います。

import logging

@setup_logger
def thread_top():
    logging.info('hello')
    logging.error('darn!!')

しかし、setup_loggerデコがどのように見えるべきかわかりません。リクエストごとに個別のプロセスを使用する回避策を考え出しました。その後、各プロセスでルートロガーを設定すると、希望どおりの結果が得られます。マルチプロセッシングを使用せずにこれを機能させる方法はありますか?

ありがとうございました!

4

1 に答える 1

1

私はこれをカスタムフォーマッターとスレッドローカルストレージで行っています:

from collections import defaultdict
import logging
import threading

class ContextAwareFormatter(logging.Formatter):
    """
    Makes use of get_context() to populate the record attributes.
    """

    def format(self, record):
        # Using defaultdict to avoid KeyErrorS when a key is not in the context.
        def factory():
            return ""
        record.__dict__ = defaultdict(factory, record.__dict__)

        for k, v in get_context().iteritems():
            if not hasattr(record, k):
                setattr(record, k, v)
        return logging.Formatter.format(self, record)

THREADLOCAL_ATTR = "logging_context"
_threadlocal = threading.local()

def get_context():
    result = getattr(_threadlocal, THREADLOCAL_ATTR, None)
    if result is None:
        result = {}
        setattr(_threadlocal, THREADLOCAL_ATTR, result)
    return result

def set_context(**context):
    c = get_context()
    c.clear()
    c.update(**context)
    return c

def update_context(**context):
    c = get_context()
    c.update(**context)
    return c

次に、ロガー構成で:

"formatters": {
    "default": {
        "()": "log.ContextAwareFormatter",
        "format": "%(asctime)s %(levelname)s [%(request_id)s] %(message)s (%(module)s:%(lineno)d)",
    },
}

ログに記録する前に、コンテキストには次の情報が入力されます。

update_context(request_id=request_id)

request_idログレコードで必要とされない可能性のあるアプリケーションのさまざまな部分に、さまざまなフォーマッタを使用することをお勧めします。

于 2012-06-12T10:23:49.760 に答える