Package zephir :: Package monitor :: Package agentmanager :: Module rrd
[frames] | no frames]

Source Code for Module zephir.monitor.agentmanager.rrd

  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  Interface orientée objet aux commandes RRDtool. 
 11   
 12  Il est conseillé de consulter la documentation des outils RRDtool: 
 13  L{http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/manual/index.html}. 
 14  """ 
 15   
 16  try: _ # localized string fetch function 
 17  except NameError: _ = str 
 18   
 19  from datetime import datetime, timedelta 
 20   
 21  import rrdtool, os 
 22   
 23  from zephir.monitor.agentmanager.util import TIME_ORIGIN, utcnow, log 
 24   
 25  DATASOURCE_TYPES = ['GAUGE', 'COUNTER', 'DERIVE', 'ABSOLUTE'] 
 26  CONSOLIDATION_FUNCTIONS = ['AVERAGE', 'MIN', 'MAX', 'LAST'] 
 27   
 28   
 29   
 30   
31 -def rrd_date_from_datetime(date):
32 if date is None: 33 timestamp = 'N' 34 else: 35 delta = date - TIME_ORIGIN 36 timestamp = '%d' % (delta.days*24*3600 + delta.seconds) 37 return timestamp
38 39 40 41
42 -class Database:
43 """Round-Robin Database (fichier C{.rrd}) 44 """ 45
46 - def __init__(self, rrdfile, step=60):
47 self.rrdfile = rrdfile # TODO path + basename without .rrd extension 48 self.step = step 49 self.datasources = [] 50 self.archives = [] 51 self.graphs = []
52 53
54 - def new_datasource(self, name, ds_type='GAUGE', heartbeat=None, 55 min_bound=None, max_bound=None):
56 """Ajoute une nouvelle I{datasource} (DS) à la base de données 57 """ 58 if heartbeat is None: 59 heartbeat = 2 * self.step 60 ds = Datasource(name, ds_type, heartbeat, min_bound, max_bound) 61 self.datasources.append(ds)
62 63
64 - def new_archive(self, rows, consolidation='AVERAGE', 65 steps=1, xfiles_factor=0):
66 """Ajoute une nouvelle archive I{round-robin} (RRA) à la base 67 de données. 68 """ 69 rra = Archive(rows, consolidation, steps, xfiles_factor) 70 self.archives.append(rra)
71 72
73 - def new_graph(self, pngname, vnamedefs, options):
74 """Ajoute un nouveau graphe à la base de données. 75 76 @param vnamedefs: {vname: (ds_name, CF)} 77 """ 78 #TODO default options 79 defs = [ "DEF:%s=%s:%s:%s" % (vname, self.rrdfile, ds, cf) 80 for vname, (ds, cf) in vnamedefs.items() ] 81 graph = Graph(pngname, defs, *options) 82 self.graphs.append(graph)
83 84
85 - def create(self):
86 """Crée le fichier C{.rrd} une fois que les datasources, 87 archives et graphes ont été configurés. 88 """ 89 # check if already created 90 if not os.path.exists(self.rrdfile): 91 begin = rrd_date_from_datetime(utcnow()) # - timedelta(seconds=10)) 92 args = [self.rrdfile, 93 "-b%s" % begin, 94 "-s%d" % self.step] 95 args += map(str, self.datasources) 96 args += map(str, self.archives) 97 #log.msg('RRDtool create: %s' % ' '.join(args)) 98 rrdtool.create(*args)
99 100
101 - def update(self, values, date=None): #values = list | dict
102 """Insère une nouvelle valeur dans la base de données. 103 104 @param values: soit une liste de valeurs (données dans l'ordre 105 de déclaration des champs), soit un dictionnaire C{{champ: 106 valeur}}. 107 """ 108 if date is None: 109 date = utcnow() 110 args = [self.rrdfile] 111 if type(values) is dict: 112 items = values.items() 113 args.append('-t' + ':'.join([ str(i[0]) for i in items])) 114 values = [ str(i[1]) for i in items] 115 args.append(rrd_date_from_datetime(date)+ ':' + ':'.join(values)) 116 #log.msg(' '.join(args)) 117 try: 118 rrdtool.update(*args) 119 except rrdtool.error, e: 120 log.msg(_('RRDtool warning: ') + str(e))
121 122
123 - def graph_all(self, additional_args = None):
124 """Génère ou met à jour tous les graphes de cette base de 125 données. 126 """ 127 for g in self.graphs: 128 g.graph(additional_args)
129
130 - def info(self):
131 """retourne des informations sur le fichier rrd associé 132 """ 133 if os.path.exists(self.rrdfile): 134 return rrdtool.info(self.rrdfile) 135 else: 136 return None
137
138 -class Datasource:
139
140 - def __init__(self, name, ds_type, heartbeat, 141 min_bound=None, max_bound=None):
142 assert not name is "" 143 assert ds_type in DATASOURCE_TYPES 144 assert not heartbeat is None 145 self.name = name 146 self.type = ds_type 147 self.heartbeat = heartbeat 148 self.min_bound = min_bound 149 self.max_bound = max_bound
150
151 - def __str__(self):
152 minb, maxb = "U", "U" 153 if self.min_bound is not None: minb = str(self.min_bound) 154 if self.max_bound is not None: maxb = str(self.max_bound) 155 return "DS:%(ds-name)s:%(DST)s:%(heartbeat)d:%(min)s:%(max)s" % { 156 'ds-name': self.name, 'DST': self.type, 157 'heartbeat': self.heartbeat, 158 'min': minb, 'max': maxb 159 }
160 161 162 163
164 -class Archive:
165
166 - def __init__(self, rows, consolidation='AVERAGE', 167 steps=1, xfiles_factor=0):
168 assert consolidation in CONSOLIDATION_FUNCTIONS 169 assert xfiles_factor >= 0.0 and xfiles_factor < 1 170 self.rows = rows 171 self.consolidation = consolidation 172 self.steps = steps 173 self.xfiles_factor = xfiles_factor
174
175 - def __str__(self):
176 return "RRA:%(CF)s:%(xff)f:%(steps)d:%(rows)d" % { 177 'CF': self.consolidation, 'xff': self.xfiles_factor, 178 'steps': self.steps, 179 'rows': self.rows 180 }
181 182 183 184
185 -class Graph:
186
187 - def __init__(self, imgname, defs, *options):
188 self.imgname = imgname 189 self.defs = defs 190 self.options = list(options)
191 # self.options.append('-z') 192
193 - def graph(self, additional_args = None):
194 #log.msg("*** rrd.graph %s" % self.imgname) 195 args = [self.imgname] 196 args += map(str, self.defs) 197 args += self.options 198 if additional_args is not None: 199 args += additional_args 200 return rrdtool.graph(*args)
201 202 203 204 205 # def test_main(): 206 # test_support.run_unittest(UserStringTest) 207 208 # if __name__ == "__main__": 209 # test_main() 210