Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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