前言
Django
对于日志输出的信息是很完善的,request的信息,setting配置,trackback的信息,一应俱全,足够我们调试了。但是在线上环境,如果让用户看到这些信息,是很不安全的(暴露代码)。所以在线上我们要关闭Debug,但是又不能扔掉这些调试信息,这就要用到logging模块。
logging模块其实是Python的模块,在Django中有很多本地化的支持。
Python日志记录配置由四部分组成:
- Logger(记录仪)
- Handler处理程序
- Filters过滤器
- Formaters格式化程序
Logger
记录器是记录系统的入口点。每个记录器都是一个命名存储桶,可以将消息写入进行处理。
记录器配置为具有日志级别。此日志级别描述了记录器将处理的消息的严重性。Python定义了以下日志级别:
- DEBUG:用于调试目的的低级系统信息
- INFO:一般系统信息
- WARNING:描述已发生的小问题的信息。
- ERROR:描述已发生的主要问题的信息。
- CRITICAL:描述已发生的严重问题的信息。
- 一旦记录器确定需要处理消息,它就会传递给处理程序。
# 管理员邮箱
ADMINS = (
('laixintao','*******@163.com'),
)
# 非空链接,却发生404错误,发送通知MANAGERS
SEND_BROKEN_LINK_EMAILS = True
MANAGERS = ADMINS
# Email设置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST= 'smtp.163.com' # QQ邮箱SMTP服务器(邮箱需要开通SMTP服务)
EMAIL_PORT= 25 # QQ邮箱SMTP服务端口
EMAIL_HOST_USER = '**********@163.com' # 我的邮箱帐号
EMAIL_HOST_PASSWORD = '**************' # 授权码
EMAIL_SUBJECT_PREFIX = 'website' # 为邮件标题的前缀,默认是'[django]'
EMAIL_USE_TLS = True # 开启安全链接
DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER # 设置发件人
if Settings.System.log_dir and Settings.System.log_dir.startswith('/'):
log_dir = Settings.System.log_dir
else:
log_dir = os.path.join(BASE_DIR, 'logs')
LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 如果设置为True则不记录日志
# 过滤
'filters': {
'request_id': {
'()': 'log_request_id.filters.RequestIDFilter'
},
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
# 格式化
'formatters': {
# 可以设置多种格式,根据需要选择保存的格式
'standard': {
'format': '%(levelname)-4s [%(asctime)s] [%(request_id)s] %(filename)s: %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(asctime)s %(message)s'
}
'django.server': {
'()': 'django.utils.log.ServerFormatter',
'format': '[{server_time}] {message}',
'style': '{',
}
},
# formatters表示输出的形式,asctime是输出的时间,默认这是形式‘2019-10-10 16:29:28,756’(逗号后面的数字是时间的毫秒部分)。
# levelnam消息的文本日志记录级别('DEBUG', 'INFO', 'WARNING','ERROR', 'CRITICAL').
# name用于记录调用的记录器的名称。
# threadname线程名称(如果可用)threadd线程ID(如果可用)
# lineno发出日志记录调用的源行号(如果可用)
# disable_existing_loggers中的键如果为True 表示禁用loggers,默认False
# request_id
# filename日志来源文件名
# 日志真正处理器
'handlers': {
'django.server': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'django.server',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
# 仅当 DEBUG = False 时才发送邮件
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
},
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'filters': ['require_debug_true'],
},
'default': {
# 级别
'level': 'DEBUG',
# 指定日志文件大小,若超过指定的文件大小,会再生成一个新的日志文件保存日志信息
'class': 'logging.handlers.RotatingFileHandler',
# 文件大小
'maxBytes': 1024 * 1024 * 2,
# 备份数
'backupCount': 5,
# 日志过滤器:表示用请求id区别:来自于:filters中定义的
'filters': ['request_id'],
# 日志路径
'filename': os.path.join(log_dir, 'default.log'),
# 日志格式:来自于formatters中定义的
'formatter': 'standard',
# 设置默认编码,否则打印出来汉字乱码
'encoding': 'utf-8',
},
'default_error': {
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'filters': ['request_id'],
'filename': os.path.join(log_dir, 'default_error.log'),
'maxBytes': 1024 * 1024 * 2,
# 'backupCount': 5,
'formatter': 'standard',
},
'task': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filters': ['request_id'],
'filename': os.path.join(log_dir, 'task.log'),
'maxBytes': 1024 * 1024 * 2,
# 'backupCount': 5,
'formatter': 'standard',
}
},
# 定义日志记录器
'loggers': {
'django': {
'handlers': ['console', 'mail_admins'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
},
'django.server': {
'handlers': ['django.server', 'console'],
'level': 'INFO',
'propagate': False,
},
'default': {
# 指定处理器
'handlers': ['default', 'default_error', 'console'],
# 指定日志的最低级别
'level': 'DEBUG',
# 向不向更高级别的logger传递
'propagate': False
},
'task': {
'handlers': ['task', 'console'],
'level': 'DEBUG',
'propagate': False
},
# 生产环境下,系统错误发送邮件给系统管理员
'django.request': {
'handlers': ['default','mail_admins'],
'level': 'ERROR',
'propagate': True,
},
# 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件
'django.security.DisallowedHost': {
'handlers': ['null'],
'propagate': False,
},
}
}
# https://github.com/dabapps/django-log-request-id
LOG_REQUESTS = True # Logging all requests
LOG_REQUEST_ID_HEADER = "HTTP_X_REQUEST_ID"
GENERATE_REQUEST_ID_IF_NOT_IN_HEADER = True
REQUEST_ID_RESPONSE_HEADER = "HTTP_X_REQUEST_ID"
封装
# log.py
import logging
__all__ = [
'Logging',
'default_logger',
'task_logger',
]
class LoggingBase(object):
@property
def default_logger(self):
return logging.getLogger('default')
@property
def script_logger(self):
return logging.getLogger('script')
@property
def task_logger(self):
return logging.getLogger('task')
@staticmethod
def custom_logger(logger_name):
"""
Should be added in settings.py
:return:
"""
return logging.getLogger(logger_name)
Logging = LoggingBase()
default_logger = Logging.default_logger
task_logger = Logging.task_logger
视图使用
from common.log import default_logger as logger
logger.info("xxxxxxxxx")
logger.error("xxxxxxxxx")
task任务使用
from common.log import task_logger as logger
logger.info("xxxxxxxxx")
logger.error("xxxxxxxxx")