Naposledy aktivní 1 month ago

TVS Tools from my Smart Monitor

tvs_tools.py Raw
1#!/usr/bin/python
2#encoding:UTF-8
3
4import os, smtplib, shutil, syslog, subprocess, cgi, commands, re, MySQLdb
5from datetime import date, timedelta
6from email.mime.multipart import MIMEMultipart
7from email.mime.text import MIMEText
8from htmlentitydefs import codepoint2name
9
10
11def toNotationUnit(value, base=10):
12 units = [ 'y','z','a','f','p','n','u','m',' ', 'k','M','G','T','P','E','Z','Y']
13 counter = 8
14 if base==10:
15 val = value if value > 0 else -value
16 if val < 1:
17 while ( val < 1.00) and not (counter == 0):
18 counter = counter - 1
19 val = val * 1000.0
20 else:
21 while ( val >= 1000 ) and not (counter == 16):
22 counter = counter + 1
23 val = val / 1000.0
24 return ( (val if value > 0 else -val) , units[counter])
25 elif base == 2:
26 val = value if value > 0 else -value
27 if val < 1:
28 while ( val < 1.00) and not (counter == 0):
29 counter = counter - 1
30 val = val * 1024.0
31 else:
32 while ( val >= 1024 ) and not (counter == 16):
33 counter = counter + 1
34 val = val / 1024.0
35 return ( (val if value > 0 else -val) , units[counter])
36
37
38def htmlentities(text):
39 text = (text).decode('utf-8')
40
41 from htmlentitydefs import codepoint2name
42 d = dict((unichr(code), u'&%s;' % name) for code,name in codepoint2name.iteritems() if code!=38) # exclude "&"
43 if u"&" in text:
44 text = text.replace(u"&", u"&amp;")
45 for key, value in d.iteritems():
46 if key in text:
47 text = text.replace(key, value)
48 return text
49
50def LOG(msg):
51 syslog.syslog(syslog.LOG_INFO, 'TVS Backup System: %s' %msg)
52
53def WARN(msg):
54 syslog.syslog(syslog.LOG_WARNING, 'TVS Backup System: %s' %msg)
55
56def ExecuteShell(cmd):
57 return subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read()
58
59def GetDiskList():
60 disks = filter(None, ExecuteShell('ls /sys/block/ |grep "sd\|xvd\|drbd"').split('\n'))
61 return [ ("/dev/%s" %d) for d in disks ]
62
63def GetSmartData(disk):
64 try :
65 smartok = commands.getstatusoutput('smartctl -a %s' %disk)[0]
66 if smartok == 0:
67 ModelFamily = ExecuteShell('smartctl -a %s | grep "Model Family" | cut -d: -f2' %disk).strip()
68 DeviceModel = ExecuteShell('smartctl -a %s | grep "Device Model" | cut -d: -f2' %disk).strip()
69 UserCapacity = ExecuteShell('smartctl -a %s | grep "User Capacity" | cut -d: -f2' %disk).strip()
70 DiskHealth = ExecuteShell('smartctl -a %s | grep "SMART overall-health" | cut -d: -f2' %disk).strip()
71 PowerOnHours = ExecuteShell('smartctl -a %s | grep "Power_On_Hours"' %disk).strip().split(' ')
72 PowerOnHours = PowerOnHours[len(PowerOnHours)-1]
73 PowerCycleCount = ExecuteShell('smartctl -a %s | grep "Power_Cycle_Count"' %disk).strip().split(' ')
74 PowerCycleCount = PowerCycleCount[len(PowerCycleCount)-1]
75 ReadErrorRate = ExecuteShell('smartctl -a %s | grep "Raw_Read_Error_Rate"' %disk).strip().split(' ')
76 ReadErrorRate = ReadErrorRate[len(ReadErrorRate)-1]
77 ReallocatedSector = ExecuteShell('smartctl -a %s | grep "Reallocated_Sector_Ct"' %disk).strip().split(' ')
78 ReallocatedSector = ReallocatedSector[len(ReallocatedSector)-1]
79
80 return { "Device": disk, "ModelFamily" : ModelFamily, "DeviceModel" : DeviceModel, "UserCapacity" : UserCapacity, "DiskHealth": DiskHealth, "PowerOnHours" : PowerOnHours, "PowerCycleCount" : PowerCycleCount, "ReadErrorRate" : ReadErrorRate, "ReallocatedSector" : ReallocatedSector }
81 except Exception, e:
82 WARN("Erro ao ler SMART (%s): %s" %(disk,e))
83 return None
84
85def Init3WareSmart():
86 try:
87 smartok = commands.getstatusoutput('smartctl -d 3ware,0 /dev/twa0')
88 except:
89 pass
90
91
92def Get3WareSmartData():
93 Init3WareSmart()
94 smlist = []
95 try :
96 for disk in range(0,12):
97 smartok = commands.getstatusoutput('smartctl -a -d 3ware,%s /dev/twa0' %disk)[0]
98 if smartok == 0:
99 ModelFamily = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "Model Family" | cut -d: -f2' %disk).strip()
100 DeviceModel = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "Device Model" | cut -d: -f2' %disk).strip()
101 UserCapacity = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "User Capacity" | cut -d: -f2' %disk).strip()
102 DiskHealth = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "SMART overall-health" | cut -d: -f2' %disk).strip()
103 PowerOnHours = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "Power_On_Hours"' %disk).strip().split(' ')
104 PowerOnHours = PowerOnHours[len(PowerOnHours)-1]
105 PowerCycleCount = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "Power_Cycle_Count"' %disk).strip().split(' ')
106 PowerCycleCount = PowerCycleCount[len(PowerCycleCount)-1]
107 ReadErrorRate = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "Raw_Read_Error_Rate"' %disk).strip().split(' ')
108 ReadErrorRate = ReadErrorRate[len(ReadErrorRate)-1]
109 ReallocatedSector = ExecuteShell('smartctl -a -d 3ware,%s /dev/twa0 | grep "Reallocated_Sector_Ct"' %disk).strip().split(' ')
110 ReallocatedSector = ReallocatedSector[len(ReallocatedSector)-1]
111
112 smlist.append({ "Device": "3ware:%s" %disk, "ModelFamily" : ModelFamily, "DeviceModel" : DeviceModel, "UserCapacity" : UserCapacity, "DiskHealth": DiskHealth, "PowerOnHours" : PowerOnHours, "PowerCycleCount" : PowerCycleCount, "ReadErrorRate" : ReadErrorRate, "ReallocatedSector" : ReallocatedSector })
113 return smlist
114 except Exception, e:
115 WARN("Erro ao ler SMART: %s" %(e))
116 return None
117
118
119def GetDiskUsage():
120 disks = []
121 try:
122 disk_data = filter(None, ExecuteShell('df -h |grep "/dev/sd\|/dev/xvd\|/dev/mapper/\|/dev/drbd"').split('\n'))
123 for disk in disk_data:
124 dsk = filter(None, disk.split(' '))
125 dk = { 'Device' : dsk[0], 'Size' : dsk[1], 'Used' : dsk[2], 'Free' : dsk[3], 'UsedPercent' : dsk[4], 'MountPoint' : dsk[5] }
126 disks.append(dk)
127 except Exception, e:
128 WARN("Erro ao ler dados de disco : %s" %(e))
129 return disks
130
131def GetNetDevData(dev):
132 devdata = { 'Device' : dev, "TX" : "(0.0 B)", "RX" : "(0.0 B)", "IP" : "Unknown", "Broadcast" : "Unknown", "NetMask" : "Unknown" }
133 try:
134 netstring = ExecuteShell('LANG="en_US.UTF-8" LANGUAGE="en" ifconfig %s' %dev)
135 devdata["IP"] = '.'.join(re.findall("inet addr:([0-9]*).([0-9]*).([0-9]*).([0-9]*)", netstring)[0])
136 devdata["Broadcast"] = '.'.join(re.findall("Bcast:([0-9]*).([0-9]*).([0-9]*).([0-9]*)", netstring)[0])
137 devdata["NetMask"] = '.'.join(re.findall("Mask:([0-9]*).([0-9]*).([0-9]*).([0-9]*)", netstring)[0])
138 tx = toNotationUnit(int(re.findall("TX bytes:([0-9]*)", netstring)[0]))
139 rx = toNotationUnit(int(re.findall("RX bytes:([0-9]*)", netstring)[0]))
140 devdata["TX"] = '(%s %sB)' %(round(tx[0]*100)/100.0, tx[1])
141 devdata["RX"] = '(%s %sB)' %(round(rx[0]*100)/100.0, rx[1])
142 except Exception, e:
143 WARN("Erro ao ler dados da rede (%s) : %s" %(dev, e))
144 return devdata
145
146def GetNetworkDevices():
147 devices = []
148 try:
149 data = filter(None, ExecuteShell('cat /proc/net/dev').split('\n'))
150 data.pop(0)
151 data.pop(0)
152 for i in data:
153 devices.append(i.split(':', 1)[0].strip())
154 except Exception, e:
155 WARN("Erro ao ler interfaces de rede : %s" %(e))
156 return devices
157
158def GetNetworkUsage():
159 devices = GetNetworkDevices()
160 usages = []
161 for device in devices:
162 usages.append( GetNetDevData(device) )
163
164 return usages
165
166def GetDevicesInfo():
167 devs = filter(None, ExecuteShell("lspci").split('\n'))
168 devs = [ d[8:] for d in devs ]
169 return devs
170
171def GetMemInfo():
172 '''
173 Retorna informações sobre a memória
174 '''
175 total = toNotationUnit(int(commands.getstatusoutput('cat /proc/meminfo |grep MemTotal | cut -d: -f2')[1].strip()[:-3]) * 1000)
176 free = toNotationUnit(int(commands.getstatusoutput('cat /proc/meminfo |grep MemFree | cut -d: -f2')[1].strip()[:-3]) * 1000)
177 swaptotal = toNotationUnit(int(commands.getstatusoutput('cat /proc/meminfo |grep SwapTotal | cut -d: -f2')[1].strip()[:-3]) * 1000)
178 swapfree = toNotationUnit(int(commands.getstatusoutput('cat /proc/meminfo |grep SwapFree | cut -d: -f2')[1].strip()[:-3]) * 1000)
179 return { "total" : "%s %sB" % (round(total[0]*100)/100, total[1]) , "free" : "%s %sB" % (round(free[0]*100)/100, free[1]), "swaptotal" : "%s %sB" % (round(swaptotal[0]*100)/100, swaptotal[1]), "swapfree" : "%s %sB" % (round(swapfree[0]*100)/100, swapfree[1]) }
180
181def GetUpTime():
182 uptime = float(commands.getstatusoutput('cat /proc/uptime')[1].split(' ')[0])
183 return str( timedelta(seconds=round(uptime)))
184
185def GetCPUInfo():
186 '''
187 Retorna os dados do processador
188 '''
189 cpu_family = commands.getstatusoutput('cat /proc/cpuinfo |grep "cpu family" |head -n1 |cut -d: -f2')[1].strip()
190 cpu_model = commands.getstatusoutput('cat /proc/cpuinfo |grep "model" |head -n1 |cut -d: -f2')[1].strip()
191 cpu_model_name = commands.getstatusoutput('cat /proc/cpuinfo |grep "model name" |head -n1 |cut -d: -f2')[1].strip()
192 cpu_stepping = commands.getstatusoutput('cat /proc/cpuinfo |grep "stepping" |head -n1 |cut -d: -f2')[1].strip()
193 cpu_cores = commands.getstatusoutput('cat /proc/cpuinfo |grep "cpu cores" |head -n1 |cut -d: -f2')[1].strip()
194 cpu_bogomips = commands.getstatusoutput('cat /proc/cpuinfo |grep "bogomips" |head -n1 |cut -d: -f2')[1].strip()
195 return { 'cpu_family' : cpu_family, 'cpu_model' : cpu_model, 'cpu_model_name' : cpu_model_name, 'cpu_stepping' : cpu_stepping, 'cpu_cores' : cpu_cores, 'cpu_bogomips' : cpu_bogomips }
196
197def GetDRBDInfo():
198 '''
199 Retorna informações sobre DRBD
200 '''
201 drbdinfo = {"conn" : {}}
202 try:
203 f = open("/proc/drbd")
204 data = f.read()
205 f.close()
206 drbdinfo["has"] = True
207 drbdinfo["drbdfile"] = data
208 data = filter(None, data.split("\n"))
209 lastdigit = None
210 for line in data:
211 block = line.split(":",1)
212 block[0] = block[0].strip()
213 block[1] = block[1].strip()
214 if 'srcversion' in block[0]:
215 drbdinfo["srcversion"] = block[1]
216 elif 'version' in block[0]:
217 drbdinfo["version"] = block[1]
218 elif block[0].isdigit():
219 lastdigit = int(block[0])
220 drbdinfo["conn"][lastdigit] = {}
221 d2 = filter(None, block[1].split(" "))
222 for d in d2:
223 o = d.split(":")
224 if len(o) > 1:
225 drbdinfo["conn"][lastdigit][o[0]] = o[1]
226 else:
227 if lastdigit == None:
228 WARN("Problemas ao ler partes do DRBD! - Linha: \n %s \n\n /proc/drbd : \n %s" %(line, "\n".join(data)))
229 else:
230 drbdinfo["conn"][lastdigit][block[0]] = block[1]
231 except:
232 drbdinfo["has"] = False
233 return drbdinfo
234
235def GetMySQLSlave(hostname,username,password):
236 '''
237 Retorna informações da sincronia do MySQL
238 '''
239 con = MySQLdb.connect(hostname,username,password)
240 cursor = con.cursor()
241 cursor.execute("SHOW SLAVE STATUS")
242 data = cursor.fetchall()[0]
243 desc = cursor.description
244
245 con.close()
246
247 output = {}
248 c = 0
249 for dc in desc:
250 output[dc[0]] = data[c]
251 c = c + 1
252
253 return output
254
255