5

django アプリケーションで Python ロギングを使用しています。バックエンド API に接続するクラスは、必要に応じてファイル ハンドラーを使用してこのロガーを初期化します。クラスは、API 呼び出しが行われるたびにインスタンス化されます。追加のハンドラーが毎回追加されないようにしようとしましたが、

lsof | grep my.log 

ログ ファイルでハンドラーの量が増加していることを示しており、しばらくすると、この開いているファイルの制限が原因でサーバーに障害が発生します。

 self.logger = logging.getLogger("FPA")

        try:
            if self.logger.handlers[0].__class__.__name__=="FileHandler":
                pass
        except Exception, e:
            print 'new filehandler added'+str(e)
            ch = logging.FileHandler(FPA_LOG_TARGET)
            formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s - %(pathname)s @ line %(lineno)d")
            ch.setFormatter(formatter)
            self.logger.setLevel(logging.DEBUG)
            self.logger.addHandler(ch)

これが最善の方法ではないことは承知していますが、これまでの実装でエラーは見つかりませんでした。

4

1 に答える 1

1

長い間分析していませんでしたが、並行性の問題のようです。

各プロセス/スレッドは、開いているログファイルへのファイルハンドルの独自のリストを保持しています。

それを修正する方法は?マルチスレッドコードの場合、すべてのハンドルが保持されているグローバルディクショナリがあることを確認してください。マルチプロセスの場合-答えがないのではないかと思います...各プロセスは独自のファイルハンドルを保持しており、メモリにマッピングしている可能性があります(メモリマップファイルはオプションである可能性があります)が、よくわかりませんこれは良い解決策です-この注釈を参照してください

しかし、主な問題は、なぜそのようなことをする必要があるのか​​ということです。

まず、logging.confファイルを使用してすべてのロガー/ハンドラー/フォーマッターを初期化し、必要に応じて(たとえば、特定のロガーが広範囲にわたっていて、別のファイルに記録したい場合)、別のファイル名で別のロガーを追加できます。アプリのメインに追加して、djangoアプリごとに1つのロガーを追加する場合、これは非常に賢明__init__.pyです。

import logging
log = logging.getLogger(__name__)

log次に、残りのアプリコード(ビュー、モデルなど)をインポートします

使用logging.confするには、settings.pyに次の行を追加します。

import os
import logging
DIRNAME = os.path.abspath(os.path.dirname(__file__))
logging.config.fileConfig(os.path.join(DIRNAME, 'logging.conf'))

はい、手動ですが、コードを変更する必要はなく、構成ファイルを変更するだけです。

別のアプローチ(ロガータイプごとに1つのファイルが本当に必要な場合)は、ファイルを開いたままにして、アプリケーションからの接続を受け入れる別のプロセスを用意することです。ロギングモジュールのドキュメントには、このメソッドの良い例があります。

最後になりましたが、役立つかもしれないいくつかの素晴らしい解決策がすでにあります。1つは、非常に良いことですが、django-sentryを使用することです。このモジュールは、すべての例外404(追加のミドルウェアを含む)をログに記録し、(含まれているログハンドラーを介して)すべてのログをキャプチャできます。

提供されたUIにより、ログに記録されたすべてのメッセージを検索し、重大度とログソースでフィルタリングすることができます。しかし、これはそれらに限定されません-あなたは単にあなた自身のモジュールを追加することができます。

于 2011-03-21T13:40:58.297 に答える