1
2
3 _mon_classes = {}
4
5 from Ganga.Core.exceptions import GangaException
6 from Ganga.GPIDev.Adapters.IMonitoringService import IMonitoringService
7 from Ganga.Lib.MonitoringServices.Composite import CompositeMonitoringService
8
9 from Ganga.Utility.Config import makeConfig
10
11 c = makeConfig('MonitoringServices', """External monitoring systems are used
12 to follow the submission and execution of jobs. Each entry in this section
13 defines a monitoring plugin used for a particular combination of application
14 and backend. Asterisks may be used to specify any application or any
15 backend. The configuration entry syntax:
16
17 ApplicationName/BackendName = dot.path.to.monitoring.plugin.class.
18
19 Example: DummyMS plugin will be used to track executables run on all backends:
20
21 Executable/* = Ganga.Lib.MonitoringServices.DummyMS.DummyMS
22
23 """,is_open=True)
24
27
28
30 """
31 Return the class object based on the class name string provided as input
32 If the class object is already available in cache the saved value is returned
33 """
34 try:
35 return _mon_classes[mclassname]
36 except KeyError:
37 try:
38 classpath = mclassname.split('.')
39 classname = classpath.pop()
40 modname = '.'.join(classpath)
41 monitoring_module = __import__(modname,globals(), locals(), [classname])
42 monitoring_class = vars(monitoring_module)[classname]
43
44 try:
45 if not issubclass(monitoring_class,IMonitoringService):
46 raise MonitoringServiceError('%s is not IMonitoringService subclass while loading %s'%(classname,mclassname))
47 except TypeError:
48 raise MonitoringServiceError('%s (%s) is not IMonitoringService subclass while loading %s'%(classname,str(type(monitoring_class)),mclassname))
49
50
51 monitoring_class._mod_name = modname
52
53 _mon_classes[mclassname] = monitoring_class
54 return monitoring_class
55 except ImportError,x:
56 raise MonitoringServiceError('%s while loading %s'%(str(x),mclassname))
57 except KeyError,x:
58 raise MonitoringServiceError('class %s not found while loading %s'%(classname,mclassname))
59
61 """
62 Return a comma separted list of class names for
63 a gived job based on its backend and application names.
64 """
65
66 from Ganga.Utility.Config import getConfig, ConfigError
67 mc = getConfig('MonitoringServices')
68
69 def _getMonClasses(option):
70 """
71 for a given app,backend pair return the monitoring classes or an empty string
72 if it's None or not defined
73 """
74 try:
75 monClasses = mc[option]
76
77 if monClasses:
78 return monClasses
79 except (ConfigError,KeyError):
80 pass
81 return ''
82
83
84
85
86
87
88 applicationName = job.application._name
89 backendName = job.backend._name
90
91 allclasses = []
92 for configParam in [applicationName + '/' + backendName,
93 applicationName + '/*',
94 '*/' + backendName,
95 '*/*']:
96 allclasses += _getMonClasses(configParam).split(",")
97
98
99 uniqueclasses = []
100 for x in allclasses:
101 if len(x) > 0 and x not in uniqueclasses:
102 uniqueclasses += [x]
103
104 return ",".join(uniqueclasses)
105
107 """
108 Composite pattern:
109 return a wrapped object implementing the IMonitoringService which contains a
110 list of IMonitoringServices inside and delegating the interface methods to each of them
111 """
112
113 names = [ name.strip() for name in findMonitoringClassesName(job).split(',') if name.strip() ]
114
115 monClasses = [ getMonitoringClass(name) for name in names]
116 jobs = [job]*len(monClasses)
117 configs = [ monClass.getConfig() for monClass in monClasses]
118 return CompositeMonitoringService(monClasses,jobs,configs)
119