A new doc condor_config.html is being added showing the condor configuration
[burt-test.git] / frontend / glideinFrontendMonitorAggregator.py
blobbc8481a8978657452d57af7ebbad67a2232ff40f
2 # Project:
3 # glideinWMS
5 # File Version:
6 # $Id: glideinFrontendMonitorAggregator.py,v 1.13 2011/02/10 21:35:31 parag Exp $
8 # Description:
9 # This module implements the functions needed
10 # to aggregate the monitoring fo the frontend
12 # Author:
13 # Igor Sfiligoi (Mar 19th 2009)
16 import time,string,os.path,copy
17 import timeConversion
18 import xmlParse,xmlFormat
19 import glideinFrontendMonitoring
22 ############################################################
24 # Configuration
26 ############################################################
28 class MonitorAggregatorConfig:
29 def __init__(self):
30 # The name of the attribute that identifies the glidein
31 self.monitor_dir="monitor/"
33 # list of entries
34 self.entries=[]
36 # name of the status files
37 self.status_relname="frontend_status.xml"
39 def config_frontend(self,monitor_dir,groups):
40 self.monitor_dir=monitor_dir
41 self.groups=groups
42 glideinFrontendMonitoring.monitoringConfig.monitor_dir=monitor_dir
45 # global configuration of the module
46 monitorAggregatorConfig=MonitorAggregatorConfig()
48 ###########################################################
50 # Functions
52 ###########################################################
54 status_attributes={'Jobs':("Idle","OldIdle","Running","Total"),
55 'Glideins':("Idle","Running","Total"),
56 'MatchedJobs':("Idle","EffIdle","OldIdle","Running","RunningHere"),
57 'MatchedGlideins':("Total","Idle","Running"),
58 'Requested':("Idle","MaxRun")}
60 ##############################################################################
61 # create an aggregate of status files, write it in an aggregate status file
62 # end return the values
63 def aggregateStatus():
64 global monitorAggregatorConfig
66 type_strings={'Jobs':'Jobs','Glideins':'Glidein','MatchedJobs':'MatchJob',
67 'MatchedGlideins':'MatchGlidein','Requested':'Req'}
68 global_total={'Jobs':None,'Glideins':None,'MatchedJobs':None,'Requested':None,'MatchedGlideins':None}
69 status={'groups':{},'total':global_total}
71 # initialize the RRD dictionary, so it gets created properly
72 val_dict={}
73 for tp in global_total.keys():
74 # type - status or requested
75 if not (tp in status_attributes.keys()):
76 continue
78 tp_str=type_strings[tp]
80 attributes_tp=status_attributes[tp]
81 for a in attributes_tp:
82 val_dict["%s%s"%(tp_str,a)]=None
84 nr_groups=0
85 for group in monitorAggregatorConfig.groups:
86 # load group status file
87 status_fname=os.path.join(os.path.join(monitorAggregatorConfig.monitor_dir,'group_'+group),
88 monitorAggregatorConfig.status_relname)
89 try:
90 group_data=xmlParse.xmlfile2dict(status_fname)
91 except IOError:
92 continue # file not found, ignore
94 # update group
95 try:
96 status['groups'][group]={'factories':group_data['factories']}
97 except KeyError, e:
98 # first time after upgrade factories may not be defined
99 status['groups'][group]={'factories':{}}
101 #nr_groups+=1
102 #status['groups'][group]={}
104 if group_data.has_key('total'):
105 nr_groups+=1
106 status['groups'][group]['total']=group_data['total']
108 for w in global_total.keys():
109 tel=global_total[w]
110 if not group_data['total'].has_key(w):
111 continue
112 #status['groups'][group][w]=group_data[w]
113 el=group_data['total'][w]
114 if tel==None:
115 # new one, just copy over
116 global_total[w]={}
117 tel=global_total[w]
118 for a in el.keys():
119 tel[a]=int(el[a]) #coming from XML, everything is a string
120 else:
121 # successive, sum
122 for a in el.keys():
123 if tel.has_key(a):
124 tel[a]+=int(el[a])
126 # if any attribute from prev. factories are not in the current one, remove from total
127 for a in tel.keys():
128 if not el.has_key(a):
129 del tel[a]
131 for w in global_total.keys():
132 if global_total[w]==None:
133 del global_total[w] # remove group if not defined
135 # Write xml files
136 updated=time.time()
137 xml_str=('<?xml version="1.0" encoding="ISO-8859-1"?>\n\n'+
138 '<VOFrontendStats>\n'+
139 get_xml_updated(updated,indent_tab=xmlFormat.DEFAULT_TAB,leading_tab=xmlFormat.DEFAULT_TAB)+"\n"+
140 xmlFormat.dict2string(status["groups"],dict_name="groups",el_name="group",
141 subtypes_params={"class":{"dicts_params":{"factories":{"el_name":"factory",
142 "subtypes_params":{"class":{"subclass_params":{"Requested":{"dicts_params":{"Parameters":{"el_name":"Parameter",
143 "subtypes_params":{"class":{}}}}}}}}}}}},
144 leading_tab=xmlFormat.DEFAULT_TAB)+"\n"+
145 xmlFormat.class2string(status["total"],inst_name="total",leading_tab=xmlFormat.DEFAULT_TAB)+"\n"+
146 "</VOFrontendStats>\n")
147 glideinFrontendMonitoring.monitoringConfig.write_file(monitorAggregatorConfig.status_relname,xml_str)
149 # Write rrds
150 glideinFrontendMonitoring.monitoringConfig.establish_dir("total")
152 for tp in global_total.keys():
153 # type - status or requested
154 if not (tp in status_attributes.keys()):
155 continue
157 tp_str=type_strings[tp]
158 attributes_tp=status_attributes[tp]
160 tp_el=global_total[tp]
162 for a in tp_el.keys():
163 if a in attributes_tp:
164 a_el=int(tp_el[a])
165 val_dict["%s%s"%(tp_str,a)]=a_el
167 glideinFrontendMonitoring.monitoringConfig.write_rrd_multi("total/Status_Attributes",
168 "GAUGE",updated,val_dict)
170 return status
172 ################# PRIVATE #####################
174 def get_xml_updated(when,indent_tab=xmlFormat.DEFAULT_TAB,leading_tab=""):
175 xml_updated={"UTC":{"unixtime":timeConversion.getSeconds(when),
176 "ISO8601":timeConversion.getISO8601_UTC(when),
177 "RFC2822":timeConversion.getRFC2822_UTC(when)},
178 "Local":{"ISO8601":timeConversion.getISO8601_Local(when),
179 "RFC2822":timeConversion.getRFC2822_Local(when),
180 "human":timeConversion.getHuman(when)}}
181 return xmlFormat.dict2string(xml_updated,
182 dict_name="updated",el_name="timezone",
183 subtypes_params={"class":{}},
184 indent_tab=indent_tab,leading_tab=leading_tab)