2021SC@SDUSC
上周分析的代码部分主要为 Framework.py ,本周对其涉及调用的其他文件代码部分进行分析。
上周对 Framework 部分的主要源代码文件 Framework.py 的源码进行了简单的分析介绍,其中 Framework.py 导入并引用了很多其他的类,以及类方法。上周在分析 主要文件 Framework.py 的源码时,对于调用的其他类的方法,仅仅简单那看了一下这个类方法所实现的功能,返回的值等基本信息,并未对其实现过程,以及这个方法所属的类进行详细分析。所以本周的任务主要是对 Framework.py 文件中所引用的相关类以及相关类方法的实现代码进行详细分析,分析其方法实现过程与原理。
使用 UML 类图简单描述下 Framework.py 所涉及的各个类之间的关系
本部分对 Logger.py 源码进行分析,该部分主要是实现系统日志相关的功能,将日志以一定格式输出到系统文件、将日志输出到远程系统等等日志相关的功能。Logger 类中关键其实主要是 logger 这个属性,而 logger 属性定义 :logger = logging.getLogger('frameworkd')
,主要与 python 的 logging 模块相关。
首先导入相关模块
import string, logging, os, sys
在用 Python 编写代码的时候,在想查看相关信息的地方利用 print xx 就能在控制台上显示打印相关信息,这样就能知道一些程序运行过程中产生的相关信息,但是当我需要看大量的地方或者在一个文件中查看的时候,这时候使用 print 可能就不大方便了,所以 Python 引入了 logging 模块来记录我想要的信息。
print 也可以输入日志,但是 logging 相对 print 来说更便于控制输出在哪个地方,怎么输出以及控制消息级别来过滤掉那些不需要的信息。
接下来是具体类的代码部分
首先创建一个 logger 日志对象,然后设置默认的日志级别、创建日志格式对象、自定义日志格式、logger日志对象加载StreamHandler对象。
handler:用来自定义日志对象的规则(比如:设置日志输出格式、等级等)
关于这个级别的问题,后面会涉及到
级别排序 : CRITICAL > ERROR > WARNING > INFO > DEBUG
debug : 打印全部的日志,详细的信息,通常只出现在诊断问题上
info : 打印info,warning,error,critical级别的日志,确认一切按预期运行
warning : 打印warning,error,critical级别的日志,一个迹象表明,一些意想不到的事情发生了,或表明一些问题在不久的将来(例如。磁盘空间低”),这个软件还能按预期工作
error : 打印error,critical级别的日志,更严重的问题,软件没能执行一些功能
critical : 打印critical级别,一个严重的错误,这表明程序本身可能无法继续运行
使用工厂方法返回一个Logger实例
logger = logging.getLogger('frameworkd')
Log等级总开关,设置日志级别
logger.setLevel(logging.INFO)
格式
DEFAULT_FORMAT = '%(asctime)s %(module)s [%(levelname)s]: %(message)s'
SYSLOG_FORMAT = 'ossim-frameword: %(asctime)s %(module)s [%(levelname)s]: %(message)s'
定义handler的输出格式,Formatter为python通用的格式化输出,字符串格式化工具
__formatter = logging.Formatter(DEFAULT_FORMAT)
__streamhandler = None
默认情况下加载Streamhandler,也就是将信息输出到控制台
它将在守护程序模式下被删除
__streamhandler = logging.StreamHandler()
StreamHandler对象自定义日志格式
__streamhandler.setFormatter(__formatter)
logger日志对象加载StreamHandler对象
logger.addHandler(__streamhandler)
1、remove_console_handler()
方法:
这个方法代码很简单,就是用来移除上面代码默认设置的 __streamhandler = logging.StreamHandler()
当 Agent 以守护程序模式启动时调用该方法
if Logger.__streamhandler:
Logger.logger.removeHandler(Logger.__streamhandler)
2、_add_file_handler(file, log_level = None)
方法:
以特定格式,将日志信息输出到指定磁盘文件上
首先获取传入变量 file
的目录地址,并判断该目录地址是否存在,如果不存在,则使用 makedirs
递归创建该目录
rstrip: 删除 string 字符串末尾的指定字符(默认为空格)
os.path 模块主要用于获取文件的属性
basename():返回文件名
dir为file文件的目录地址
def _add_file_handler(file, log_level = None):
dir = file.rstrip(os.path.basename(file))
先判断file文件目录地址是否存在,如果不存在,则使用makedirs创建该目录地址
os.makedirs(dir, 0755):递归创建目录。
如果子目录创建失败或者已经存在,会抛出一个 OSError 的异常。
if not os.path.isdir(dir):
try:
os.makedirs(dir, 0755)
except OSError, e:
print "Logger: Error adding file handler,", \
"can not create log directory (%s): %s" % (dir, e)
return
然后就是创建一个 FileHandler
对象,自定义日志格式, logger
日志对象加载 FileHandler
对象
#创建一个FileHandler对象,并捕获相应异常
#FileHandler:继承自StreamHandler。将日志信息输出到磁盘文件上。
try:
handler = logging.FileHandler(file)
except IOError, e:
print "Logger: Error adding file handler: %s" % (e)
return
自定义日志格式
handler.setFormatter(Logger.__formatter)
if log_level: # 修改 log_level
handler.setLevel(log_level)
logger日志对象加载FileHandler对象
Logger.logger.addHandler(handler)
3、add_error_file_handler(file)
方法:
这个方法很简单,功能就是实现将日志 error
和 critical
信息输出到指定磁盘文件上
通过调用方法刚才分析的方法 _add_file_handler(file, logging.ERROR)
实现。
设置日志级别 log_level = logging.ERROR
,目的是使得仅仅 error
和 critical
的日志信息才会被输出到指定文件上
def add_error_file_handler(file):
Logger._add_file_handler(file, logging.ERROR)
关于等级问题:上面的文章里已经简单叙述了各个等级之间的关系,以及对应打印输出的内容信息等。这里简单做了个实验测试一下
测试代码:
import logging # 引入logging模块
# 将信息打印到控制台上
logging.debug(u"debug")
logging.info(u"info")
logging.warning(u"warning")
logging.error(u"error")
logging.critical(u"critical")
控制台输出:
可以看出仅仅输出了后面三个等级,默认生成的 root logger 的 level 是 logging.WARNING
,低于该级别的就不输出了
4、add_syslog_handler(address)
方法:
将事件发送到远程系统日志
过程和前面相同:首先创建一个SysLogHandler,然后设置日志格式,最后logger日志对象加载SysLogHandler对象
def add_syslog_handler(address):
from logging.handlers import SysLogHandler
handler = SysLogHandler(address)
handler.setFormatter(logging.Formatter(Logger.SYSLOG_FORMAT))
Logger.logger.addHandler(handler)
下一篇继续分析 BackupManager.py
上一篇:OSSIM开源安全信息管理系统(六)
下一篇: