OSSIM开源安全信息管理系统(七)

2021SC@SDUSC



上周分析的代码部分主要为 Framework.py ,本周对其涉及调用的其他文件代码部分进行分析。

1、Framework.py 涉及到的其他类分析

1.1、简述

上周对 Framework 部分的主要源代码文件 Framework.py 的源码进行了简单的分析介绍,其中 Framework.py 导入并引用了很多其他的类,以及类方法。上周在分析 主要文件 Framework.py 的源码时,对于调用的其他类的方法,仅仅简单那看了一下这个类方法所实现的功能,返回的值等基本信息,并未对其实现过程,以及这个方法所属的类进行详细分析。所以本周的任务主要是对 Framework.py 文件中所引用的相关类以及相关类方法的实现代码进行详细分析,分析其方法实现过程与原理。


1.2、类关系图

使用 UML 类图简单描述下 Framework.py 所涉及的各个类之间的关系

OSSIM开源安全信息管理系统(七)_第1张图片


1.3、Logger.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) 方法:

这个方法很简单,功能就是实现将日志 errorcritical 信息输出到指定磁盘文件上

通过调用方法刚才分析的方法 _add_file_handler(file, logging.ERROR) 实现。

设置日志级别 log_level = logging.ERROR ,目的是使得仅仅 errorcritical 的日志信息才会被输出到指定文件上

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")

控制台输出:

OSSIM开源安全信息管理系统(七)_第2张图片

可以看出仅仅输出了后面三个等级,默认生成的 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开源安全信息管理系统(六)
下一篇:

你可能感兴趣的:(2021SC@SDUSC,安全,安全架构,运维)