Python / Django:runserverの下でコンソールに記録し、Apacheの下でファイルに記録します


113

printDjangoアプリを実行しているときにトレースメッセージをコンソール(など)に送信できますが、manage.py runserverApacheでアプリを実行しているときにこれらのメッセージをログファイルに送信するにはどうすればよいですか?

私はDjangoロギングをレビューしましたが、その柔軟性と高度な使用のための構成可能性に感銘を受けましたが、それでも私は単純なユースケースの処理方法に困惑しています。


回答:


84

stderrに出力されたテキストは、mod_wsgiで実行すると、httpdのエラーログに表示されます。print直接使用することも、logging代わりに使用することもできます。

print >>sys.stderr, 'Goodbye, cruel world!'

2
ただし、技術的には有効なWSGIではないため、より厳密な環境ではエラーが発生します。
ポールマクミラン

13
WSGIに関する限り、 'print。'を 'sys.stderr'で使用することに問題はなく、エラーが発生しないはずです。
Graham Dumpleton、2012

私はsysをインポートしましたが、これは私にはうまくいかないようです。
Hack-R

17
これはPython 3では機能しません。こちらをご覧ください。必要なものprint("Goodbye cruel world!", file=sys.stderr)
カルダモン2017

103

これがDjangoのロギングベースのソリューションです。開発サーバーを実行しているかどうかを実際に確認するのではなく、デバッグ設定を使用しますが、それを確認するより良い方法が見つかれば、簡単に適応できます。

LOGGING = {
    'version': 1,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/path/to/your/file.log',
            'formatter': 'simple'
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

if DEBUG:
    # make all loggers use the console.
    for logger in LOGGING['loggers']:
        LOGGING['loggers'][logger]['handlers'] = ['console']

詳細については、https://docs.djangoproject.com/en/dev/topics/logging/を参照してください。


8
また試してくださいLOGGING['loggers'][logger]['handlers'] += ['console']
Nir Levy

@ m01:これをsettings.pyに構成した後、これを印刷目的でどのように使用しますか?ありがとう
Niks Jain

私は自分の回答のコードをsettings.py一番下の方に入れDEBUG = Trueて設定しました(同じファイルの一番上の近くの設定を探します)。次に、python manage.py runserverターミナルから実行し(詳細についてはdjango docsを参照)、ログメッセージがターミナルウィンドウに表示されます。本番環境では、異なるsettings.pyを使用します。ここでDEBUG = False、ログメッセージはに送信され/path/to/your/file.logます。
m01

あなたのインデントは私に頭痛を与えました。情報をありがとう、それはうまくいきます!
ioan 2017

ありがとう!インデントにいくつかの変更を加えましたが、それが今より良くなることを願っています
m01

26

settings.pyファイルにロギングを設定できます。

一例:

if DEBUG:
    # will output to your console
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
    )
else:
    # will output to logging file
    logging.basicConfig(
        level = logging.DEBUG,
        format = '%(asctime)s %(levelname)s %(message)s',
        filename = '/my_log_file.log',
        filemode = 'a'
    )

しかし、それはDEBUGの設定に依存しており、おそらくそれがどのように設定されるかを心配する必要はありません。上のこの回答を参照してくださいどのように私は私のDjangoアプリケーションは、開発サーバー上で実行されているかどうかを伝えることができますか?その条件付きで書くためのより良い方法のために。編集:上記の例はDjango 1.1プロジェクトのもので、Djangoのロギング設定はそのバージョン以降多少変更されています。


DEBUGに依存したくありません。私はむしろ、他の投稿でリンクされているdev-server検出メカニズムに依存したいと思います。ただし、他の投稿の検出メカニズムは、リクエストインスタンスへのアクセス権に依存しています。settings.pyでリクエストインスタンスを取得するにはどうすればよいですか?
ジャスティングラント

4

私はこれを使います:

logging.conf:

[loggers]
keys=root,applog
[handlers]
keys=rotateFileHandler,rotateConsoleHandler

[formatters]
keys=applog_format,console_format

[formatter_applog_format]
format=%(asctime)s-[%(levelname)-8s]:%(message)s

[formatter_console_format]
format=%(asctime)s-%(filename)s%(lineno)d[%(levelname)s]:%(message)s

[logger_root]
level=DEBUG
handlers=rotateFileHandler,rotateConsoleHandler

[logger_applog]
level=DEBUG
handlers=rotateFileHandler
qualname=simple_example

[handler_rotateFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=applog_format
args=('applog.log', 'a', 10000, 9)

[handler_rotateConsoleHandler]
class=StreamHandler
level=DEBUG
formatter=console_format
args=(sys.stdout,)

testapp.py:

import logging
import logging.config

def main():
    logging.config.fileConfig('logging.conf')
    logger = logging.getLogger('applog')

    logger.debug('debug message')
    logger.info('info message')
    logger.warn('warn message')
    logger.error('error message')
    logger.critical('critical message')
    #logging.shutdown()

if __name__ == '__main__':
    main()

0

これはtagalog(https://github.com/dorkitude/tagalog)でかなり簡単に行うことができます

たとえば、標準のPythonモジュールは追加モードで開かれたファイルオブジェクトに書き込みますが、App Engineモジュール(https://github.com/dorkitude/tagalog/blob/master/tagalog_appengine.py)はこの動作をオーバーライドし、代わりにを使用しlogging.INFOます。

App Engineプロジェクトでこの動作を実現するには、次のようにするだけです。

import tagalog.tagalog_appengine as tagalog
tagalog.log('whatever message', ['whatever','tags'])

自分でモジュールを拡張して、ログ機能を簡単に上書きできます。


0

これは私のlocal.pyで非常にうまく機能し、通常のロギングを混乱させる手間を省きます。

from .settings import *

LOGGING['handlers']['console'] = {
    'level': 'DEBUG',
    'class': 'logging.StreamHandler',
    'formatter': 'verbose'
}
LOGGING['loggers']['foo.bar'] = {
    'handlers': ['console'],
    'propagate': False,
    'level': 'DEBUG',
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.