zephir.monitor.agents.systeme

Package zephir :: Package monitor :: Package agents :: Module systeme |
[frames] | no frames]

# Source Code for Module zephir.monitor.agents.systeme

      1  # -*- coding: UTF-8 -*-
      2  ###########################################################################
      3  # Eole NG - 2007
      4  # Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
      5  # Licence CeCill  cf /root/LicenceEole.txt
      6  # eole@ac-dijon.fr
      7  ###########################################################################
      8
      9  """
     10  Agents zephir pour Information Système
     11  """
     12
     13  from zephir.monitor.agentmanager.agent import MultiRRDAgent
     14  from zephir.monitor.agentmanager import status
     15  from zephir.monitor.agentmanager.data import TableData, HTMLData
     16
     17  from twisted.internet.utils import getProcessOutput
     18  import os
     19
     20  SECONDS_PER_DAY = 3600*24
     21
     22
     23 -def _mega(val):
     24      """ transfo de la valeur passée (string en octets) en Mo
     25      """
     26      return (int(val)/1024/1024)
     27
     28 -def _pourcent(use, tot):
     29      """ calcul du pourcentage de mémoire utilisée
     30      """
     31      #return (str(int(use)*100/int(tot))+"%")
     32      if int(tot) != 0:
     33          return (int(int(use)*100/int(tot)))
     34      else:
     35          return 0
     36
     37 -def _stats(x):
     38      return "%.1f" % x
     39
     40 -class SysInfo(MultiRRDAgent):
     41      """
     42      Bilan de l'etat de la memoire
     43      présentation en tableau
     44      """
     45
     46 -    def __init__(self, name, **params):
     47          MultiRRDAgent.__init__(self, name, **params)
     48          self.fich = "/proc/meminfo"
     49          self.swap_pourcent = 0
     50          self.kernel_version = ""
     51          self.table = TableData([
     52              ('name', 'Type', {'align':'right'}, None),
     53              ('perc', 'utilisation', {'align':'right'}, None),
     54              ('free', 'libre', {'align':'right'}, None),
     55              ('used', 'utilisé', {'align':'right'}, None),
     56              ('size', 'taille', {'align':'right'}, None) ])
     57          self.table2 = TableData([
     58              ('name', ' ', {'align':'left'}, None),
     59              ('value', 'valeur', {'align':'right'}, None)])
     60
     61 -    def init_data(self, archive_dir):
     62          """on initialise les archives rrd, et on définit
     63          la liste des données"""
     64          title1 = HTMLData("<h3>Information processeur<h3>")
     65          title2 = HTMLData("<h3>Informations mémoire<h3>")
     66          title3 = HTMLData("<h3>Historique CPU/mémoire<h3>")
     67          self.data.extend([title1, self.table2, title2, self.table, title3])
     68          MultiRRDAgent.init_data(self,archive_dir)
     69          #self.data.extend([title3, self.table2])
     70
     71 -    def measure(self):
     72          self.dico = {}
     73          if os.path.exists('/etc/eole/eolevz'):
     74              self.measure_mem_eolevz()
     75          else:
     76              self.measure_mem()
     77          self.measure_load_rrd()
     78          data = self.measure_proc()
     79          return data
     80
     81 -    def measure_mem_eolevz(self):
     82          """calcul de la memoire pour une machine virtuelle eolevz
     83          /proc/user_beancounters
     84          """
     85          out = file('/proc/user_beancounters')
     86          res = out.read().strip()
     87          out.close()
     88          statistics = []
     89          # total des allocations refusées
     90          failcnt = 0
     91          for line in res.split('\n')[2:]:
     92              data=line.split()
     93              failcnt += int(data[-1])
     94              if data[0] == 'privvmpages':
     95                  mem_used = int(data[1])
     96                  mem_total = int(data[3])
     97          # mémoire disponible : privvmpage parameter - mémoire disponible pour allocation
     98          # mem totale : 4e colonne de privvmpages * 4096 (barrier)
     99          # mem utilisée : 2e colonne (held)
    100          mem_phys = {'name' : 'allouée (machine virtuelle)',
    101                   'perc' : str(_pourcent(mem_used,mem_total))+" %",
    102                   'free' : str(_mega((mem_total - mem_used) * 4096))+" Mo",
    103                   'used' : str(_mega(mem_used*4096))+" Mo",
    104                   'size' : str(_mega(mem_total*4096))+" Mo",
    105                  }
    106          self.measure_data['physique'] = mem_phys['perc']
    107          self.measure_data['physique_total'] = mem_phys['size']
    108          self.measure_data['physique_used'] = mem_phys['used']
    109          self.measure_data['physique_free'] = mem_phys['free']
    110          self.measure_data['failcnt'] = failcnt
    111          statistics.append(mem_phys)
    112          self.dico['statistics'] = statistics
    113          self.dico['sperc'] = _pourcent(mem_used, mem_total)
    114          self.dico['failcnt'] = failcnt
    115
    116 -    def measure_mem(self):
    117          # mémoire
    118          out = file(self.fich)
    119          res = out.read().strip()
    120          out.close()
    121          res=res.split("\n")
    122          statistics = []
    123          self.mem_stats = {}
    124          for line in res:
    125              data=line.split()
    126              self.mem_stats[data[0][:-1]]=data[1]
    127
    128          mem_used = int(self.mem_stats['MemTotal']) - int(self.mem_stats['MemFree'])
    129          mem_phys = {'name' : 'physique',
    130                   'perc' : str(_pourcent(mem_used,self.mem_stats['MemTotal']))+" %",
    131                   'free' : str(_mega(int(self.mem_stats['MemFree'])*1024))+" Mo",
    132                   'used' : str(_mega((mem_used)*1024))+" Mo",
    133                   'size' : str(_mega(int(self.mem_stats['MemTotal'])*1024))+" Mo",
    134                  }
    135          self.measure_data['physique'] = mem_phys['perc']
    136          self.measure_data['physique_total'] = mem_phys['size']
    137          self.measure_data['physique_used'] = mem_phys['used']
    138          self.measure_data['physique_free'] = mem_phys['free']
    139          statistics.append(mem_phys)
    140          swap_used = int(self.mem_stats['SwapTotal']) - int(self.mem_stats['SwapFree'])
    141          mem_swap = {'name' : 'swap',
    142                   'perc' : str(_pourcent(swap_used,self.mem_stats['SwapTotal']))+" %",
    143                   'free' : str(_mega(int(self.mem_stats['SwapFree'])*1024))+" Mo",
    144                   'used' : str(_mega((swap_used)*1024))+" Mo",
    145                   'size' : str(_mega(int(self.mem_stats['SwapTotal'])*1024))+" Mo",
    146                  }
    147          # sentinelle : pourcentage de swap
    148          self.measure_data['swap'] = str(_pourcent(swap_used,self.mem_stats['SwapTotal']))
    149          self.measure_data['swap_total'] = mem_swap['size']
    150          self.measure_data['swap_used'] = mem_swap['used']
    151          self.measure_data['swap_free'] = mem_swap['free']
    152          self.swap_pourcent = int(self.measure_data['swap'])
    153          statistics.append(mem_swap)
    154          self.dico['statistics'] = statistics
    155          # stats pour graphes RRD
    156          # pourcentage de mémoire pour le cache
    157          self.dico['cached'] = _pourcent(self.mem_stats['Cached'],self.mem_stats['MemTotal'])
    158          # swapping
    159          swap = res[2].split()
    160          self.dico['sperc'] = _pourcent((int(self.mem_stats['SwapTotal']) - int(self.mem_stats['SwapFree'])), self.mem_stats['SwapTotal'])
    161
    162 -    def measure_proc(self):
    163          version = getProcessOutput('/bin/uname',
    164                                     args = ['-r'],
    165                                     env = {'LC_ALL': 'C'})
    166          version.addCallback(self.measure_uptime)
    167          return version
    168
    169 -    def measure_uptime(self, version):
    170          self.kernel_version = version.strip()
    171          uptime = getProcessOutput('/usr/bin/uptime',
    172                                     env = {'LC_ALL': 'C'})
    173          uptime.addCallback(self.measure_process)
    174          return uptime
    175
    176 -    def measure_process(self,result):
    177          lignes = result.splitlines()
    178          # On parse la sortie standard de la commande
    179          ligne = lignes[0]
    180          # nombre d'utilisateurs
    181          champs=ligne[:ligne.index('user')]
    182          users=str(int(champs[champs.rindex(',')+1:]))
    183          # on récupère le temps d'uptime
    184          uptime_str = champs[:champs.rindex(',')]
    185          uptime_str = uptime_str[champs.index('up')+2:].strip()
    186          statistics = []
    187          statistics.append( { 'name' : "Serveur en marche depuis",
    188                               'value': uptime_str.replace('day','jour') }
    189                           )
    190          statistics.append( { 'name' : "Nombre d'utilisateurs système connectés",
    191                               'value': users }
    192                           )
    193          # version du noyau
    194          statistics.append( { 'name' : "Version du noyau",
    195                               'value': self.kernel_version }
    196                           )
    197          if os.path.exists('/etc/eole/eolevz'):
    198              # echecs d'allocation (eolevz)
    199              statistics.append( { 'name' : "Echecs d'allocation mémoire",
    200                                   'value': self.dico['failcnt'] }
    201                               )
    202          self.dico['statistics2'] = statistics
    203          self.measure_data['kernel'] = self.kernel_version
    204          # sentinelle : uptime et version kernel
    205          f_uptime = open("/proc/uptime")
    206          uptime = f_uptime.read().strip().split()[0]
    207          f_uptime.close()
    208          self.measure_data['uptime'] = int(uptime.split('.')[0])
    209          return self.dico
    210
    211 -    def measure_load_rrd(self):
    212          # cpu load average
    213          f_load = open("/proc/loadavg")
    214          # on garde la moyenne sur 5 minutes
    215          loadavg = f_load.read().strip().split()
    216          f_load.close()
    217          self.measure_data['load1'] = loadavg[0]
    218          self.measure_data['load5'] = loadavg[1]
    219          self.measure_data['load15'] = loadavg[2]
    220          self.dico['load'] = loadavg[0]
    221
    222 -    def write_data(self):
    223          MultiRRDAgent.write_data(self)
    224          if self.last_measure is not None:
    225              self.table.table_data = self.last_measure.value['statistics']
    226              self.table2.table_data = self.last_measure.value['statistics2']
    227
    228 -    def check_status(self):
    229          """
    230          Warning en cas de Swap important
    231          Erreur en cas de Swap très important
    232          """
    233          if os.path.exists('/etc/eole/eolevz'):
    234              # alertes si allocations refusées
    235              try:
    236                  failcnt = self.last_measure.value['failcnt']
    237              except:
    238                  failcnt = 0
    239              #if failcnt > 100:
    240              #    return status.Error("Dépassement des ressources autorisées par OpenVZ")
    241              #elif failcnt > 0:
    242              #    return  status.Warn("Ressources refusées par OpenVZ à certains processus"
    243              if failcnt > 0:
    244                  return status.Error("Dépassement des ressources autorisées par OpenVZ")
    245          else:
    246              warn_step = 60
    247              error_step = 90
    248              if self.swap_pourcent >= error_step:
    249                  return status.Error("Swap utilisé à plus de %d%%" % error_step)
    250              elif self.swap_pourcent >= warn_step:
    251                  return status.Warn("Swap utilisé à plus de %d%%" % warn_step)
    252          return status.OK()
    253