日志在程序开发中是非常重要的。在生产环境下,通过日志我们可以查看程序错误信息,处理程序异常。Django利用了python提供的logging模块来记录系统日志。

本节内容参考自Django官方文档,并结合实例进行功能实现演示,必要时请查阅python标准库有关logging模块的使用说明,确保你能够完全理解本节内容,然后才能进入下一节。

1 日志模块logging基本介绍

1.1 logging的组成

python的logging模块由四部分组成: - Loggers :用户使用的直接接口,将日志传递给Handler - Handlers:控制日志输出到哪里,console,file… ,一个logger可以有多个Handler - Filters:控制哪些日志可以从logger流向Handler - Formatters:控制日志的格式

Loggers

Logger是日志系统的入口。每个logger都是一个带有名称的bucket,你可以通过这个bucket写入需要处理的日志信息。
每个logger都有一个日志级别,日志级别表示该logger将要处理的消息的严重性。python定义的日志级别有:

写入logger的每条消息都是一个日志记录。每个日志记录也具有一个日志级别,它表示对应的消息的严重性。每个日志记录还可以包含描述正在打印的事件的有用元信息。 这些元信息可以包含很多细节,例如回溯栈或错误码。

当一条消息传递给logger时,消息的日志级别将与logger的日志级别进行比较。 如果消息的日志级别大于等于logger 的日志级别,该消息将会往下继续处理。 如果小于logger的日志级别,该消息将被忽略。

Logger一旦决定消息需要处理,它将传递该消息给一个Handler。

Handlers

Handler决定如何处理logger中的每条消息。 它描述一个特定的日志行为,例如将消息写到屏幕上、写到文件中或者写到网络socket。

与logger一样,handler也有一个日志级别。如果消息的日志级别小于handler的级别,handler将忽略该消息。

Logger 可以有多个handler,而每个handler 可以有不同的日志级别。利用这种方式,可以根据消息的重要性提供不同形式的处理。 例如,你可以用一个handler将CRITICAL和ERROR消息发送给一个页面服务,而用另外一个hander将所有的消息(包括ERROR和CRITICAL消息)记录到一个文件中用于以后进行分析。

Filters

Filter用于对从logger传递给handler的日志记录进行额外的控制。

通过filter,你可以对日志处理添加额外的条件。例如,你可以配置一个filter,只允许处理来自特定源的ERROR 消息。

Filters 还可以用于修改将要处理的日志记录的优先级。例如,如果日志记录满足特定的条件,可以编写一个filter 将日志记录从ERROR 降为WARNING。

Filters可以注册到loggers或handlers;可以将多个filters链接起来执行多个过滤操作。

Formatters

最后,日志记录需要转换成文本。Formatter用来定义日志最终输出的格式。我们可以编写自定义formatters来实现特定的格式化行为。

对于知识点的学习学习和理解始终都是枯燥的,接下来通过几个例子来进一步了解logging各部分的作用。

1.2 简单的日志输出

使用pycharm 打开sandboMP项目,接下的操作都在sandboxMP/apps/cmdb/tests.py中完成。
在sandboxMP/apps/cmdb/tests.py文件中写入如下内容:

import logginglogging.warning('Watch out!')
logging.info('I told you so')

按下Ctrl+S 保存并自动上传代码到远程服务器,右键tests.py文件,选择【Run tests】,在pycharm控制台可以看到info记录的信息没有输出,这是因为logging默认输出级别为WARNING级别。

控制台中输出的日志信息为:WARNING:root:Watch Out!,日志的输出使用了basicConfig默认的日志格式:

severity:logger name:message

1.3 将日志输出到文件

1.2中提到logging默认输出日志级别是WARNING,同时还提到日志输出格式是severity:logger name:message。这些信息都是在basicConfig中的默认配置,通过使用basicConfig方法能够满足基本需求,也可以通过指定参数来设置日志输出级别和日志输出的文件名,例如下面将日志输出到文件的实现。
将下面代码写入sandboxMP/apps/cmdb/tests.py,按下Ctrl+S保存并同步到远程服务器。

import logginglogging.basicConfig(filename='/root/project_file/example.log', level=logging.DEBUG)logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

说明: 上面例子中,使用了basicConfig方法,通过参数filename设置了日志输出文件路径,通过level定义了日志输出级别为DEBUG。注意: 因为pycharm采用的是远程部署模式,程序是运行在远程服务器上,所以这里指定的路径是远程服务器上项目根目录。

运行test.py,因为上面已经运行过一次,所以在pycharm右上角有快捷运行选项,可以直接运行:

完成运行操作以后使用CRT工具连接sandboxMP远程服务器,执行下面命令查看日志文件:

[root@sandboxmp ~]$ cat /root/project_file/example.log
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
[root@sandboxmp ~]$

除了登陆远程服务器查看项目文件外,pycharm远程部署功能还提供了浏览远程服务器上项目文件的功能,在pycharm上选择Tools → Deployment → Browse Remote Host。

通过日志文件可以看到,将level设置为DEBUG后,三条日志内容都输出到文件中了。
basicConfig方法除了可以配置日志输出级别和文件外,该方法可选参数还有:

一份日志基本信息应该包含日志的发生时间,所以上面的日志并不完善,让我们利用上面的这些参数来自定义日志输出格式,完善日志输出信息,修改test.py中的配置:

import logginglogging.basicConfig(filename='/root/project_file/example.log',level=logging.DEBUG,format='%(asctime)s %(levelname)s:%(message)s',datefmt='%Y-%m-%d %H:%M:%S',
)logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

按下Ctrl+S保存并上传,运行test.py,打开example.log文件,查看日志信息(日志文件的查看方法上面已经介绍了两种方法):

2018-12-01 21:00:03 DEBUG:This message should go to the log file
2018-12-01 21:00:03 INFO:So should this
2018-12-01 21:00:03 WARNING:And this, too

对比下前后两次日志输出的格式,理解下日志输出的基本配置。

如果你对日志记录需求比较简单,上面演示的基本功能就可以满足你的需求,接下来将介绍logging更多高级功能。

2 logging使用进阶

前面介绍了logging包含了四个组件:Logger、Handler、Filter、Formatter。

2.1 命名loggers

日志功能都是调用Logger类实例方法,可以通过logging.getLogger()调用获取一个logger实例,并且可以指定一个名称来标致这个实例,例如:

logger = logging.getLogger('sandbox')

在命名logger时,可以用点分割名称来表示层级关系,例如 sandbox.cmdb.scaner。

Logger的名称习惯上通常使用name,即包含该logger的Python模块的名字:

logger = logging.getLogger(__name__)

2.2 logging流程

下图是官方绘制的Loggers 和Handlers的处理流程:

  1. 当一条消息传递给logger时,消息的日志级别将与logger的日志级别进行比较。 如果消息的日志级别大于等于logger 的日志级别,该消息将会往下继续处理。 如果小于logger的日志级别,该消息将被忽略。
  2. 创建LogRecord对象,调用注册到Logger对象中的Filter进行过滤,如果不满足Filter条件,Filter将忽略该条信息;如果满足Fiter条件,继续下一步。
  3. Loger将消息传递给Handler来进行处理,如果消息的日志级别小于handler的级别,handler将忽略该消息,否则继续下一步。
  4. 判断当前Loger对象是否有父Logger对象,如果没有则流程结束,如果有重复2、3步骤中的操作。

看到这里是不是很头昏,别着急,我们还是通过一个实例来加深理解logging流程。
注释掉sandboxMP/apps/cmdb/tests.py中所有测试内容,写入下面内容:

import logging# 1.实例化一个logger,并使用test命名该logger,设置logger级别
logger = logging.getLogger('test')
logger.setLevel(logging.DEBUG)# 2.定义两个handler用来处理logger中的消息,一个handler将消息输出到控制台,一个输出到文件
handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="/root/project_file/example.log")# 3.将两个handler设置成不同的事件级别
handler1.setLevel(logging.DEBUG)
handler2.setLevel(logging.WARNING)'''
4.格式化日志输出,formatter常用变量参考官方文档:
https://docs.python.org/3.7/library/logging.html#logrecord-attributes'''
formatter = logging.Formatter("%(asctime)s :%(name)s :%(levelname)s %(message)s")
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)# 5.将两个处理器handler注册到logger,前面介绍到一个logger可以包含多个handler
logger.addHandler(handler1)
logger.addHandler(handler2)# 6.通过loger日志接口,写入不同级别的日志数据
logger.debug('sandbox debug message')
logger.info('sandbox info message')
logger.warning('sandbox warning message')
logger.error('sandbox error message')
logger.critical('sandbox critical message')

CTRL+S 保存并上传到远程服务器,使用CRT登陆sandboxMP远程服务器,在命令窗口输入下面内容清空临时日志文件中的内容:

[root@sandboxmp ~]$ echo '' > project_file/example.log

回到pycharm,运行test.py ,查看日志输出信息(一个输出到控制台,一个输出到文件),通过pycharm可以对比下日志信息:

通过图中信息可以看到,logger注册了两个handler来处理日志输出,handler1日志级别为DEBUG输出到控制台一共5条日志;handler2日志级别为WARNING输出日志到文件,一共输出3条日志。

2.3 logger配置

在2.2中logging的实现是放在代码中通过硬编码的形式来定义Handler和Formatter的,其实python的logging库还提供了通过配置文件的方式来配置logging,日志配置的方式有三种:1.在python代码中实现(2.2中用法)2.通过日志配置文件实现(支持ini和yaml格式),通过fileConfig()函数来读取配置文件;

# ini语法格式的配置文件
[loggers]
keys=root,simpleExample[handlers]
keys=consoleHandler[formatters]
keys=simpleFormatter[logger_root]
level=DEBUG
handlers=consoleHandler[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0
# yaml语法格式的配置文件
version: 1
formatters:simple:format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:console:class: logging.StreamHandlerlevel: DEBUGformatter: simplestream: ext://sys.stdout
loggers:simpleExample:level: DEBUGhandlers: [console]propagate: no
root:level: DEBUGhandlers: [console]

3.使用字典配置信息,通过dictConfig()函数来读取配置。

# dict格式的配置信息
LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'file': {'level': 'DEBUG','class': 'logging.FileHandler','filename': '/path/to/django/debug.log',},},'loggers': {'django': {'handlers': ['file'],'level': 'DEBUG','propagate': True,},},
}

logging模块的共功非常灵活,有兴趣的朋友可以深入学习下官方文档和cookbook:

https://docs.python.org/3.6/library/logging.html#logrecord-attributes
https://docs.python.org/3.6/howto/logging-cookbook.html#logging-cookbook

2 定义项目中使用的日志格式

对于1中的logging内容,如果你没有完全理解也没关系,下面我们来定义项目中的日志配置。

  1. 在项目中新建日志存储目录(右键项目更目录新建文件夹):sandboxMP/slogs;
  2. 打开sandboxMP/sandboxMP/settings.py,添加logging配置内容:
# logging configBASE_LOG_DIR = os.path.join(BASE_DIR, 'slogs')LOGGING = {'version': 1,'disable_existing_loggers': False,  # 禁用已经存在的logger实例# 日志文件的格式'formatters': {# 详细的日志格式'standard': {'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(levelname)s]''[%(filename)s:%(lineno)d][%(message)s]'},# 简单的日志格式'simple': {'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'},},# 处理器'handlers': {# 默认的'default': {'level': 'INFO','class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切'filename': os.path.join(BASE_LOG_DIR, "sandbox_info.log"),  # 日志文件'maxBytes': 1024 * 1024 * 50,  # 日志大小50M'backupCount': 3,  # 最多备份3个日志文件'formatter': 'simple','encoding': 'utf-8',},# 用来记错误日志'error': {'level': 'ERROR','class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切割日志文件'filename': os.path.join(BASE_LOG_DIR, "sandbox_err.log"),  # 日志文件'maxBytes': 1024 * 1024 * 50,  # 日志大小50M'backupCount': 5,'formatter': 'standard','encoding': 'utf-8',}},'loggers': {# 名为sandbox_info的logger'sandbox_info': {'handlers': ['default'],  # 使用defaul handler'level': 'INFO','propagate': True,  # 向不向更高级别的logger传递},# 名为 'sandbox_error'的logger'sandbox_error': {'handlers': ['error'],'level': 'ERROR',}}}

3.在项目中测试日志配置 修改sandboxMP/apps/cmdb/test.py文件,删除原来的所有测试内容,添加如下内容:

from django.views.generic.base import View
from django.shortcuts import HttpResponse
import logging
from .models import Codeinfo_logger = logging.getLogger('sandbox_info')
error_logger = logging.getLogger('sandbox_error')class TestLoggingView(View):def get(self, request):print('a')info_logger.info('The system print a letter "a" ')try:Code.objects.get(id=100)except Exception as e:error_logger.error(e)return HttpResponse("OK!")

  • 上面代码中实例化了两个logger:info_logger和error_logger;
  • 定义了一个视图TestLoggingView;
  • 视图中执行了print('a')操作,然后通过info_logger输出日志;
  • 进行Code数据库查询(这个数据库中现在还没有数据,所以执行get查询一定会报告错误),捕获错误信息,通过error_loger输出日志。

修改sandboxMP/sandboxMP/urls.py,添加下面的URL:

from cmdb.tests import TestLoggingViewurlpatterns = ['''原有内容省略'''path('test/', TestLoggingView.as_view()),]

修改sandboxMP/sandboxMP/settings.py,添加访问白名单(/test/只是用来测试,不需要加入权限系统,所以直接添加到白名单就可以访问了)

# safe url
SAFE_URL = [r'^/$','/login/','/logout','/index/','/media/','/admin/','/ckeditor/','/test/',]

==Ctrl+S==保存并上传项目,然后运行项目,注意这时候的右上角运行按钮旁的运行环境不是test了,要选择SMP_Remote,运行后访问测试页面:

# 测试页面会返回OK
http://172.16.3.100:8000/test/

这时候查看远程服务器上的项目文件,在sandboxMP/slogs目录下会多处两个日志文件:sandbox_err.log 和 sandbox_info.log ,日志内容分别如下:

# sandbox_err.log日志内容
[2018-12-01 23:45:56,656][Thread-1:140421591549696][task_id:sandbox_error][ERROR][tests.py:76][Code matching query does not exist.]# sandbox_info.log日志内容
[INFO][2018-12-01 23:45:56,317][tests.py:72]The system print a letter "a"

可以看到在访问/test/页面时,通过不同名称的logger实列,将符合不同handler规则的日志信息写入到了不同的文件。

最后保留settings.py文件中日志格式的配置,在后面的项目中将会使用这个日志配置,tests.py 和 urls.py中的测试配置,以及settings.py中的URL白名单中的/test/ 可以删除。

修改完成后按下==Ctrl+S==保存并上传到远程服务器。

更多实战类文档,点个关注呗!
知乎专栏:SandBox
知乎专栏:Django 学习小组
最新最全文档,请关注我的知识星球: https://t.zsxq.com/MBiqJi2(微信中打开链接)
本节文档对应源码版本: https://github.com/RobbieHan/sandboxMP/tree/v2.04
轻量级办公管理系统项目开源地址:https://github.com/RobbieHan/gistandard

pycharm console日志如何输出到txt_Django实战2-自动化运维之配置管理-04:知识扩展-logging日志模块...相关推荐

  1. 【网工手艺】专栏入口(网工学习实战+网络自动化运维探讨)

    哈喽,大家好!第一次在CSDN发文章哈! 我叫朱嘉盛,一名至今依然奋战在一线运维的平凡网工.入行11载,通信网2G守到5G,互联网(城域网)从近乎空白全程参与到百来万用户.一路走来,在网络自动化运维方 ...

  2. 一个颜值低但脾气超好的自动化运维实战入门教程

    注:本教程由廖高祥发布于实验楼,版权归原作者所有. 什么是自动化运维? 自动化运维是指将IT运维中日常的.大量的重复性工作自动化,把过去的手工执行转为自动化操作.自动化运维不单纯是一个维护过程,更是一 ...

  3. Django项目实战:CMDB资产扫描和DevOPS自动化运维

    文章目录 项目实战:CMDB自动化资产扫描和自动化运维 1.项目介绍 2.项目技术分析 运维自动化难点和痛点 项目技术难点 整体工程设计 3.项目环境搭建 项目环境要求 项目环境的搭建 项目目录的配置 ...

  4. python paramiko模块下载_Python自动化运维实战:使用Python管理网络设备

    现在,我们已经知道如何在不同的操作系统中使用和安装Python以及如何使用EVE-NG搭建网络拓扑.在本章中,我们将学习如何使用目前常用的网络自动化库自动完成各种网络任务.Python可以在不同的网络 ...

  5. 自动化运维-----项目实战: 基于Ansible的云平台自动化运维系统

    文章目录 项目实战: 基于Ansible的云平台自动化运维系统 一.项目介绍 1.项目介绍 2.项目背景 二.项目环境搭建 1.项目目录的配置 2.远程服务器虚拟环境的配置 3.MySQL数据库配置 ...

  6. 自动化运维工具-Ansible实战指南

    Ansible实战 前言 一.Ansible简介 1.ansible是什么? 2.ansible特点 3.ansible架构 主要模块 工作流程 命令执行过程 二.Ansible 配置 1 安装ans ...

  7. Python+Django+Ansible Playbook自动化运维项目实战(二)

    Python+Django+Ansible Playbook自动化运维项目实战 一.资产管理,自动化发现.扫描 1.服务端资产探测.扫描发现 1)资产管理的资产: 2)抽象与约定: 2.探测协议和模块 ...

  8. Python+Django+Ansible Playbook自动化运维项目实战:资产管理

    Python+Django+Ansible Playbook自动化运维项目实战 一.资产管理,自动化发现.扫描 1.服务端资产探测.扫描发现 1)资产管理的资产: 2)抽象与约定: 2.探测协议和模块 ...

  9. 云计算开发教程:Python自动化运维开发实战流程控制

    今天这篇文章是给大家分享一些云计算开发教程,今天讲解的是:Python自动化运维开发实战流程控制. Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. P ...

最新文章

  1. oracle主目录修改,ORACLE主目录权限被修改,恢复ORACLE_HOME或GI_HOME权限、属主
  2. perl开发环境配置(Database,SOCKET,CISCO)j(ReShip)
  3. C# 窗体最小化的托盘/系统通知区域(转)
  4. 腾讯员工晒出薪资:真实 985 毕业薪资,大家看我还有救吗?网友:日薪?
  5. Python中的石头、剪刀、布游戏
  6. PAT甲级1054 map的使用
  7. JavaScript(第二十二天)【动态加载js和css】
  8. Mac 效率工具必备神器 —— Alfred
  9. 最新版苹果手机html5摇一摇,iphone微信摇一摇失效问题解决
  10. 别让生活 耗尽了你的耐心和向往 你还有诗和远方...
  11. spring核心技术之Resource资源理解
  12. NTFS和FAT32的区别和转换
  13. 《心经》经典段落及释义
  14. Unity3d 动态字体
  15. 企业微信三方开发:注册企业微信服务商
  16. springboot+乡村图书管理系统 毕业设计-附源码191505
  17. NG-ALAIN 边学边记1
  18. 怎么找外贸客户之海关数据
  19. WiFi、蓝牙以及双WiFi流程
  20. 企业为何要认定高新技术企业,都有哪些好处?

热门文章

  1. codeforces 675E E. Trains and Statistic(线段树+dp)
  2. 解决VMWare Workstation 响应慢
  3. mos 多路模拟电子开关_软开关设计 || 软开关硬件三极管、MOS管典型电路分析
  4. Java代码有效和片段有效_Java 9 尝鲜之交互式编程环境
  5. windows系统下修改mysql时区_Linux与Windows下修改MySql时区的方法
  6. 斜视术后融合训练方法_做斜视手术两年后又复发了怎么办?
  7. prim算法_历时两月,终拿字节跳动offer,算法面试题分享「带答案」
  8. UI素材模板|新拟态新趋势图标ICON
  9. 超简单炫彩抽象线条感海报PSD分层素材,一切变得简单!
  10. UI设计中常见插画应用素材,拿来就可以用!