参考文档(引用若有版权问题,请联系删除)
logging.config --- 日志记录配置 — Python 3.8.13 文档
根据大江狗的配置是没有错的,但仍然有很多需要注意和提醒的地方
-
邮箱配置,在 django 的日志的邮箱配置中,用得是 SERVER_EMAIL 作为 from_email,而这个 SERVER_EMAIL 默认是 root@localhost 可能早期,qq 邮箱没有严格限制这个这个邮箱的真实性,后来才加的规则,所以这里要是一个正常格式的邮箱号即可,网站给的必须是<xxx@qq.com> 必须带尖括号格式是没有依据的,可以从源码中得出
# django 官方给的send_email 函数from_email参数是个普通的邮箱
from django.core.mail import send_mail
send_mail(
'Subject here',
'Here is the message.',
'from@example.com',
['to@example.com'],
fail_silently=False,
)
# 错误邮件拼接的类中from_email取的内容
def mail_admins(subject, message, fail_silently=False, connection=None,
html_message=None):
"""Send a message to the admins, as defined by the ADMINS setting."""
if not settings.ADMINS:
return
if not all(isinstance(a, (list, tuple)) and len(a) == 2 for a in settings.ADMINS):
raise ValueError('The ADMINS setting must be a list of 2-tuples.')
mail = EmailMultiAlternatives(
'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject), message,
# 这里就是获取SERVER_EMAIL 导致获取的是root@localhost错误格式
settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS],
connection=connection,
)
if html_message:
mail.attach_alternative(html_message, 'text/html')
mail.send(fail_silently=fail_silently)
# 邮件格式对象init函数
class EmailMultiAlternatives(EmailMessage):
"""
A version of EmailMessage that makes it easy to send multipart/alternative
messages. For example, including text and HTML versions of the text is
made easier.
"""
alternative_subtype = 'alternative'
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
connection=None, attachments=None, headers=None, alternatives=None,
cc=None, reply_to=None):
"""
Initialize a single email message (which can be sent to multiple
recipients).
"""
super().__init__(
subject, body, from_email, to, bcc, connection, attachments,
headers, cc, reply_to,
)
self.alternatives = alternatives or []
日志发送邮箱的配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# https://docs.djangoproject.com/en/dev/ref/settings/#email-host
EMAIL_HOST = 'smtp.qq.com'
# https://docs.djangoproject.com/en/dev/ref/settings/#email-port
EMAIL_USE_SSL = True
EMAIL_PORT = 465
EMAIL_HOST_USER = 'xxx@qq.com'
EMAIL_HOST_PASSWORD = 'xxxx'
DEFAULT_FROM_EMAIL = 'xxxx@qq.com'
SERVER_EMAIL = "xxxx@qq.com"
# 下面是给Django log 使用的
ADMINS = (
# 这个从上面的源码必须这样配置第一个是人名,第二个是邮箱号
('wangsen','xxxx@sina.com'),
)
MANAGERS = ADMINS
日志配置讲解
# Django 日志配置
LOG_DIR = os.path.join(BASE_DIR, "logs")
if not os.path.exists(LOG_DIR):
os.mkdir(LOG_DIR)
LOGGING = {
"version": 1,
"disable_existing_loggers": False, # 禁用已经存在的logger实例
# python 官方日志对filters略带讲了一下,但可以从对其他的东西的讲解知道
# () 这个key为一个特殊的key,意思是后面跟的是一个自定义的python类
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}}, # () 是一个保留key 标识用户自定义过滤
"formatters": { # 定义了两种日志格式
"verbose": { # 详细
"format": "%(levelname)s %(asctime)s %(module)s "
"%(process)d %(thread)d %(message)s"
},
'simple': { # 简单
'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
},
},
"handlers": { # 定义了三种日志处理方式
"mail_admins": { # 只有debug=False且Error级别以上发邮件给admin
"level": "ERROR",
"filters": ["require_debug_false"],
"class": "django.utils.log.AdminEmailHandler",
},
'file': { # 对INFO级别以上信息以日志文件形式保存
'level': "INFO",
'class': 'logging.handlers.RotatingFileHandler', # 滚动生成日志,切割
'filename': os.path.join(LOG_DIR, 'django.log'), # 日志文件名
'maxBytes': 1024 * 1024 * 10, # 单个日志文件最大为10M
'backupCount': 5, # 日志备份文件最大数量
'formatter': 'simple', # 简单格式
'encoding': 'utf-8', # 放置中文乱码
},
"console": { # 打印到终端console
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": "verbose",
},
},
"root": {"level": "INFO", "handlers": ["file"]},
"loggers": {
"django.request": { # Django的request发生error会自动记录
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": True, # 向不向更高级别的logger传递
},
"apps.blog": {"level": "DEBUG", "handlers": ["console", "file", "mail_admins"]},
},
}
# filter 类源码
class RequireDebugFalse(logging.Filter):
def filter(self, record):
return not settings.DEBUG
python 日志的 root 和 loggers 是父子之间的关系
也即使用时,可以根据你包名来配置 loggers 的归属关系,可以选择是否冒泡 propagate,这个挺有意思的
日志的使用
import logging
# __name__ 你还可以这样配置"apps.blog"
# 等价于Yii日志体系中的category 可以按类别进行过滤和收集
logger = logging.getLogger(__name__)