Django 之日志配置
Django 之日志配置
日志作为服务的,排查故障分析性能及问题的重要“帮手”,是服务必不可少的。
配置日志
定义日志记录器
定义了三个日志记录器,分别针对Django、自定义应用程序和自定义库。每个日志记录器都有不同的日志级别和处理器,例如控制台和文件处理器。
Django日志记录器的级别为INFO,意味着只有INFO级别及以上的日志消息才会被记录。自定义应用程序的日志记录器的级别为ERROR,意味着只有ERROR级别及以上的日志消息才会被记录。
自定义库的日志记录器的级别为WARNING,意味着只有WARNING级别及以上的日志消息才会被记录。
### ### myproject/myproject/settings.py LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { #'level': 'INFO' 表示只记录INFO级别及以上的日志消息,不包含DEBUG级别的消息 #'level': 'DEBUG',记录所有级别的日志消息,包括DEBUG、INFO、WARNING、ERROR和CRITICAL 'level': 'DEBUG', 'class': 'logging.FileHandler', 'filename': '/git/Python/myproject/myapp/myapp.log', 'encoding': 'utf-8', }, }, 'loggers': { 'myapp_info': { 'handlers': ['file'], 'level': 'INFO', }, 'myapp_error': { 'handlers': ['file'], 'level': 'ERROR', }, 'myapp_warn': { 'handlers': ['file'], 'level': 'WARNING', }, 'myapp_critical': { 'handlers': ['file'], 'level': 'CRITICAL', }, 'myapp_debug': { 'handlers': ['file'], 'level': 'DEBUG', }, }, }
定义视图配置日志
设置日志等级
- logger.setLevel(logging.INFO)
- 表示将控制台处理器的日志记录级别设置为 INFO。这意味着,只有 INFO 级别及以上的日志消息才会被发送到控制台进行输出。
- 更低级别的日志消息,例如 DEBUG 级别的消息,将被忽略,不会在控制台上输出。
- 因此,只有 INFO、WARNING、ERROR 和 CRITICAL 级别的日志消息会被记录并输出到控制台。
- logger.setLevel(logging.DEBUG)
- 将文件处理器的日志记录级别设置为 DEBUG,这样所有级别的日志消息都会被记录到文件中。
- 将控制台处理器的日志记录级别也设置为 DEBUG,这样所有级别的日志消息都会被输出到控制台中
### ### myproject/myapp/views.py import logging # 创建一个名为myapp的日志记录器 # 使用了名为logger的默认记录器来记录日志消息 logger = logging.getLogger('myapp1') logger.setLevel(logging.INFO) # 创建一个控制台处理程序,并将其添加到日志记录器中 console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(status)s: %(message)s') # console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s') console_handler.setFormatter(console_formatter) logger.addHandler(console_handler) # 将默认记录器的处理器设置为file,以确保日志消息被写入文件 # 日志文件输出为乱码,可能是因为文件的编码格式不正确。你可以尝试在创建FileHandler对象时指定正确的编码格式 # 添加了一个名为file_handler的处理器,并将其级别设置为INFO。我们还将处理器的格式化程序设置为与handler相同的格式化程序。 # 然后,我们将处理器添加到默认记录器中,以确保日志消息被写入文件 # 创建一个文件处理程序,并将其添加到日志记录器中 file_handler = logging.FileHandler('/git/Python/myproject/myapp/myapp.log', encoding='utf-8') file_handler.setLevel(logging.INFO) file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(status)s: %(message)s') # file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s') # file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(file_formatter) logger.addHandler(file_handler) @csrf_exempt def config_form(request): ... if request.method == 'POST': #首先在settings.py文件中配置了两个日志记录器:一个是Django日志记录器,级别为INFO;另一个是自定义应用程序的日志记录器,级别也为INFO。然后,在我们的视图函数中,我们使用自定义应用程序的日志记录器来记录一条日志消息。这条消息将被记录到控制台和文件中,因为我们在日志处理器中指定了这两个处理器 try: logger.info('提交表单,重定向到/myapp/config/success/', extra={'status': 200}) except Exception as e: logger.error('跳转失败: %s', str(e), extra={'status': 500}) #可测试日志等级示例 # logger.debug('这是一条DEBUG级别的日志消息') # logger.info('这是一条INFO级别的日志消息') # logger.warning('这是一条WARNING级别的日志消息') # logger.error('这是一条ERROR级别的日志消息') # logger.critical('这是一条CRITICAL级别的日志消息') # return HttpResponse('这是响应消息') # 重定向到成功页面 return HttpResponseRedirect('/myapp/config/success/', content) else: #首先在settings.py文件中配置了两个日志记录器:一个是Django日志记录器,级别为INFO;另一个是自定义应用程序的日志记录器,级别也为INFO。 # 然后,在我们的视图函数中,我们使用自定义应用程序的日志记录器来记录一条日志消息。 # 这条消息将被记录到控制台和文件中,因为我们在日志处理器中指定了这两个处理器。最后,我们使用render函数来渲染模板并返回响应。 try: if logger.isEnabledFor(logging.INFO): logger.info('跳转显示表单页面', extra={'status': 200}) except Exception as e: if logger.isEnabledFor(logging.ERROR): logger.error('跳转显示表单页面失败: %s', str(e), extra={'status': 500}) return render(request, 'config_form.html', context) @validate_header def config_success(request): ... try: if logger.isEnabledFor(logging.INFO): logger.info('重定向到/myapp/config/success/,显示配置页面', extra={'status': 200}) except Exception as e: if logger.isEnabledFor(logging.ERROR): logger.error('重定向到显示配置页面失败: %s', str(e), extra={'status': 500}) # 第一个语句使用了extra参数,它是一个字典,可以用来传递额外的信息给日志记录器。在这里,它被用来传递状态码信息。当使用extra参数时,需要在日志格式化字符串中加入%(key)s占位符来表示额外信息的键名。 # 第二个语句直接使用了关键字参数来传递状态码信息。这种方式不需要在日志格式化字符串中加入额外信息的占位符。 # 总的来说,使用extra参数可以传递更多的额外信息,而使用关键字参数则更为简单直接。 # logger.error('重定向到显示配置页面失败', extra={'status': 500}) # logger.error('重定向到显示配置页面失败', status=401) return response
访问查看日志
http://localhost:8080/myapp/config
异常访问失败日志
正常访问日志
日志记录
2023-08-07 23:08:02,651 - myapp - DEBUG - middleware - 401: Invalid request header,未经授权的访问 2023-08-07 23:08:02,695 - myapp - DEBUG - middleware - 401: Invalid request header,未经授权的访问 2023-08-07 23:08:16,785 - myapp - DEBUG - middleware - 401: Invalid request header,未经授权的访问 2023-08-07 23:08:16,825 - myapp - DEBUG - middleware - 401: Invalid request header,未经授权的访问 2023-08-07 23:10:24,872 - myapp1 - INFO - views - 200: 重定向到/myapp/config/success/,显示配置页面 2023-08-07 23:10:24,874 - myapp - INFO - middleware - 200: 浏览器验证成功 2023-08-07 23:10:50,017 - myapp1 - INFO - views - 200: 跳转显示表单页面 2023-08-07 23:11:16,137 - myapp1 - INFO - views - 200: 提交表单,重定向到/myapp/config/success/ 2023-08-07 23:11:16,190 - myapp1 - INFO - views - 200: 重定向到/myapp/config/success/,显示配置页面 2023-08-07 23:11:16,191 - myapp - INFO - middleware - 200: 浏览器验证成功 2023-08-07 23:11:18,304 - myapp1 - INFO - views - 200: 跳转显示表单页面