flask logger decorator(데코레이터)와 함께 사용하기
기본로그 세팅하기
로그에 대한 부분이 늘 걱정이긴 한데, 사실 따로 python logger 클래스를 사용해서 로그는 남기는 클래스를 만들고 만드는 프로젝트 마다 붙여서 사용하는 식으로 했었는데 이번에 flask 에 있는 logger 를 이용해 보기로 했다. 기본적으로 다음과 같은 몇개의 핸들러를 제공하고 있다.
FileHandler – 로그 메시지를 파일에 남긴다.
RotatingFileHandler – 로그메시지를 파일에 남기고, 특정수 이상이면 다음파일로 넘겨서 로그를 만드는 핸들러, maxBytes 라는 생성자의 파라미터가 있음.
NTEvenetLogHandler – 윈도우 시스템의 시스템 이벤트 로그에 남긴다. 만약 윈도우에 배포된다면 사용해라.
SysLogHandler – 유닉스 syslog
로그핸들러를 선택하고 나면, 아래와 같이 세팅을 해줘야 한다. app.logger 인스턴스에 addHandler()
메서드를 이용해서 선택한 로그핸들러를 등록하는 작업이라고 보면된다.
Traceback (most recent call last):
File “payon.py”, line 77, in <module>
@basicLog
File “/usr/lib/python2.6/site-packages/flask/app.py”, line 1013, in decorator
self.add_url_rule(rule, endpoint, f, **options)
File “/usr/lib/python2.6/site-packages/flask/app.py”, line 62, in wrapper_func
return f(self, *args, **kwargs)
File “/usr/lib/python2.6/site-packages/flask/app.py”, line 984, in add_url_rule
‘existing endpoint function: %s’ % endpoint)
AssertionError: **View function mapping is overwriting an existing endpoint function: newFunc
에러를 확인해 보면 overwriting 이라는 부분이 눈에 띄는데 여러개의 view 메소드 즉, register, signin 등의 메소드에 적용했을때 데코레이터 함수를 거치면서 newFunc 라는 이름이 View Fuction 으로 인식하기 때문에 발생하는 문제이다.
알다시피 flask 의 view function(register, signin과 같은)의 이름은 유일해야 한다. 즉 메소드 이름이 겹치면 발생되는 에러이다.(실제로 같은 두개의 View Function 을 같은 메소드 이름으로 만들면 에러를 볼 수 있다.) 즉 아래와 같이 되는 경우에 발생한다.
위와 같은 문제를 방지하려면 데코레이터에 다음과 같이 functools 는 함수와 호출가능한 객체가 동작하는데 필요한 도구를 제공하는 역할을 하는데 그 안에서 wraps 는 랩핑되는 호출가능한 객체의 속성을 업데이트 하는 역할을 하는데 데코레이터를 쓸때 유용하다고 한다. 그 이유는 변형된 즉, 랩핑된 함수의 원래 속성을 가지게 만드는 역할을 하고 있다.
그래서 위와 같이 func 인자, 이 인자로 VIew function 이 들어오게 되고, 이게 결국 랩핑되는 호출가능한 객체이다. 그 객체를 @wraps(func) 처리를 해주면 각각의 View Function 들이 newFunc 라는 랩핑된 이름이 아닌 고유의 유일한 이름을 가지고 구별되게 됨으로써 flask 실행시 에러를 일으키지 않게 된다.
데코레이터를 활용하면 좀더 메서드에서 선작업(pre-process) 을 지정할 수가 있다. 본 글에서는 단순히 로그를 처리하는 작업을 했는데 좀더 나아간다면 암호환된 키를 체크한다던지 하는 등의 매 함수마다 체크하는 작업들을 하는것도 좋을것 같다. 데코레이터가 좋은 점은 반복코드를 줄여줄수 있다는 점이고 일반적인 함수호출 부분과 같은 역할을 하는것 같지만, 메인코드가 아닌 함수 선언 위쪽에 위치함으로써 좀더 개발자로 하여금 깔끔한 코드를 작성하게 하는것 같다.
functools 에는 데코레이터 및 함수와 관련된 몇가지 기능들이 있으니 한번 살펴보면 좋은데 PyMOTW 에 들어가서 보면 좀더 예제와 함께 잘 이해할 수가 있다.