Par*_*and 94 python django logging
我还没有找到一种用Django设置Python日志的方法,我很满意.我的要求很简单:
我目前的设置是logging.conf在我登录的每个模块中使用文件和设置日志记录.感觉不对劲.
你有自己喜欢的日志设置吗?请详细说明:如何设置配置(logging.conf在代码中使用或设置),何时/何时启动记录器,以及如何在模块中访问它们等.
Ste*_*ano 121
我知道这已经是一个已经解决的答案,但是根据django> = 1.3,有一个新的日志记录设置.
从旧到新是不自动的,所以我想我会在这里写下来.
当然,请查看django doc以获取更多信息.
这是基本的conf,默认使用django-admin createproject v1.3创建 - 里程可能会随着最新的django版本而改变:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
}
}
}
Run Code Online (Sandbox Code Playgroud)
此结构基于标准Python日志记录dictConfig,它指示以下块:
formatters - 相应的值将是一个dict,其中每个键是格式化程序ID,每个值都是一个描述如何配置相应的Formatter实例的字典.filters - 相应的值将是一个dict,其中每个键都是一个过滤器ID,每个值都是一个描述如何配置相应Filter实例的dict.handlers - 相应的值将是一个dict,其中每个键是一个处理程序ID,每个值都是一个描述如何配置相应的Handler实例的dict.每个处理程序都有以下键:
class(强制).这是处理程序类的完全限定名称.level(可选的).处理程序的级别.formatter(可选的).此处理程序的格式化程序的ID.filters(可选的).此处理程序的过滤器的ID列表.我通常至少这样做:
这转化为:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'null': {
'level':'DEBUG',
'class':'django.utils.log.NullHandler',
},
'console':{
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
# I always add this handler to facilitate separating loggings
'log_file':{
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(VAR_ROOT, 'logs/django.log'),
'maxBytes': '16777216', # 16megabytes
'formatter': 'verbose'
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
'apps': { # I keep all my of apps under 'apps' folder, but you can also add them one by one, and this depends on how your virtualenv/paths are set
'handlers': ['log_file'],
'level': 'INFO',
'propagate': True,
},
},
# you can also shortcut 'loggers' and just configure logging for EVERYTHING at once
'root': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO'
},
}
Run Code Online (Sandbox Code Playgroud)
编辑
请参阅请求异常现在始终记录并且票证#16288:
我更新了上面的示例conf以明确包含mail_admins的正确过滤器,以便默认情况下,当debug为True时不会发送电子邮件.
你应该添加一个过滤器:
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
Run Code Online (Sandbox Code Playgroud)
并将其应用于mail_admins处理程序:
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
}
Run Code Online (Sandbox Code Playgroud)
否则,django.core.handers.base.handle_uncaught_exception如果settings.DEBUG为True,则不会将错误传递给'django.request'记录器.
如果你不在Django 1.5中这样做,你会得到一个
弃用警告:您没有在'mail_admins'日志记录处理程序上定义过滤器:添加隐式debug-false-only过滤器
但事情仍然可以在django 1.4和django 1.5中正常工作.
**结束编辑**
这个conf受到django doc中示例conf的强烈启发,但添加了日志文件部分.
我经常也做以下事情:
LOG_LEVEL = 'DEBUG' if DEBUG else 'INFO'
...
'level': LOG_LEVEL
...
Run Code Online (Sandbox Code Playgroud)
然后在我的python代码中,我总是添加一个NullHandler,以防无法定义任何记录conf.这避免了没有指定Handler的警告.对于不一定只在Django中调用的库特别有用(参考)
import logging
# Get an instance of a logger
logger = logging.getLogger(__name__)
class NullHandler(logging.Handler): #exists in python 3.1
def emit(self, record):
pass
nullhandler = logger.addHandler(NullHandler())
# here you can also add some local logger should you want: to stdout with streamhandler, or to a local file...
Run Code Online (Sandbox Code Playgroud)
[...]
logger.warning('etc.etc.')
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
Vin*_*jip 53
到目前为止,我发现的最好的方法是初始化settings.py中的日志记录设置 - 其他地方.您可以使用配置文件,也可以逐步编程 - 这只取决于您的要求.关键是我通常会将我想要的处理程序添加到根记录器中,使用级别,有时还使用logging.Filters来获取我想要的事件到适当的文件,控制台,系统日志等.您当然可以将处理程序添加到任何其他记录器同样,但根据我的经验,通常不需要这样做.
在每个模块中,我使用定义记录器
logger = logging.getLogger(__name__)
Run Code Online (Sandbox Code Playgroud)
并使用它来记录模块中的事件(如果我想进一步区分),请使用一个记录器,它是上面创建的记录器的子代.
如果我的应用程序可能会在未配置settings.py中的日志记录的站点中使用,我会在某处定义NullHandler,如下所示:
#someutils.py
class NullHandler(logging.Handler):
def emit(self, record):
pass
null_handler = NullHandler()
Run Code Online (Sandbox Code Playgroud)
并确保将其实例添加到我的应用程序中使用日志记录的模块中创建的所有记录器中.(注意:NullHandler已经在Python 3.1的日志包中,并且将在Python 2.7中.)所以:
logger = logging.getLogger(__name__)
logger.addHandler(someutils.null_handler)
Run Code Online (Sandbox Code Playgroud)
这样做是为了确保您的模块在没有配置settings.py中的日志记录的站点中很好地运行,并且您没有得到任何恼人的"无法找到记录器XYZ的处理程序"消息(这是关于潜在的警告错误配置的日志记录).
这样做可以满足您的要求:
getLogger(__name__).settings.py.更新:请注意,从版本1.3开始,Django现在包含对日志记录的支持.
我们urls.py使用logging.ini文件初始化顶级日志记录.
的位置logging.ini提供了settings.py,但仅此而已.
然后每个模块都可以
logger = logging.getLogger(__name__)
Run Code Online (Sandbox Code Playgroud)
为了区分测试,开发和生产实例,我们有不同的logging.ini文件.在大多数情况下,我们有一个"控制台日志",仅带有错误的stderr.我们有一个"应用程序日志",它使用一个转到日志目录的常规滚动日志文件.