Skip to content

Instantly share code, notes, and snippets.

@piroyoung
Created May 14, 2020 15:16
Show Gist options
  • Save piroyoung/bf4a18a87f270757f88370e65639e483 to your computer and use it in GitHub Desktop.
Save piroyoung/bf4a18a87f270757f88370e65639e483 to your computer and use it in GitHub Desktop.
import abc
import functools
import json
import time
import uuid
from dataclasses import asdict
from dataclasses import dataclass
from logging import INFO
from logging import Logger
from logging import basicConfig
from logging import getLogger
from typing import Callable
from typing import Dict
# interface definition
class Describable(metaclass=abc.ABCMeta):
@abc.abstractmethod
def describe(self) -> Dict:
raise NotImplementedError()
# decorator
def observe(logger: Logger):
def decorator(func: Callable) -> Callable:
@functools.wraps(func)
def decorated(self: Describable, *args, **kwargs):
l: Logger = logger.getChild(self.__class__.__name__).getChild(func.__name__)
transaction_id: str = str(uuid.uuid4())
l.info(json.dumps({
"transaction_id": transaction_id,
"type": "start",
"logged_at": time.time_ns(),
"name": "{0}.{1}".format(
self.__class__.__name__,
func.__name__
),
"description": self.describe()
}))
try:
res = func(self, *args, **kwargs)
finally:
l.info(json.dumps({
"transaction_id": transaction_id,
"type": "end",
"logged_at": time.time_ns(),
"name": "{0}.{1}".format(
self.__class__.__name__,
func.__name__
),
"description": self.describe()
}))
return res
return decorated
return decorator
# class definition
_logger: Logger = getLogger(__name__)
@dataclass(frozen=True)
class Value(Describable):
__value: str
def describe(self) -> Dict:
return asdict(self)
@observe(logger=_logger)
def get_value(self):
return self.__value
# class use case
if __name__ == "__main__":
basicConfig(level=INFO)
v: Value = Value("hello")
print(v.get_value())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment