Package sysmon :: Module system
[hide private]
[frames] | no frames]

Source Code for Module sysmon.system

  1  ######################################################################### 
  2  # YASMon - Yet Another System Monitor                                   # 
  3  # Copyright (C) 2010  Scott Lawrence                                    # 
  4  #                                                                       # 
  5  # This program is free software: you can redistribute it and/or modify  # 
  6  # it under the terms of the GNU General Public License as published by  # 
  7  # the Free Software Foundation, either version 3 of the License, or     # 
  8  # (at your option) any later version.                                   # 
  9  #                                                                       # 
 10  # This program is distributed in the hope that it will be useful,       # 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of        # 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         # 
 13  # GNU General Public License for more details.                          # 
 14  #                                                                       # 
 15  # You should have received a copy of the GNU General Public License     # 
 16  # along with this program.  If not, see <http://www.gnu.org/licenses/>. # 
 17  ######################################################################### 
 18   
 19  """Provides an interface to an abstract system 
 20   
 21  """ 
 22   
 23  from threading import Lock,Timer 
 24  import re 
 25  import callback 
26 27 -class System():
28 """Represents an abstract system and implements some basic logic. 29 30 """ 31
32 - def __init__(self,name="no-name"):
33 self.lock=Lock() 34 self._uptime=Uptime.null() 35 self._processors=[] 36 self._memory=Memory.null() 37 self._filesystems=[] #filesystems (to measure space usage) 38 self._drives=[] #drives (to measure i/o usage) 39 self._netconns=[] #network connections 40 self._processlist=ProcessList.null() 41 self._delay=5 #the update interval in seconds 42 self._callback=callback.SysmonCallback() 43 self._timers=[] 44 self._name=name
45
46 - def name(self):
47 """Returns the identifying name of the system. 48 """ 49 return self._name
50
51 - def run(self):
52 """Runs the system monitor. 53 54 All parts are updated immediately, and then again at the 55 interval specified in the parts' configuration. 56 """ 57 for part in self.parts(): 58 part.update()
59
60 - def stop(self):
61 """Stops the system monitor. 62 63 The monitor may safely be stopped and run and indefinite 64 number of times. 65 """ 66 for part in self.parts(): 67 part.timer.cancel()
68
69 - def acquire(self):
70 """Acquire the lock object hidden in this system, 71 """ 72 self.lock.acquire()
73
74 - def release(self):
75 """Release the lock object hidden in this system. 76 """ 77 self.lock.release()
78
79 - def update(self):
80 """Performs an update of the system. 81 82 These updates are done periodically (depending on the delay 83 setting), so there is ordinarily no reason to call it from 84 outside of the system. 85 86 Implementation note: this method updates the entire 87 system. Since each part may have its own delay interval, the 88 parts are responsible for calling their own update methods 89 independently of the system. In other words, this method is 90 ordinarily never called. 91 """ 92 for part in self.parts(): 93 part.update()
94
95 - def set_delay(self,interval):
96 """Sets the update interval after which information is 97 refreshed, in seconds. This may be a fraction. 98 """ 99 self._delay=interval
100
101 - def delay(self):
102 """Returns the update interval after which information is 103 refreshed in seconds. 104 """ 105 return self._delay
106
107 - def set_callback(self,callback):
108 """Sets the callback class to be used 109 110 Generally, this function is not needed, as a callback class is 111 usually created that can be used without setting a new one. 112 """ 113 self._callback=callback
114
115 - def callback(self):
116 """Returns the callback class being used 117 """ 118 return self._callback
119
120 - def parts(self):
121 """Returns a list of all parts of the system. 122 """ 123 return (self._processors+ 124 [self._memory]+ 125 self._filesystems+ 126 self._drives+ 127 [self._uptime]+ 128 self._netconns+ 129 [self._processlist])
130
131 - def set_uptime(self,uptime):
132 """Sets the system's uptime object. 133 """ 134 uptime.set_system(self) 135 self._uptime=uptime
136
137 - def uptime(self):
138 """Returns the system's uptime object. 139 """ 140 return self._uptime
141
142 - def add_processor(self,processor):
143 """Adds a processor to the system. 144 """ 145 processor.set_system(self) 146 self._processors+=[processor]
147
148 - def processors(self):
149 """Returns a list of processors in the system. 150 """ 151 return self._processors
152
153 - def processor(self,name):
154 """Returns the processor with the specified name, or None if 155 there is none. 156 """ 157 for p in self.processors(): 158 if p.name()==name: 159 return p 160 return None
161
162 - def set_memory(self,memory):
163 """Sets the system's memory bank. 164 """ 165 memory.set_system(self) 166 self._memory=memory
167
168 - def memory(self):
169 """Returns the system's memory bank. 170 """ 171 return self._memory
172
173 - def add_drive(self,drive):
174 """adds a drive to the system 175 """ 176 drive.set_system(self) 177 self._drives+=[drive]
178
179 - def drives(self):
180 """Returns a list of all physical drives in the system. 181 """ 182 return self._drives
183
184 - def add_filesystem(self,filesystem):
185 """adds a filesystem to the system 186 """ 187 filesystem.set_system(self) 188 self._filesystems+=[filesystem]
189
190 - def filesystems(self):
191 """Returns a list of all filesystems in the system. 192 """ 193 return self._filesystems
194
195 - def add_networkconnection(self,nc):
196 """Adds a network connection to the system. 197 """ 198 nc.set_system(self) 199 self._netconns+=[nc]
200
201 - def networkconnections(self):
202 """Returns a list of all network connections in the system 203 """ 204 return self._netconns
205
206 - def set_processlist(self,processlist):
207 """Sets the object representing the process list. 208 """ 209 processlist.set_system(self) 210 self._processlist=processlist
211
212 - def processlist(self):
213 """Returns the object representing the process list. 214 """ 215 return self._processlist
216
217 218 -class SystemPart():
219 """Represents a part of a system. 220 """
221 - def __init__(self):
222 self._delay=None 223 self._system=None 224 self.timer=None
225 226 @staticmethod
227 - def null():
228 """Returns a null part to be used when no real part is 229 available. 230 """ 231 return SystemPart()
232
233 - def update(self):
234 """Performs an update of the part's information. 235 236 This method is called periodically (depending on the delay 237 setting), so there is ordinarily no reason to call it from 238 outside of the system. 239 """ 240 #make sure we have a valid delay 241 if not self.delay(): 242 self.set_delay(self.system().delay()) 243 244 245 #acquire the lock 246 self.system().acquire() 247 #do the wuhk 248 self.do_update() 249 250 #don't set the timer if we're weird 251 if not self.delay()==-1: 252 #reset the timer 253 self.timer=Timer(self.delay(),self.update) 254 self.timer.daemon=True 255 self.timer.start() 256 #release the lock 257 self.system().release()
258
259 - def callback(self):
260 return self.system().callback()
261
262 - def do_update(self):
263 """Perform the actual update. 264 265 Part implementations should override this method. 266 """ 267 self.system().callback().call("misc.updated",self)
268
269 - def set_delay(self,delay):
270 """Sets the delay between updates. 271 """ 272 self._delay=delay
273
274 - def delay(self):
275 """Returns the current delay between updates. 276 """ 277 return self._delay
278
279 - def set_system(self,system):
280 """Sets the system that this part is in. 281 282 A part may only be in one system at once - if a part is in two 283 systems at once IRL, it may be best to have a representation 284 of it in each system, or to make it its own system. 285 """ 286 self._system=system
287
288 - def system(self):
289 return self._system
290
291 292 -class Uptime(SystemPart):
293 """Represents the uptime of a system. 294 """
295 - def uptime(self):
296 """Returns the uptime in seconds. 297 """ 298 return 0
299
300 -class Processor(SystemPart):
301 """Represents a single abstract processor. 302 """
303 - def name(self):
304 """An appropriate name for the processor, like cpu4. 305 """ 306 return "cpu"
307
308 - def modelname(self):
309 """The modelname of this processor. 310 """ 311 return self.dict()['model name']
312
313 - def max_freq(self):
314 """The maximum frequency of this processor, in MHz. 315 """ 316 mf=self.freq() #if nothing else is found 317 #check the model name 318 mn=self.modelname() 319 match=re.search('([0-9.]+)GHz',mn) 320 if match: 321 mf=float(match.group(1))*1000 322 return float(mf)
323
324 - def freq(self):
325 """The current operating frequency of this processor, in MHz. 326 """ 327 return self.dict()['cpu MHz']
328
329 - def usage(self):
330 """The current usage of this processor, as a fraction. 331 """ 332 return float(self.dict()['usage'])
333
334 - def dict(self):
335 """Returns a dictionary with a massive amount of 336 meta-information, by string. 337 338 Most implementations will take this directly out of 339 /proc/cpuinfo. It is generally bad form to use this directly 340 in an application. 341 """ 342 return dict()
343
344 345 -class Memory(SystemPart):
346 """Represents a memory (RAM) bank. 347 """
348 - def total_memory(self):
349 """Returns the total amount of memory, in bytes. 350 """ 351 return self.dict()['MemTotal']
352
353 - def free_memory(self):
354 """Returns the amount of completely free memory, in bytes. 355 356 Generally, it's better to use unused_memory, since 357 free_memory doesn't count caching and other such "essentially 358 free" types of memory. 359 """ 360 return self.dict()['MemFree']
361
362 - def active_memory(self):
363 """Returns the number of bytes of active memory. 364 """ 365 return self.dict()['Active']
366
367 - def inactive_memory(self):
368 """Returns the amount of inactive memory, in bytes. 369 """ 370 return self.dict()['Inactive']
371
372 - def unused_memory(self):
373 """Returns the amount of unused memory, in bytes. 374 """ 375 return self.total_memory()-self.active_memory()
376
377 - def total_swap(self):
378 """Returns the total amount of swap, in bytes. 379 """ 380 return self.dict()['SwapTotal']
381
382 - def free_swap(self):
383 """Returns the amount of free swap, in bytes. 384 """ 385 return self.dict()['SwapFree']
386
387 - def dict(self):
388 """Returns a dictionary with a massive amount of 389 meta-information, by string. 390 391 Most implementations will take this directly out of 392 /proc/meminfo. It is generally bad form to use this in an 393 application. 394 """ 395 return dict()
396
397 398 -class Filesystem(SystemPart):
399 """Represents a filesystem. 400 """
401 - def size(self):
402 """Returns the size, in bytes, of the filesystem. 403 """ 404 return 0
405
406 - def used(self):
407 """Returns the amount of used space, in bytes, of the 408 filesystem. 409 """ 410 return 0
411
412 - def available(self):
413 """Returns the available space, in bytes, of the filesystem. 414 """ 415 return self.size()-self.used()
416
417 - def device(self):
418 """Returns the device name (the relative path from /dev). 419 """ 420 pass
421
422 - def mount_point(self):
423 """Returns the mount point of the drive, or None if not 424 mounted. 425 """ 426 pass
427
428 - def mounted(self):
429 """Returns True if the drive is mounted, or False otherwise. 430 """ 431 return self.mount_point()==None
432
433 434 -class Drive(SystemPart):
435 """Represents a physical drive. 436 """ 437 pass
438
439 -class ProcessList(SystemPart):
440 """Represents a list of processes. 441 """ 442 pass
443
444 445 -class NetworkConnection(SystemPart):
446 """Represents a single network connection 447 """ 448 pass
449
450 451 -class Process:
452 """Represents a single process 453 """ 454 pass
455
456 457 -class Server:
458 """Represents running server software (sshd, httpd, etc...) 459 """ 460 pass
461