[python] Django 설정 기본 로깅

Django 설치를 위해 “기본”로거를 설정하는 방법을 알아낼 수없는 것 같습니다. .NET에서 Django 1.3의 새로운 LOGGING설정 을 사용하고 싶습니다 settings.py.

Django Logging Doc의 예제를 살펴 보았지만 특정 로거에 대한 로깅을 수행하는 핸들러 만 설정하는 것처럼 보입니다. 예제의 경우 ‘django’, ‘django.request’및 ‘myproject.custom’이라는 로거에 대한 핸들러를 설정합니다.

내가 원하는 것은 기본적으로 logging.handlers.RotatingFileHandler모든 로거를 처리 할 기본값 을 설정하는 것입니다. 즉, 프로젝트 어딘가에 새 모듈을 만들고 다음과 같이 표시 my_app_name.my_new_module되면이 작업을 수행하고 모든 로깅을 회전하는 파일 로그로 이동할 수 있어야합니다.

# In file './my_app_name/my_new_module.py'
import logging
logger = logging.getLogger('my_app_name.my_new_module')
logger.debug('Hello logs!') # <-- This should get logged to my RotatingFileHandler that I setup in `settings.py`!



답변

알아 냈어 …

빈 문자열로 참조하여 ‘모두 포괄’로거를 설정합니다 : ''.

예를 들어, 다음 설정에서는에 저장 될 로그 이벤트를 logs/mylog.log제외 하고 모든 로그 이벤트가에 django.request저장됩니다 logs/django_request.log. 내 로거 'propagate'False대해 로 설정되어 있기 때문에 django.request로그 이벤트는 ‘모두 포괄’로거에 도달하지 않습니다.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': True
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}


답변

답변 , Chris 에서 말했듯 이 기본 로거를 정의하는 한 가지 옵션은 빈 문자열을 키로 사용하는 것입니다.

그러나 의도 된 방법은 root로깅 구성 사전 의 키 아래에 특수 로거를 정의하는 것이라고 생각합니다 . 파이썬 문서 에서 이것을 찾았습니다 .

루트 -이것은 루트 로거의 구성입니다. 구성 처리는 propagate설정이 적용되지 않는 것을 제외하고는 모든 로거와 동일합니다 .

root키 를 사용하기 위해 변경된 답변의 구성은 다음과 같습니다 .

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'root': {
        'handlers': ['default'],
        'level': 'DEBUG'
    },
    'loggers': {
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}

공정하게 말하면 두 구성 간의 동작 차이를 볼 수 없습니다. 빈 문자열 키로 로거를 정의하면 루트 로거 logging.getLogger('')를 반환 하기 때문에 루트 로거가 수정되는 것으로 보입니다 .

내가 선호하는 유일한 이유 'root'이상은 ''이 루트 로거 수정에 대한 명시적인 것입니다. 경우에 당신은 호기심이 있었다 'root'재정의 ''루트 항목이 마지막으로 처리해서, 모두 정의합니다.


답변

import logging
logger = logging.getLogger(__name__)

추가 후 :

logging.basicConfig(
    level = logging.DEBUG,
    format = '%(name)s %(levelname)s %(message)s',
)

형식을 다음과 같이 변경할 수 있습니다.

format = '"%(levelname)s:%(name)s:%(message)s"  ',

또는

format = '%(name)s %(asctime)s %(levelname)s %(message)s',


답변

root키와 빈 ''로거가 config dict에서 참조 될 때 사용되는 구성을 확인하기 위해 빠른 샘플을 만들었습니다 .

import logging.config

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'fmt1': {
            'format': '[FMT1] %(asctime)-15s %(message)s',
        },
        'fmt2': {
            'format': '[FMT2] %(asctime)-15s %(message)s',
        }
    },
    'handlers': {
        'console1': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt1',
        },
        'console2': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt2',
        },
    },
    # First config for root logger: console1 -> fmt1
    'root': {
        'handlers': ['console1'],
        'level': 'DEBUG',
        'propagate': True,
    },
    'loggers': {
        # Second config for root logger: console2 -> fmt2
        '': {
            'handlers': ['console2'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

logging.config.dictConfig(LOGGING)

l1 = logging.getLogger()
l2 = logging.getLogger('')
root = logging.root

l1.info("l1")
l2.info("l2")
root.info("root logger")

다음 결과를 인쇄합니다.

[FMT1] 2018-12-18 17:24:47,691 l1
[FMT1] 2018-12-18 17:24:47,691 l2
[FMT1] 2018-12-18 17:24:47,691 root logger

root키 아래의 구성 이 가장 높은 우선 순위를 가짐을 나타냅니다 . 블록이 제거되면 결과는 다음과 같습니다.

[FMT2] 2018-12-18 17:25:43,757 l1
[FMT2] 2018-12-18 17:25:43,757 l2
[FMT2] 2018-12-18 17:25:43,757 root logger

두 경우 모두 세 개의 로거 ( l1, l2root) 가 모두 동일한 로거 인스턴스 인 루트 로거를 참조 하는지 디버그하고 확인할 수있었습니다 .

저와 같이 루트 로거를 구성하는 두 가지 다른 방법으로 혼란스러워했던 다른 사람들에게 도움이되기를 바랍니다.


답변