Source code for gadget

# -*- coding: utf-8 -*-
import json
import datetime
import time

import logbook
import munch

__author__ = 'Rotem Yaari'
__email__ = 'vmalloc@gmail.com'

_MARKER = 'GDGT::'

TYPE_CODES = munch.Munch(
    CREATE='CR',
    DELETE='DL',
    OPERATION='OP',
    STATE='ST',
    UPDATE='UP',
    ERROR='ER',
)

_ALL_TYPE_CODES = set(TYPE_CODES.values())

_logger = logbook.Logger(__name__)


[docs]class Setup(object): def __init__(self, level=logbook.DEBUG): super(Setup, self).__init__() self.level = level def __enter__(self): _setups.append(self) return self def __exit__(self, *_): popped = _setups.pop() assert popped is self
_setups = [Setup()]
[docs]def log_entity_creation(entity, params=None): """Logs an entity creation """ p = {'entity': entity} if params: p['params'] = params _log(TYPE_CODES.CREATE, p)
[docs]def log_entity_deletion(entity, params=None): """Logs an entity creation """ p = {'entity': entity} if params: p['params'] = params _log(TYPE_CODES.DELETE, p)
[docs]def log_operation(entities, operation_name, params=None): """Logs an operation done on an entity, possibly with other arguments """ if isinstance(entities, (list, tuple)): entities = list(entities) else: entities = [entities] p = {'name': operation_name, 'on': entities} if params: p['params'] = params _log(TYPE_CODES.OPERATION, p)
[docs]def log_state(entity, state): """Logs a new state of an entity """ p = {'on': entity, 'state': state} _log(TYPE_CODES.STATE, p)
[docs]def log_update(entity, update): """Logs an update done on an entity """ p = {'on': entity, 'update': update} _log(TYPE_CODES.UPDATE, p)
[docs]def log_error(error, result): """Logs an error """ p = {'error': error, 'result':result} _log(TYPE_CODES.ERROR, p)
def _log(code, params): if not _setups: return _logger.log( _setups[-1].level, '{}{}:{}:{}', _MARKER, code, time.time(), _LazyJSON(params)) class _LazyJSON(object): def __init__(self, what): self._what = what self._rendered = None def __repr__(self): if self._rendered is None: self._rendered = json.dumps(self._what, default=repr) return self._rendered __str__ = __repr__ # Parsing
[docs]def parse_log_line(line): try: index = line.index(_MARKER) except ValueError: return None line = line[index + len(_MARKER):] linetype, timestamp, params = line.split(':', 2) returned = munch.Munch(type=linetype, params=json.loads(params), timestamp=datetime.datetime.fromtimestamp(float(timestamp))) if returned.type == TYPE_CODES.OPERATION: returned.entities = returned.params.get('on') returned.name = returned.params.get('name') elif returned.type == TYPE_CODES.STATE: returned.entity = returned.params.get('on') returned.state = returned.params.get('state') elif returned.type == TYPE_CODES.UPDATE: returned.entity = returned.params.get('on') returned.update = returned.params.get('update') elif returned.type in [TYPE_CODES.CREATE, TYPE_CODES.DELETE]: returned.entity = returned.params.get('entity') return returned