72

Celery ロギングを で動作させようとしていDjangoます。settings.pyコンソールに移動するためのログイン セットアップがあります(ホストしている場合は正常に動作しますHeroku)。各モジュールの上部には、次のものがあります。

import logging
logger = logging.getLogger(__name__)

そして私のtasks.pyには、次のものがあります。

from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)

これは、タスクからの呼び出しをログに記録するのに問題なく機能し、次のような出力が得られます。

2012-11-13T18:05:38+00:00 app[worker.1]: [2012-11-13 18:05:38,527: INFO/PoolWorker-2] Syc feed is starting

しかし、そのタスクが別のモジュールのメソッド (メソッドなど) を呼び出した場合、queryset重複したログ エントリが取得されます。

2012-11-13T18:00:51+00:00 app[worker.1]: [INFO] utils.generic_importers.ftp_processor process(): File xxx.csv already imported. Not downloaded
2012-11-13T18:00:51+00:00 app[worker.1]: [2012-11-13 18:00:51,736: INFO/PoolWorker-6] File xxx.csv already imported. Not downloaded

使えると思います

CELERY_HIJACK_ROOT_LOGGER = False

ロギングを使用するだけですDjangoが、試してみるとうまく"PoolWorker-6"いきませんでした。(ちなみに、Celery のログ エントリにタスク名を表示する方法がわかりません。これは、ドキュメントがそうすべきであることを示しているようです)。

ここで単純なものが欠けていると思います。

4

4 に答える 4

80

ロガーが「別のモジュール」の最初に初期化されると、別のロガーにリンクします。あなたのメッセージを処理します。ルートロガーにすることも、通常は Django プロジェクトで見られる名前の logger にすることもできます''

ここでの最善の方法は、ロギング構成をオーバーライドすることです。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'simple': {
            'format': '%(levelname)s %(message)s',
             'datefmt': '%y %b %d, %H:%M:%S',
            },
        },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'celery': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'celery.log',
            'formatter': 'simple',
            'maxBytes': 1024 * 1024 * 100,  # 100 mb
        },
    },
    'loggers': {
        'celery': {
            'handlers': ['celery', 'console'],
            'level': 'DEBUG',
        },
    }
}

from logging.config import dictConfig
dictConfig(LOGGING)

この場合、想定どおりに動作するはずです。

PS dictConfig は Python2.7+ で追加されました。

于 2012-11-17T10:53:03.503 に答える
11

重複したログの問題を修正するために、設定を宣言するときに伝播設定をfalseに設定するとうまくいきました.LOGGING dict

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        },
    },
    'formatters': {
        'verbose': {
            'format': '%(asctime)s %(levelname)s module=%(module)s, '
            'process_id=%(process)d, %(message)s'
        }
    },
    'loggers': {
        'my_app1': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False #this will do the trick
        },
        'celery': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True
        },
    }
}

django プロジェクトのレイアウトが次のようになっているとしましょう:
my_project/
- tasks.py
- email.py

タスクの 1 つが email.py の関数を呼び出すとします。ロギングは email.py で行われ、そのロギングは「親」に伝播されます。この場合はセロリ タスクです。したがって、二重ロギング。ただし、特定のロガーの伝播を False に設定すると、そのロガー/アプリのログは親に伝播されないため、「二重」ロギングは行われません。デフォルトでは、'propagate' は True に設定されています

これは、その親/子ロガーに関するdjangoドキュメントセクションへのリンクです

于 2015-07-06T17:08:29.497 に答える