6 # $Id: glideinFrontendMonitorAggregator.py,v 1.13 2011/02/10 21:35:31 parag Exp $
9 # This module implements the functions needed
10 # to aggregate the monitoring fo the frontend
13 # Igor Sfiligoi (Mar 19th 2009)
16 import time
,string
,os
.path
,copy
18 import xmlParse
,xmlFormat
19 import glideinFrontendMonitoring
22 ############################################################
26 ############################################################
28 class MonitorAggregatorConfig
:
30 # The name of the attribute that identifies the glidein
31 self
.monitor_dir
="monitor/"
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
42 glideinFrontendMonitoring
.monitoringConfig
.monitor_dir
=monitor_dir
45 # global configuration of the module
46 monitorAggregatorConfig
=MonitorAggregatorConfig()
48 ###########################################################
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
73 for tp
in global_total
.keys():
74 # type - status or requested
75 if not (tp
in status_attributes
.keys()):
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
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
)
90 group_data
=xmlParse
.xmlfile2dict(status_fname
)
92 continue # file not found, ignore
96 status
['groups'][group
]={'factories':group_data
['factories']}
98 # first time after upgrade factories may not be defined
99 status
['groups'][group
]={'factories':{}}
102 #status['groups'][group]={}
104 if group_data
.has_key('total'):
106 status
['groups'][group
]['total']=group_data
['total']
108 for w
in global_total
.keys():
110 if not group_data
['total'].has_key(w
):
112 #status['groups'][group][w]=group_data[w]
113 el
=group_data
['total'][w
]
115 # new one, just copy over
119 tel
[a
]=int(el
[a
]) #coming from XML, everything is a string
126 # if any attribute from prev. factories are not in the current one, remove from total
128 if not el
.has_key(a
):
131 for w
in global_total
.keys():
132 if global_total
[w
]==None:
133 del global_total
[w
] # remove group if not defined
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
)
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()):
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
:
165 val_dict
["%s%s"%(tp_str
,a
)]=a_el
167 glideinFrontendMonitoring
.monitoringConfig
.write_rrd_multi("total/Status_Attributes",
168 "GAUGE",updated
,val_dict
)
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
)