2021SC@SDUSC
上周开始对 framework.py 的相关联的其他类进行了分析,并且上周主要分析的是 logger.py ,这周开始对另一个重要的源代码文件 backupmanager.py 进行分析,也就是对 backupmanager 这个类进行分析
BackupManager 该类继承自 python 自带线程类 threading.Thread,该类主要功能为管理备份
threading.Thread简介:
Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。其中 _thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。而 threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
除了使用方法外,线程模块同样提供了 Thread 类来处理线程,Thread 类提供了以下方法:
首先继承自 python 的 threading.Thread
然后定义了两个变量:
/etc/ossim/framework/bksock.sock
,但是看了一下这个类后面的各个方法的代码,并没有发现任何有使用这个变量的代码片段,可能是在其他类中使用了该变量,等到后续遇到了再仔细看一下吧。这个文件就是以 .sock 为后缀的文件而已。UNIX 系统不以后缀区分文件类型,但为了方便,通常使用后缀来标识一下。.sock 文件极有可能是 UNIX 域套接字(UNIX domain socket),即通过文件系统(而非网络地址)进行寻址和访问的套接字class BackupManager(threading.Thread):
UPDATE_BACKUP_FILE = '/etc/ossim/framework/lastbkday.fkm'
LISTEN_SOCK = '/etc/ossim/framework/bksock.sock'
__inin__(self)
:
一个默认的构造器,用于声明一些类属性,并初始化类的属性,以及调用 threading.Thread.__init__(self)
初始化父类 threading.Thread
def __init__(self):
threading.Thread.__init__(self)
self.__myDB = OssimDB(_CONF[VAR_DB_HOST],
_CONF[VAR_DB_SCHEMA],
_CONF[VAR_DB_USER],
_CONF[VAR_DB_PASSWORD])
self.__myDB_connected = False
self.__keepWorking = True
self.__bkConfig = {
} #存储备份配置信息
self.__loadConfiguration()
self.__stopE = threading.Event()
self.__stopE.clear()
__loadConfiguration(self)
:
主要功能为加载备份管理器的相关配置,并使用数据库中的值进行更新。
def __loadConfiguration(self):
#从文件中读取备份的配置信息,存储在self.__bkConfig中
self.__loadBackupConfig()
连接数据库
if not self.__myDB_connected:
if self.__myDB.connect():
self.__myDB_connected = True
else:
logger.error("Can't connect to database")
return
从数据库中查询相关配置信息,判断配置信息,并更新相关配置信息
query = 'select * from config where conf like "%backup%"'
data = None
data = self.__myDB.exec_query(query)
tmpConfig = {
}
if data is not None:
for row in data:
if row['conf'] in ['backup_base', 'backup_day', 'backup_dir', 'backup_events', 'backup_store','frameworkd_backup_storage_days_lifetime', 'backup_hour']:
tmpConfig [row['conf']] = row['value']
for key, value in tmpConfig.iteritems():
if key == 'last_run':
continue
if key not in self.__bkConfig:
logger.info("Backup new config key: '%s' '%s'" % (key, value))
self.__bkConfig[key] = tmpConfig[key]
elif value != self.__bkConfig[key]:
logger.info('Backup Config value has changed %s=%s and old value %s=%s' % (key, value, key, self.__bkConfig[key]))
self.__bkConfig[key] = tmpConfig[key]
if not self.__bkConfig.has_key('last_run'):
self.__bkConfig['last_run'] = date(year=1,month=1,day=1)
if not self.__bkConfig.has_key('backup_day'):
self.__bkConfig['backup_day'] = 30
if not self.__bkConfig.has_key('frameworkd_backup_storage_days_lifetime'):
self.__bkConfig['frameworkd_backup_storage_days_lifetime'] = 5
self.__updateBackupConfigFile()
__updateBackupConfigFile(self)
:
主要实现功能为更新备份配置文件
def __updateBackupConfigFile(self):
try:
bk_configfile = open(BackupManager.UPDATE_BACKUP_FILE, "wb")
pickle.dump(self.__bkConfig, bk_configfile)
bk_configfile.close()
os.chmod(BackupManager.UPDATE_BACKUP_FILE,0644)
except Exception, e:
logger.error("Error dumping backup config update_file...:%s" % str(e))
__loadBackupConfig(self)
:
该函数主要功能为从文件中加载备份配置信息,并将备份配置内容信息存储到 __bkConfig
中
def __loadBackupConfig(self):
self.__bkConfig = {
}
首先判断 UPDATE_BACKUP_FILE = '/etc/ossim/framework/lastbkday.fkm'
文件是否存在
存在的话使用 pickle.load(bk_configfile)
反序列化读取文件中存储的对象
if os.path.isfile(BackupManager.UPDATE_BACKUP_FILE):
try:
bk_configfile = open(BackupManager.UPDATE_BACKUP_FILE)
该函数对文件中存储的对象进行反序列化,使用的模块为 pickle,是 python 的一个重要模块。
pickle 提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。
pickle 模块只能在 Python 中使用,python 中几乎所有的数据类型(列表,字典,集合,类等)都可以用 pickle来序列化,
因为这里用到了 python 的序列化与反序列化的相关知识,所以对这方面内容进行了简单的查询学习和了解。关于 python 序列化函数的简单介绍:
pickle.dump(obj, file[, protocol])
:
pickle.load(file)
:
self.__bkConfig = pickle.load(bk_configfile)
bk_configfile.close()
isinstance()
函数用来判断一个对象是否是一个已知的类型,类似于 type()。
下面部分代码主要就是判断反序列化得到的对象是否为一个字典类型(dict)
if not isinstance(self.__bkConfig, dict):
if 判断如果不是字典类型数据,则报告相应警告提示信息,然后从数据库加载配置信息
logger.warning("Error loading backup configuration file.")
logger.info("New configuration will be loaded from database")
self.__bkConfig = {
}
except Exception, e:
logger.warning("Error loading backup configuration file...:%s" % str(e))
logger.info("New configuration will be loaded from database")
self.__bkConfig = {
}
purgeOldBackupfiles(self)
:
该方法主要功能为清除旧备份文件。
def purgeOldBackupfiles(self):
backup_files = []
bkdays = 5
try:
#从配置信息中读取backup_day
bkdays = int(_CONF[VAR_BACKUP_DAYS_LIFETIME])
except ValueError,e:
logger.warning("Invalid value for backup_day in config table")
timedelta
:该函数表示两个时间的间隔
参数可选、默认值都为0:
datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
通过 while 循环,分别对每天的备份进行处理,在相应目录下,创建 /insert-[经过格式化的时间字符串 today].sql.gz
today = datetime.now() - timedelta(days=1)
while bkdays>0:
dt = today.date().isoformat()
dtstr = "%s" % dt
dtstr = dtstr.replace('-','')
str_insert = '%s/insert-%s.sql.gz' % (self.__bkConfig['backup_dir'], dtstr)
str_delete = '%s/delete-%s.sql.gz' % (self.__bkConfig['backup_dir'], dtstr)
backup_files.append(str_insert)
backup_files.append(str_delete)
bkdays = bkdays - 1
today = today -timedelta(days=1)
glob 是 python 自带的一个操作文件的相关模块,用它可以查找符合特定规则的文件路径名。模块功能不是很多,还是比较容易掌握的。
使用该模块查找文件,只需要用到: “*”, “?”, “[]”这三个匹配符;
因为这里用到了这个模块里面的方法,来实现文件路径名的查找,所以先简单学习介绍一下这个模块。
这里主要实现通过 os.unlink()
方法来删除一些过时的备份文件,如果文件是一个目录则返回一个错误。 os.unlink()
是 python 用来删除指定路径文件的一个函数。
for bkfile in glob.glob(os.path.join(self.__bkConfig['backup_dir'], '[insert|delete]*.sql.gz')):
bkfilep=os.path.join(self.__bkConfig['backup_dir'], bkfile)
if bkfilep not in backup_files:
logger.info("Removing outdated backfile :%s" % bkfilep)
try:
os.unlink(bkfilep)
except Exception,e:
logger.error("Error removing outdated files: %s" % bkfilep)
上一篇:
下一篇: