Django 프로젝트에서 비지니스 로직에 영향을 주지 않고 최대한 깔끔하게 로깅 하는 방법을 찾다보니 데코레이터가 떠올랐다.(Spring 에서 많이 사용하는 AOP(Aspect Oriented Programming) 느낌으로 접근하면 이해가 편할 것 같다.)
로그를 남기는 데이터는 별것없다. 누가, 언제, 어떤 action 딱 3개의 데이터만 해당 view 에 접근했을때 Logging DB에 insert 하려한다.
view
DRF를 이용해서 view를 만들었다. @api_view 또한 데코레이터를 사용하기 때문에 순서가 중요하다.
api_view 먼저 실행 시키고 그다음에 나의 custom logging 데코레이터를 실행 하려한다.
@api_view(['GET'])
@Logging.log_decorator('고객을 가져오는 액션!')
def get_customer(request: Request) -> Response:
데코레이터
Logging Model에 static 메소드로 데코레이터를 생성했다.
데코레이터가 무려 두개나 있는데 이는 action 이라는 매개변수를 전달 받기 위함이다.
(stackoverflow 참조: https://stackoverflow.com/questions/5929107/decorators-with-parameters)
function(*args, **kwargs)은 기존의 view 로직을 실행하는 구문이다.
필자는 기존의 view 로직을 수행하기 전에 로깅을 하기 원한다.
Logging 데이터를 추가하기 전에 args는 api_view 데코레이터를 처리한 뒤 반환된 값이라 Django에서 사용하는 user 객체를 이용할 수 있다. 해서 user 데이터를 args[0].user.username을 사용해서 추가했다.
필자가 실행한 전처리보다는 후처리를 하고 싶은 경우엔 # 후처리 부분에 로직을 넣으면 된다.
class Logging(TimeStampedModel):
user = models.CharField(max_length=255)
action = models.CharField(max_length=255)
created = models.DateTimeField(auto_now_add=True)
@staticmethod
def log_decorator(action: str):
def decorator(function):
def wrapper(*args, **kwargs):
try: # 전처리
Logging.objects.create(user=args[0].user.username, action=action).save()
except Exception as e:
print("###Error####", e)
result = function(*args, **kwargs)
# print('GoodBye~') # 후처리
return result
return wrapper
return decorator
결론 : 비지니스 로직에 Logging 로직을 넣지 말고 데코레이터를 이용해 넣자. 깔끔해진다.
'python' 카테고리의 다른 글
파이썬 데코레이터 패턴으로 코드 깔끔하게 정리하기 (0) | 2024.03.19 |
---|---|
python oracle 데이터 json serialize(django) (0) | 2020.02.25 |
python super (0) | 2019.12.26 |
python 메모리 관리(memory allocation) (4) | 2019.11.15 |
클래스 관계 IS-A 상속 (0) | 2019.11.07 |