Python/Django: 在 runserver 下日志到控制台,在 Apache 下日志到文件

manage.py runserver下运行 Django 应用程序时,如何向控制台发送跟踪消息(如 print) ,但在 Apache 下运行应用程序时,如何将这些消息发送到日志文件?

I reviewed 姜戈伐木 and although I was impressed with its flexibility and configurability for advanced uses, I'm still stumped with how to handle my simple use-case.

164324 次浏览

在 mod _ wsgi 下运行时,输出到 stderr 的文本将显示在 httpd 的错误日志中。您可以直接使用 print,也可以使用 logging

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

You can configure logging in your settings.py file.

举个例子:

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 中的日志配置在该版本之后发生了一些变化。

你可以很容易地做到这一点与 tagalog( https://github.com/dorkitude/tagalog )

例如,当标准 python 模块写入在 append 模式下打开的文件对象时,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'])

您可以自己扩展模块并覆盖 log 函数,这不会有太大困难。

下面是一个基于 Django 日志记录的解决方案。它使用 DEBUG 设置,而不是实际检查您是否正在运行开发服务器,但是如果您找到了更好的方法来检查这一点,那么应该很容易进行调整。

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/

我用这个:

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,)

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()

This works quite well in my local.py, saves me messing up the regular logging:

from .settings import *


LOGGING['handlers']['console'] = {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
LOGGING['loggers']['foo.bar'] = {
'handlers': ['console'],
'propagate': False,
'level': 'DEBUG',
}