python监控文件或目录变化

简介:

  我们经常会遇到监控一个文件或目录的变化,如果有变化,把文件上传备份至备份主机,并且我们还要监控上传过程是否有问题等,根据此需求,查阅了相关的一些材料,编写如下脚本实现这个功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python
#coding=utf-8
#######################
#
#Status wd gs/ccs sql file changed
#date:2013-08-26  王伟
#文件有变化上传至备份主机,上传之后验证文件是否正确
#
#######################
import  paramiko,os,sys,datetime,time,MySQLdb
from  pyinotify  import  WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE,IN_MODIFY
'''
CREATE TABLE `wddel_log.status_sql` (
   `ip` varchar(16) NOT NULL COMMENT '机器IP',
   `tar_name` varchar(50) NOT NULL COMMENT '备份文件名字',
   `md5` varchar(50) NOT NULL COMMENT '备份文件MD5',
   `flag` int(2) NOT NULL COMMENT '0:成功;1:失败',
   `error_log` varchar(100) NOT NULL COMMENT '错误日志',
   `uptime` datetime NOT NULL COMMENT '更新时间',
   KEY `ip` (`ip`),
   KEY `uptime` (`uptime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8''' #日志表创建脚本
GM_path = '/home/asktao/'
center_hostname = '192.168.1.100'
center_username = 'root'
center_password = '123456'
center_port = 63008
def  log2db(ip,tar_name,md5,flag,error = '0' ): #删除日志入库
     try :
         tar_name  =  os.path.split(tar_name)[ 1 ]
         now   =  time.strftime( "%Y-%m-%d %H:%M:%S" )
         conn  =  MySQLdb.connect(host  =  '192.168.1.104' ,user  =  'root' ,passwd  =  '1q2w3e4r' ,charset = 'utf8' ,connect_timeout = 20 )
         cursor  =  conn.cursor()
         sql  =  "SELECT ip FROM wddel_log.status_sql WHERE ip='%s'"  %  ip
         cursor.execute(sql)
         res  =  cursor.fetchall()
         if  len (res) = = 0 :
             inster_sql  =  "insert into wddel_log.status_sql VALUES('%s','%s','%s',%s,'%s','%s')"  %  (ip,tar_name,md5,flag,error,now)
             cursor.execute(inster_sql)
             conn.commit()
         else :
             update_sql  =  "UPDATE wddel_log.status_sql SET md5='%s',flag='%s',error_log='%s',uptime='%s' WHERE ip='%s'"  %  (md5,flag,error,now,ip)
             cursor.execute(update_sql)
             conn.commit()
         cursor.close()
         conn.close()
     except  Exception,e:
         print  e
def  find_ip(): #获取本地eth0的IP地址
     ip  =  os.popen( "/sbin/ip a|grep 'global eth0'" ).readlines()[ 0 ].split()[ 1 ].split( "/" )[ 0 ]
     if  "192.168."  in  ip:
         ip  =  os.popen( "/sbin/ip a|grep 'global eth1'" ).readlines()[ 0 ].split()[ 1 ].split( "/" )[ 0 ]
     return  ip
def  md5sum(file_name): #验证sql打包文件的MD5
     if  os.path.isfile(file_name):
         =  open (file_name, 'rb' )
         py_ver  =  sys.version[: 3 ]
         if  py_ver  = =  "2.4" :
             import  md5 as hashlib
         else :
             import  hashlib
             md5  =  hashlib.md5(f.read()).hexdigest()
             f.close()
             return  md5
     else :
         return  0
def  center_md5(file_name): #上传至备份中心的文件的MD5
     try :
         s = paramiko.SSHClient()
         s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         s.connect(hostname  =  center_hostname,port = center_port,username = center_username, password = center_password)
         conm  =  "/usr/bin/md5sum %s"  %  file_name
         stdin,stdout,stderr = s.exec_command(conm)
         result  =  stdout.readlines()[ 0 ].split()[ 0 ].strip()
         s.close()
         return  result
     except  Exception,e:
         return  e
def  back_file(ip,tar_name,tar_md5): #上传文件到备份中心
     remote_dir = '/data/sql'
     file_name = os.path.join(remote_dir,os.path.split(tar_name)[ 1 ])
     try :
         t = paramiko.Transport((center_hostname,center_port))
         t.connect(username = center_username,password = center_password)
         sftp = paramiko.SFTPClient.from_transport(t)
         sftp.put(tar_name,file_name)
         t.close()
         #print "%s back_file OK" % tar_name
         os.remove(tar_name)
         remot_md5 = center_md5(file_name)
         if  remot_md5  = =  tar_md5:
             log2db(ip,tar_name,tar_md5, 0 )
         else :
             log2db(ip,tar_name,tar_md5, 1 , 'remot_md5!=tar_md5' )
     except  Exception,e:
         #print "connect error!"
         log2db(ip,tar_name,tar_md5, 1 ,e)
         os.remove(tar_name)
def  back_sql(): #执行备份
     ip  =  find_ip()
     tar_name  =  "/tmp/%s.tar.gz"  %  ip
     sql_conn  =  "/usr/bin/find %s -type f  -name '*.sql'|/usr/bin/xargs /bin/tar zcvPf %s"  %  (GM_path,tar_name)
     sql_tar  =  os.popen(sql_conn).readlines()
     tar_md5  =  md5sum(tar_name)
     if  tar_md5 ! =  0 :
         back_file(ip,tar_name,tar_md5)
     else :
         error_log  =   "%s not find"  %  tar_name
         log2db(ip,tar_name,tar_md5, 0 ,error_log)
class  PFilePath(ProcessEvent): #文件变化的触发
     def  process_IN_CREATE( self , event):
         if  os.path.splitext(event.name)[ 1 = =  ".sql" :
             text  =  "Create file: %s "  %  os.path.join(event.path, event.name)
             #print text
             back_sql()
     def  process_IN_MODIFY( self , event):
         if  os.path.splitext(event.name)[ 1 = =  ".sql" :
             text  =  "Modify file: %s "  %  os.path.join(event.path, event.name)
             #print text
             back_sql()
def  FSMonitor(): #主监控函数
     back_sql() #运行脚本先备份sql文件
     wm  =  WatchManager()
     mask  =  IN_CREATE |IN_MODIFY
     notifier  =  Notifier(wm, PFilePath())
     wdd  =  wm.add_watch(GM_path, mask, rec = True )
     print  'now starting monitor %s'  %  (GM_path)
     while  True :
         try  :
             notifier.process_events()
             if  notifier.check_events():
                 notifier.read_events()
         except  KeyboardInterrupt:
             notifier.stop()
             break
if  __name__  = =  "__main__" :
     FSMonitor()

   此脚本中主要用到paramiko和pyinotify模块,关于paramiko的讲解可以参见:http://wangwei007.blog.51cto.com/68019/1058726一文,pyinotify的用法可以参见官方文档:https://github.com/seb-m/pyinotify/wiki/Events-types



本文转自 lover00751CTO博客,原文链接:http://blog.51cto.com/wangwei007/1284038,如需转载请自行联系原作者


相关文章
|
5天前
|
计算机视觉 Python
如何使用Python将TS文件转换为MP4
本文介绍了如何使用Python和FFmpeg将TS文件转换为MP4文件。首先需要安装Python和FFmpeg,然后通过`subprocess`模块调用FFmpeg命令,实现文件格式的转换。代码示例展示了具体的操作步骤,包括检查文件存在性、构建FFmpeg命令和执行转换过程。
29 7
|
2月前
|
安全 Linux 数据安全/隐私保护
python知识点100篇系列(15)-加密python源代码为pyd文件
【10月更文挑战第5天】为了保护Python源码不被查看,可将其编译成二进制文件(Windows下为.pyd,Linux下为.so)。以Python3.8为例,通过Cython工具,先写好Python代码并加入`# cython: language_level=3`指令,安装easycython库后,使用`easycython *.py`命令编译源文件,最终生成.pyd文件供直接导入使用。
python知识点100篇系列(15)-加密python源代码为pyd文件
|
1月前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
44 2
|
1月前
|
中间件 Docker Python
【Azure Function】FTP上传了Python Function文件后,无法在门户页面加载函数的问题
通过FTP上传Python Function至Azure云后,出现函数列表无法加载的问题。经排查,发现是由于`requirements.txt`中的依赖包未被正确安装。解决方法为:在本地安装依赖包到`.python_packages/lib/site-packages`目录,再将该目录内容上传至云上的`wwwroot`目录,并重启应用。最终成功加载函数列表。
|
2月前
|
Java Python
> python知识点100篇系列(19)-使用python下载文件的几种方式
【10月更文挑战第7天】本文介绍了使用Python下载文件的五种方法,包括使用requests、wget、线程池、urllib3和asyncio模块。每种方法适用于不同的场景,如单文件下载、多文件并发下载等,提供了丰富的选择。
|
2月前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
2月前
|
JSON 数据格式 Python
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
这篇文章介绍了一个Python脚本,用于统计TXT或JSON文件中特定单词的出现次数。它包含两个函数,分别处理文本和JSON文件,并通过命令行参数接收文件路径、目标单词和文件格式。文章还提供了代码逻辑的解释和示例用法。
53 0
Python实用记录(十四):python统计某个单词在TXT/JSON文件中出现的次数
|
4月前
|
SQL JSON 关系型数据库
n种方式教你用python读写excel等数据文件
n种方式教你用python读写excel等数据文件
|
6月前
|
存储 Python 内存技术
python WAV音频文件处理—— (1)读写WAV文件
python WAV音频文件处理—— (1)读写WAV文件
164 14
|
7月前
|
数据挖掘 索引 Python
Python 读写 Excel 文件
Python 读写 Excel 文件
168 0
下一篇
DataWorks