Pythonロギング-すべてのロガーのログメッセージをフィルター


8

基盤となるツールがログを記録しているプロジェクトがあり、(別のロガーインスタンスを使用して)ログも記録しています。

ただし、アクセス権のないロガーが、ログから削除したい(またはプレースホルダーに置き換えたい)情報を公開する場合があります。

フィルターを使用してプロジェクト内のすべての pythonロガーにそれを行う方法はありますか?

Djangoのログ設定は次のとおりです。

LOGGING_CONFIG = None
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "my_formatter",
        },
    },
    "loggers": {
        "my_logger": {
            "handlers": ["console"],
            "level": "DEBUG"
        },
    },
}

logging.config.dictConfig(LOGGING)

本当に、私の最終的な目標は、特定のものがログに表示されないように置き換えることです。それを行う他の方法がある場合は、自由に共有してください。

ありがとう!


ロギングをどのように初期化/構成しますか?
クラウスD.

質問を更新しました。
OhMad

それで、あなたの質問は「ログイベントをフィルタリングする方法」ですよね?
pbacterio

回答:


3

重要なデータをフィルタリングすることが主な目的である場合は、Pythonを使用してログから機密データを非表示にするをご覧ください。logging.Filter一部のレコードのロギングを防止するためにを実装するかloggingFormatter、正規表現を使用して特定のレコードの部分のみを削減するためにを実装できます。

フィルターとフォーマッターのクラスをすべてのロガーに適用するには、それらをdict構成で定義し、所有しているすべてのハンドラーに追加します。また、を設定して、説明されていないハンドラを削除することを検討してくださいdisable_existing_loggers': TrueDjangoのロギングドキュメントでカスタムフォーマッタとフィルタの例をご覧ください。


2

信じられないかもしれませんが、基礎となるプロジェクトのロガーにアクセスできます!あなたはdjangoにいるので、それらの基礎となるプロジェクトのロガーがインスタンス化される前に、あなたの設定をロードし、ロギングを初期化することができます。

これは2段階のプロセスです。最初のステップは、抑制したいメッセージのソースであるロガーを識別することです。これを行うには、以下を追加namemy_formatterます。

    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] [%(name)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },

名前を見つけたら、フィルターを定義できます。

import logging


class AwesomeFilter(logging.Filter):
    def filter(self, rec):
        if 'sensitive' in rec.msg:
            return 0
        # you may need to filter based on `getMessage()` if
        # you can't find the information in the pre-formatted msg field
        return 1

そして、あなたは悪いメッセージを出しているロガーの名前を知っているので、ロガーに接続することができますAwesomeFilter

LOGGING_CONFIG = None
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] [%(name)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "my_formatter",
        },
    },
    "loggers": {
        "my_logger": {
            "handlers": ["console"],
            "level": "DEBUG"
        },
        "name_of_logger_producing_bad_messages": {
            "filters": [ "app.filters.AwesomeFilter", ],
        },
    },
}

logging.config.dictConfig(LOGGING)

ロガーの名前を見つけるトリックを使用して、サードパーティのライブラリのロギングの出力を頻繁に制御します。幸運を!


1

同じロギング構成をプロジェクトのすべてのワーカーに伝播する場合は、utilsにロガーファイルを作成し、どこにでもインポートして、代わりに使用することをお勧めします import logging

あなたの設定が他のハンドラと競合していないことを確認したい場合は、次のようにすることができます

ファイルutils / log.py

import logging
import os

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)]
LOGGING_CONFIG=[your config]
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger()

次に、ログ記録ライブラリではなく、すべてのワーカーにこのロガーをインポートします

from utils.log import logger

logger.info("Hello world")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.