From ece452d0bfe31e20925d4a84f070fe5a0e4bdc0b Mon Sep 17 00:00:00 2001 From: "Eugeniy E. Mikhailov" Date: Sat, 25 Dec 2021 23:21:10 -0500 Subject: draft of time series logger --- qolab/tsdb/__init__.py | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 qolab/tsdb/__init__.py (limited to 'qolab/tsdb/__init__.py') diff --git a/qolab/tsdb/__init__.py b/qolab/tsdb/__init__.py new file mode 100644 index 0000000..b75de0c --- /dev/null +++ b/qolab/tsdb/__init__.py @@ -0,0 +1,89 @@ +import logging +import universal_tsdb as utsdb +import time + +logging.basicConfig(format='%(asctime)s %(levelname)8s %(name)s: %(message)s', datefmt='%m/%d/%Y %H:%M:%S') +logger = logging.getLogger('qolab.tsdb') +logger.setLevel(logging.INFO) + +class Ingester(utsdb.Ingester): + """ Same as universal_tsdb.Ingester byt set measurement_prefix. + so measurement becomes measurement_prefix.measurement """ + def __init__(self, client, batch=0, measurement_prefix=''): + super().__init__(client, batch=batch) + self.measurement_prefix=measurement_prefix + + def append(self, timestamp=None, tags=None, measurement=None, **kwargs): + if self.measurement_prefix is None or not isinstance(self.measurement_prefix, str): + raise ValueError('Invalid measurement_prefix, it should be string') + if measurement is None or not isinstance(measurement, str): + raise ValueError('Invalid measurement, it should be string') + qolab_measurement = '.'.join((self.measurement_prefix, measurement)) + # space is illegal for measurements fields + qolab_measurement=qolab_measurement.replace(' ', '-') + print(qolab_measurement) + return super().append(timestamp=None, tags=tags, measurement=qolab_measurement, **kwargs) + +def tsdb_append_metric_for_class_setter_or_getter(tsdb_logger=None): + def wrap(f): + def wrapper(*args, **kwds): + if f.__name__[0:3] != 'get' and f.__name__[0:3] != 'set': + logger.warning(f'Do not know how to work with {f.__name__}, it is neither set... or get...') + ret = f(*args, **kwds) + return ret + + cls = args[0] + action = f.__name__[0:3] + var_name = f.__name__[3:] + val = None + device_type=cls.config['Device type'] + if action == 'get': + """ getter """ + val = f(*args, **kwds) + ts = time.time() + ret = val + else: + """ setter """ + val = args[1] + ts = time.time() + ret = f(*args, **kwds) + + logger.info(f'function {f.__name__} {action} {var_name} = {val}') + ts_ms = int(ts*1000) + fields={var_name: val} + try: + tsdb_logger.append(ts_ms, measurement=device_type, tags={'action': action}, **fields) + except ValueError as err: + logger.error(f'{err=} in function {f.__name__}: {var_name} = {val}') + ts_ms = int(ts*1000) + return ret + return wrapper + return wrap + +if __name__ == '__main__': + from qolab.hardware.basic import BasicInstrument + tsdb_client = utsdb.Client('influx', 'http://localhost:8428', database='qolab') + tsdb_logger = Ingester(tsdb_client, batch=10, measurement_prefix='VAMPIRE.HighPower') + class InstWithLog(BasicInstrument): + def __init__(self): + super().__init__() + self.config['Device type'] = 'TestTSDBLogger' + self.config['Device model'] = 'v01' + self.config['FnamePrefix'] = 'test_log' + self.config['SavePath'] = './data' + self.deviceProperties = ['D']; + self.d = 13.45 + + @tsdb_append_metric_for_class_setter_or_getter(tsdb_logger) + def setD(self, val): + self.d=val + + @tsdb_append_metric_for_class_setter_or_getter(tsdb_logger) + def getD(self): + return self.d + + dev = InstWithLog() + dev.getD() + dev.setD(21) + + tsdb_logger.commit() -- cgit v1.2.3