def get_hdbpp_databases(archivers=[],dbs={}): """ Method to obtain list of dbs/archivers; it allows to match any archiver list against existing dbs. This method can be used in cached mode executed like: dbs = get_hdbpp_databases() for a in archivers: db = get_hdbpp_databases(a,dbs).keys()[0] """ if not dbs: dbs = {} print('Loading databases from Tango') cms = ft.get_class_devices('HdbConfigurationManager') for c in cms: try: props = ['LibConfiguration','ArchiverList'] props = ft.get_database().get_device_property(c,props) db = dict(t.split('=') for t in props['LibConfiguration'])['dbname'] dbs[db] = {c:None} for c in props['ArchiverList']: dbs[db][c] = ft.get_device_property(c,'AttributeList') except: print('Unable to load %s config' % str(c)) traceback.print_exc() else: dbs = dbs.copy() if archivers: archivers = list(archivers) #Don't use toList here! targets = [] for a in archivers: m = fn.parse_tango_model(a,fqdn=True) targets.extend((m.fullname, m.devicename, m.devicemodel)) print(targets) for db,archs in dbs.items(): narchs = {} for a in archs.keys(): if fn.inCl(a,targets): m = fn.parse_tango_model(a,fqdn=True).fullname narchs[m] = archs[a] if not narchs: dbs.pop(db) else: dbs[db] = narchs return dbs
def start_attributes_for_archivers(target,attr_regexp='',event_conf={}, load=False, by_class=False, min_polling = 100, overwrite = False, check = True): """ Target may be an attribute list or a device regular expression if by_class = True, config will be loaded from Tango class properties """ import PyTangoArchiving.hdbpp as ptah if fn.isSequence(target): if attr_regexp: attrs = [a for a in target if fn.clmatch(attr_regexp,a.rsplit('/')[-1])] else: attrs = target else: dev_regexp = target attrs = fn.find_attributes(dev_regexp+'/'+(attr_regexp or '*')) if by_class: classes = fn.defaultdict(dict) devs = fn.defaultdict(list) [devs[a.rsplit('/',1)[0]].append(a) for a in attrs] for d,v in devs.items(): classes[fn.tango.get_device_class(d)][d] = v attrs = {} for c,devs in classes.items(): cfg = get_class_archiving(devs.keys()[0]) for d in devs: raw = devs[d] for a,v in cfg.items(): for aa in raw: if fn.clmatch(a,aa.split('/')[-1],terminate=True): if not attr_regexp or fn.clmatch(attr_regexp,aa): attrs[aa] = v elif event_conf: attrs = dict((a,event_conf) for a in attrs) else: attrs = dict((a,get_current_conf(a)) for a in attrs) print('Starting %d attributes' % (len(attrs))) archs = ptah.multi.match_attributes_and_archivers(attrs.keys()) rd = PyTangoArchiving.Reader() #print(archs) alldbs = ptah.multi.get_hdbpp_databases() dbs = ptah.multi.get_hdbpp_databases(archs,alldbs) #return dbs,archs,attrs for db,rcs in dbs.items(): api = PyTangoArchiving.Schemas.getApi(db) dbs[db] = dict.fromkeys(rcs) for d in rcs: dbs[db][d] = ts = dict.fromkeys(archs[d]) #return ts for a in ts: try: m = fn.parse_tango_model(a,fqdn=True) dbs[db][d][a] = mode = attrs[a] if not overwrite and db in rd.is_attribute_archived(a): print('%s already archived in %s' % (a,db)) continue events = ft.check_attribute_events(a,ft.EventType.ARCHIVE_EVENT) ep = events.get(ft.EventType.ARCHIVE_EVENT,False) if ep is True: if 'polling' in mode: mode.pop('polling') elif isinstance(events.get(ep,(int,float))): mode['polling'] = min((ep,mode.get('polling',10000))) mode['polling'] = max((mode['polling'],min_polling)) if not events.get(ft.EventType.CHANGE_EVENT,False): if mode.get('archive_abs_change',0): mode['abs_event'] = mode['archive_abs_change'] if mode.get('archive_rel_change',0): mode['rel_event'] = mode['archive_rel_change'] if mode.get('arch_per_event',0): mode['per_event'] = mode['archive_per_event'] print('%s.start_archiving(%s,%s,%s): %s' % (db,d,m.fullname,mode,load)) if load: fn.tango.set_attribute_events(a,**mode) r = api.start_archiving(m.fullname,d,code_event=True) assert not check or r except: print('%s failed!'%a) traceback.print_exc() return dbs
def get_panic_report(api=None, timeout=3000., tries=3, devfilter='*', attr='ActiveAlarms', trace=False): """ The key of the results: key.count('/') == 0 : alarm == 1: server == 2: device == 4: summary """ if api is None: api = panic.api() elif isString(api): api = panic.api(api) if not len(api.servers): if devfilter == '*': api.servers.load_by_name('PyAlarm/*') if isString(devfilter): api.servers.load_by_name(devfilter) else: [api.servers.load_by_name(d) for d in devfilter] alldevs = fd.tango.get_all_devices(exported=True) result = fd.dicts.defaultdict(dict) result['//alarms//'] = api.alarms.keys() result['//devices//'] = api.devices.keys() result['//servers//'] = api.servers.keys() off = [] hung = [] slow = [] aslow = [] errors = {} for s, ss in api.servers.items(): admin = fd.parse_tango_model(ss.get_admin_name())['device'] if admin.lower() not in alldevs: off.append(admin) result[s]['devices'] = ss.get_classes()['PyAlarm'] for d in result[s]['devices']: if isSequence(devfilter): if d not in devfilter: continue elif not clsearch(devfilter, d): continue if admin in off: t = END_OF_TIME off.append(d) else: proxy = fd.get_device(d) t = get_device_timeout(d, timeout, tries, alldevs, proxy, trace=False, attr=attr) if t == END_OF_TIME: hung.append(d) if t * 1e3 > timeout: slow.append(d) result[d]['timeout'] = t result[d]['attrs'] = 0 result[d]['alarms'] = len(api.devices[d].alarms) polling = float(api.devices[d].config['PollingPeriod']) result[d]['polling'] = polling try: evals = get_device_eval_times(proxy, timeout) teval = sum(evals.values()) ratio = teval / float(polling) result[d]['eval'], result[d]['ratio'] = teval, ratio except: evals = {} result[d]['eval'], result[d]['ratio'] = -1, -1 for a, aa in api.devices[d].alarms.items(): attrs = api.parse_attributes(aa['formula']) result[d]['attrs'] += len(attrs) result[a]['device'] = d result[a]['attrs'] = attrs result[a]['timeout'] = evals.get(a, -1) if result[a]['timeout'] > polling / result[d]['alarms']: aslow.append(a) result['//off//'] = off result['//bloat//'] = [ k for k in result if k.count('/') == 2 and result[k].get('ratio', -1) >= 1. ] result['//hung//'] = hung result['//slow_devices//'] = slow result['//slow_alarms//'] = aslow #print('off devices: %s\n'%(off)) #print('hung devices: %s\n'%(hung)) #print('slow devices: %s\n'%(slow)) #print('bloat devices: %s\n'%([k for k in result #if '/' in k and result[k].get('ratio',-1)>=1.])) #print('slow alarms: %s\n'%aslow) return result