django LOGGING 의 disable_existing_loggers 동작 방식에 대한 이해

django logging

django는 python의 builtin 로깅 모듈을 사용하여 시스템 로깅 작업을 수행합니다. settings.py LOGGING을 통해 설정이 가능합니다. setting.pyLOGGING 설정이 없을 경우 아래 예시처럼 default 설정을 제공합니다.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'formatters': {
        'django.server': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'style': '{',
        }
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'django.server': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        },
        'django.server': {
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        },
    }
}

위 설정을 간단히 설명하자면 djangodjango.server 두 개의 logger 를 기본으로 사용하도록 설정되어있습니다. django logger 의 경우 root 를 제외한 최상위 logger 이며 console handler 를 사용하게 되는데 debug=True 일 경우만 동작하도록 require_debug_true Filter 를 사용하고 있습니다.

django.server logger 는 django 의 요청처리와 관련된 로그 메시지를 기록하며 propagate 값이 False 이므로 상위 logger 인 django 에 전파되지 않습니다.


django logger 종류

django 는 여러 상황에 대한 로그메시지를 구분하고 기록하기 위해 기본적으로 아래 logger 들을 제공합니다. 자세한 내용은 Django logging extensions 문서를 통해 확인합니다. 여기서는 간단하게 설명합니다.

django

django framework 에서 로그 메시지를 기록하는데 직접적으로 사용되지는 않지만 아래 logger 들을 모두 포함하는 최상위 logger 입니다.

django.request

요청을 처리와 관련된 로그 메시지 입니다. 5XX 응답은 ERROR 레벨로 기록되며, 4XX 응답은 WARNING 레벨로 기록됩니다. django.security logger 에 기록되는 내용은 django.request 로거에 중복으로 기록되지 않습니다.

django.server

django runserver command 를 통해 구동되었을 경우 기록되는 logger 이며 요청 처리와 관련된 로그메시지를 기록합니다. 5XX 응답은 ERROR 레벨로 기록되며, 4XX 응답은 WARNING 레벨로 기록됩니다. 그 외 모든 로그메시지는 INFO 레벨로 기록됩니다.

django.template

django template 랜더링과 관련된 로그 메시지입니다.

django.db.backends

요청에 의해 실행되는 모든 애플리케이션 레벨의 SQL 문을 DEBUG 레벨로 기록합니다. 성능상의 이유로 설정된 logging 레벨과 관계없이 DEBUG=True 일 경우만 활성화됩니다.

django.security.*

보안관련 로그메시지를 기록합니다. 자세한 내용은 위 django 문서 링크를 확인합니다. 관련된 내용은 추후 자세히 다룰 예정입니다.

django.db.backends.schema

migration frmaework 에 의해 실행된 데이터베이스의 스키마 변경 SQL 쿼리들을 기록합니다.


diable_existing_loggers

disable_existing_loggers 값이 True 일 경우 해당 LOGGING 설정이 적용될 때 이미 존재하는 로거들을 비활성화 시키게 됩니다. True 로 설정한 경우 gunicorn 같은 WSGI 서버들의 logging 설정에 영향을 줄 수 있습니다. 예를 들어 아래 django LOGGING 설정을 사용한 app을 gunicorn 통해 실행한다고 가정해봅시다.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True, # 위 설정에서 해당 값만 True 로 변경
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'formatters': {
        'django.request': {
            '()': 'django.utils.log.ServerFormatter',
            'format': '[{server_time}] {message}',
            'style': '{',
        }
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        },
        'django.request': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.request',
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        },
        'django.request': {
            'handlers': ['django.request'],
            'level': 'INFO',
            'propagate': False,
        },
    }
}

gunicorn logger

gunicorn 은 gunicorn.access, gunicorn.error 두 종류의 logger 를 사용합니다. gunicorn 은 masterworker process 로 구성됩니다. master process 는 worker 를 관리하는 역할을 하고 worker 가 실직적으로 django app 이 로드되는 process 입니다.

master 의 경우 gunicorn logging 설정을 그대로 사용하므로 로드메시지가 기록되는데 문제가 없습니다. worker 의 경우 위 최초에 gunicorn logging 설정을 적용한 후 django app 이 등록되는 타이밍에 django logging 설정이 적용됩니다. 이 때 django 관련 logger 는 활성화되나 gunicorn 의 gunicorn.access, gunicorn.error 로거가 disabled 되어 로그메시지가 기록되지 않는 상황이 발생합니다.

master process 는 django app 을 로드하지 않으므로 gunicorn.access, gunicorn.error 로그메시지가 기록됩니다.

결국 아래와 같이 worker 의 disabled 된 로거들이 존재하게 됩니다. disable_existing_logger 과 활성화된 gunicorn logger 예시


결론

대부분의 경우 disable_existing_loggers 값을 True 로 설정할 필요는 없으나 만약 필요한 경우 반드시 동작방식을 이해하고 사용하도록 합니다

2022

MariaDB 10.1.2 하위 버전의 소숫점이 포함된 datetime 형식에 주의하자

3 분 소요

MariaDB 10.1.2 하위 버전에서는 소숫점을 가진 datetime 값을 저장할 때 독특한 형식을 사용한다. 이 독특한 형식이 데이터의 저장이나 조회 등의 일반적인 작업에서는 문제점으로 드러나지 않는다. 하지만 binlog를 사용해야 하는 일부 작업에서는 문제가 발생할 수 있...

API Gateway의 로깅 설정과 Cloudwatch logs 보관주기 설정 자동화

4 분 소요

AWS managed 서비스는 각각의 로깅방식을 제공하고 대부분 Cloudwatch logs를 통해 지원한다. API Gateway도 마찬가지로 AWS 콘솔 설정을 통해 실행 로그와 액세스 로그를 기록할 수 있다. 다만 로그 보관주기를 Gateway 콘솔에서 설정할 수 없다는 단점...

맨 위로 이동 ↑

2021

ubuntu 의 apt 사용시 lock 발생 원인과 해결책을 찾아보자

4 분 소요

ubuntu 서버에서 apt install 사용 시 apt lock 이 발생하며 설치가 실패하는 경우가 간헐적으로 발생합니다. 저의 경우 ubuntu 이미지를 기반으로 진행되는 초반 provisiong 시점에 자주 발생했습니다. [stdout]Waiting for cache loc...

Eventbridge 를 활용하여 AWS 서비스 이벤트 다루기

4 분 소요

AWS 상에서 다양한 아키텍처를 구성하다보면 서비스의 상태를 모니터링하거나 이벤트 알림을 원하는 채널에서 받을 필요가 있습니다. 원하는 서비스의 콘솔을 통해 제공하는 경우도 있으나 디테일한 설정은 어렵거나 제공되지 않는 경우가 많습니다.

PoolCleaner 를 활용한 Connection Pool 최적화

4 분 소요

Tomcat 의 ConnectionPool Tomcat 은 효율적인 Connection Pool 관리를 위해 Commons DBCP 보다 개선된 Tomcat DBCP 를 사용합니다. Idle Connection 수를 조정하고 Active 상태가 오래 지속중인 Connection 을...

python unittest 의 fixture scope

3 분 소요

python testing tool python 에는 널리 알려져 사용되는 여러 도구들이 이미 많습니다. 특히 pytest 는 좀 더 직관적인 assert 구문과 test 결과를 제공하며, 많은 plugin 을 보유하고 있습니다. 하지만 여러 도구들을 알아보기 전에 python t...

맨 위로 이동 ↑