티스토리 뷰

싸이트를 운영하다보면 종종 예상하지 못한 문제가 생긴다. 
로컬에서야 이럴때 그냥 프린트문으로 찍어보면서 해결해도 되지만, 실제 프로덕션에서 그러기는 어렵다. 이 때 도움되는 것이 로그 파일인데 장고에서는 로깅하는 것을 자체에서 제공해주고있어 매우 편리하게 적용이 가능하다!

장고의 로깅은 파이썬에 빌트인으로 들어가 있는 로깅 기능을 사용하고 있어 만약 장고 문서에 설명이 부족한 것 같으면 파이썬의 로깅에 대한 설명을 보면 된다.

어쨌건 파이썬의 로깅은 아래의 네 부분으로 이루어져있다. 나름 번역을 했으나 이게 뭔 말인지 모르겠다면 원문을 보는 편이 낫다.... 원문링크

Loggers
- 다섯 개의 로그레벨이 있다. DEBUG - INFO - WARNING - ERROR - CRITICAL 순으로 높아진다.
- 각 로거는 어떤 메세지가 작성되는지에 따라 이름지어진 버킷이다. (원문:  Each logger is a named bucket to which messages can be written for processing.)

Handler
- 핸들러는 로거의 각 메세지에 무슨 일이 벌어지는지를 결정하는 엔진으로 메세지를 스크린에 보여주거나 파일에 쓰거나 등의  로깅 동작등을 묘사하고 있다. 로거와 마찬가지로 핸들러 역시 로그 레벨을 가지고 있다. 로거는 여러개의 핸들러를 가질 수 있다.

Filters
- 필터는 로거에서 핸들러로 어떤 로그 기록이 통과할지를 추가적으로 제어한다. 기본적으론 로그 레벨에 맞는 모든 로그 메세지가 핸들러에 도달하지만, 필터를 사용해서 다른 기준을 설정해줄 수 있다.

Formatters
- 로그 기록은 텍스트로 전해지는데 포매터의 경우엔 이 텍스트의 형태를 결정한다.


로깅은 Logging 라이브러리를 사용해서 세팅하는 것도 있고, settings 파일에 구성하는 방법이 있는데, 전자의 방법은 나중엔 필요할지도 모르지만 지금 당장은 크게 필요하지 않을 것 같아서, 일단은 후자의 방법을 택했다. 물론 코드를 여러줄 쓰기 귀찮은 것도 이유에 포함된다.

장고 공식문서에서는 다양한 구성방법에 대해서 예시를 보여주고 있는데 나의 경우엔 DEBUG 레벨은 콘솔에서도 보여주고, 디버그 로그도 만들어주고, 에러의 경우엔 에러 로그를 따로 하나 더 만들도록 세팅하기로 했다.
그리고 이 로그 파일명은 {레벨}__{날짜(yyyyMMdd)}_{시간(t)}.log 로 만들어주도록 할 것이다. (초나 분까지 입력하면 로그파일이 너무 많아질 것 같고 내가 관리하는 사이트는 아직 그렇게 유저가 많진 않다)

 

먼저 날짜 포맷을 만들어보자.

from datetime import datetime
now = datetime.now()
str_now = now.strftime('%y%m%d_%H')

다음은 내 로그파일 설정이다.

 

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{asctime} {levelname} {module} {message}',
            'datefmt': '%Y-%m-%d %H:%M',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'debug_log': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': f'logs/debug/deb__{str_now}.log',
            'formatter': 'verbose',
        },
        'error_log': {
            'level': 'ERROR',
            'class': 'logging.FileHandler',
            'filename': f'logs/error/err__{str_now}.log',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'debug_log'],
            'level': 'DEBUG',
            'propagate': True,
        },
        'django.request': {
            'handlers': ['error_log'],
            'level': 'ERROR',
            'propagate': True,
        },
    },
}

거의 기본 예시에서 많이 따왓는데 조금 다른게 있다면 포매터에서 datefmt 일 것이다. 로그파일에 입력되는 메세지에 초까지 나올 필요는 없을 것 같아서 분단위까지만 짤랐다.
그리고 로그파일명도 아까의 날짜 포맷을 집어넣어 만들어주도록 했다.
마지막으로 핸들러에서 디버그 레벨의 로그는 디버그로그와 콘솔에 다 들어가도록 해주고 에러 로그는 따로 만들어주도록 해서 나의 세팅은 끝. 이후 동작을 확인해보니 잘 동작하는 것을 확인할 수 있다.

 

+

이렇게 해서 돌렸더니 로컬에서 돌릴땐 몰랐는데...실서버에서 보니 서버를 껏다 다시 켤 때만 파일이 갱신되고 그러지 않으면 계속 한 파일에 로그가 저장되는 문제가 있었다! 때문에 자동으로 하루마다 새 로그를 만들어주는 방법을 찾아봤는데 위의 예제에서 FileHandler가 아니라 'logging.handlers.TimedRotatingFileHandler'를 쓰면 된다고 한다. 

 TimedRotatingFileHandler에 대한 설명은 장고 문서가 아니라 파이썬 문서에 있다. 사실 장고의 많은 것들이 파이썬의 기본적인 것에 확장한 형태라 만약 장고 문서에서 설명을 찾을 수 없다면 파이썬 문서에서 찾으면 된다. 

반응형
댓글