本文實例實現的功能是監控一個文件或目錄的變化,如果有變化,把文件上傳備份至備份主機,并且要監控上傳過程是否有問題等,具體內容如下
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
|
#!/usr/bin/env python #coding=utf-8 # #Status wd gs/ccs sql file changed #文件有變化上傳至備份主機,上傳之后驗證文件是否正確 # 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): f = 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() |
以上就是本文的全部內容,希望對大家的學習有所幫助。