---
title: "로깅 구성 및 사용 방법"
version: 6.0
locale: ko
source: https://docs.djangoproject.com/ko/6.0/howto/logging/
canonical: https://djangodocs.dev/ko/6.0/howto/logging/
---
# 로깅 구성 및 사용 방법

> **See also**
>
> - [Django 로깅 참조](/ko/6.0/ref/logging/#logging-ref)
> - [Django 로깅 개요](/ko/6.0/topics/logging/#logging-explanation)

Django는 쉽게 확장할 수 있는 :ref:기본 로깅 구성 \<default-logging-configuration\>\`을 제공합니다.

## 기본 로깅 호출하기

코드 내에서 로그 메시지를 보내려면 로깅 호출을 입력합니다.

> **``settings.py``에서 로깅 호출을 사용하고 싶은 유혹에 빠지지 마십시오.**
>
> Django 로깅을 `setup()` 함수의 일부로 구성하면 settings.py\`\`에 있는 로깅 호출이 예상대로 작동하지 않을 수 있습니다. 왜냐하면 *로깅이 그 시점에서 설정되지 않기 때문입니다*. 로깅을 탐색하려면 아래 예에서 제안된 뷰 함수를 사용하십시오.

먼저 Python 로깅 라이브러리를 불러온 다음, ```logging.getLogger`를 사용하여 로거 인스턴스를 가져옵니다. ``getLogger()`()``` 메서드에 로거 및 해당 로거가 기록하는 레코드를 식별할 수 있는 이름을 지정하세요. 좋은 옵션은 \_\_name\_\_\`\`을 사용하는 것입니다(자세한 내용은 아래의 [로거 네임스페이싱 사용](#naming-loggers) 참고). 이렇게 하면 현재 Python 모듈의 이름이 점으로 구분된 경로 형태로 사용됩니다:

```
import logging

logger = logging.getLogger(__name__)
```

모듈 수준에서 이 선언을 수행하는 것이 좋습니다.

그런 다음 함수 안(예: 뷰 안)에서 로거에 레코드를 보냅니다:

```
def some_view(request):
    ...
    if some_risky_state:
        logger.warning("Platform is running at risk")
```

이 코드가 실행되면 해당 메시지를 포함한 :class:~logging.LogRecord\`가 로거로 전송됩니다. Django의 기본 로깅 구성을 사용하는 경우 메시지가 콘솔에 나타납니다.

위의 예에서 사용된 `WARNING` 수준은 여러 로깅 심각도 수준들 \<topic-logging-parts-loggers\>\`중 하나입니다: \`\`DEBUG\`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. 따라서 다른 예는 다음과 같습니다:

```
logger.critical("Payment system is not responding")
```

> **Important**
>
> WARNING\`\`보다 낮은 수준의 레코드는 기본적으로 콘솔에 나타나지 않습니다. 이 동작을 변경하려면 추가 구성이 필요합니다.

## 로깅 구성 사용자 정의

Django의 로깅 구성은 별 다른 구성 없이도 작동하지만, 몇 가지 추가 구성을 통해 로그가 다양한 대상(로그 파일, 외부 서비스, 이메일 등)으로 전송되는 방식을 정확하게 제어할 수 있습니다.

다음을 설정할 수 있습니다:

- 어떤 레코드를 어떤 핸들러로 보낼지 결정하는 로거 매핑
- 받은 레코드로 무엇을 할지 결정하는 핸들러
- 레코드 전송에 대한 추가 제어를 제공하고 레코드를 바로 수정할 수 있는 필터
- [`LogRecord`](https://docs.python.org/3/library/logging.html#logging.LogRecord) 객체를 사람이나 다른 시스템에서 사용할 문자열이나 다른 형식으로 변환하는 포맷터

로깅 구성에는 다양한 방법들이 있습니다. Django에서는 [`LOGGING`](/ko/6.0/ref/settings/#std-setting-LOGGING) 구성이 가장 일반적으로 사용됩니다. 이 구성은 :ref:dictConfig 형식 \<logging-config-dictschema\>\`을 사용하고 :ref:기본 로깅 구성 \<default-logging-definition\>\`을 확장합니다.

사용자 지정 설정이 Django의 기본값과 병합되는 방법에 대한 설명은 :ref:configuring-logging\`을 참조하세요.

로깅을 구성하는 다른 방법에 대한 자세한 내용은 mod:Python 로깅 문서 \<python:logging.config\>\`를 참조하세요. 단순화를 위해 이 문서에서는 \`\`LOGGING\` 설정을 통한 구성만 고려합니다.

### 기본 로깅 구성

로깅을 구성할 때, 다음을 수행하는 것이 좋습니다:

#### `LOGGING` 사전 생성

settings.py\`\`에서:

```
LOGGING = {
    "version": 1,  # the dictConfig format version
    "disable_existing_loggers": False,  # retain the default loggers
}
```

disable\_existing\_loggers\`\`를 False\`\`로 설정하여 기본 로깅 구성을 유지하고 확장하는 것이 거의 항상 좋습니다.

#### 핸들러 구성

이 예제는 Python의 ``` FileHandler`를 사용하여 ``DEBUG` ``` 이상의 로그를 (프로젝트 루트에 있는) `general.log` 파일에 저장하는 file\`\`이라는 단일 핸들러를 구성합니다:

```python
LOGGING = {
    # ...
    "handlers": {
        "file": {
            "class": "logging.FileHandler",
            "filename": "general.log",
        },
    },
}
```

핸들러 클래스마다 사용하는 구성 옵션이 다릅니다. 사용 가능한 핸들러 클래스에 대한 자세한 내용은 Django에서 제공하는 :class:~django.utils.log.AdminEmailHandler\`와 Python에서 제공하는 다양한 :mod:handler classes \<logging.handlers\>\`를 참고하세요.

로깅 수준은 핸들러에서도 설정할 수 있습니다(기본적으로 모든 수준의 로그 메시지를 수락함). 위의 예를 사용하여 다음을 추가합니다:

```python
{
    "class": "logging.FileHandler",
    "filename": "general.log",
    "level": "DEBUG",
}
```

`DEBUG` 수준 이상의 레코드만 허용하는 핸들러 구성을 정의합니다.

#### 로거 매핑 설정

이 핸들러로 레코드를 보내려면, 로거 매핑을 구성합니다. 예를 들면 다음과 같습니다:

```python
LOGGING = {
    # ...
    "loggers": {
        "": {
            "level": "DEBUG",
            "handlers": ["file"],
        },
    },
}
```

매핑의 이름은 처리할 로그 레코드를 결정합니다. 이 구성(`''`)은 *unnamed\*입니다. 즉, \*모든* 로거의 레코드를 처리한다는 의미입니다(레코드를 처리할 로거를 결정하기 위해 매핑 이름을 사용하는 방법은 아래의 [로거 네임스페이싱 사용](#naming-loggers) 참조).

`DEBUG` 수준 이상의 메시지를 file\`\`이라는 핸들러로 전달합니다.

로거는 여러 핸들러에 메시지를 전달할 수 있으므로, 로거와 핸들러 간의 관계는 many-to-many입니다.

만약 다음을 실행하는 경우:

```
logger.debug("Attempting to connect to API")
```

코드에서 프로젝트 루트의 `general.log` 파일에서 해당 메시지를 찾을 수 있습니다.

#### 포맷터 구성

기본적으로 최종 로그 출력에는 각 로그 레코드 \<logging.LogRecord\>\`의 메시지 부분이 포함됩니다. 추가 데이터를 포함하려면 포맷터를 사용하십시오. 먼저 이름을 지정하고 포맷터를 정의합니다. 이 예에서는 `verbose` 및 simple\`\`이라는 포맷터를 정의합니다:

```python
LOGGING = {
    # ...
    "formatters": {
        "verbose": {
            "format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
        "simple": {
            "format": "{levelname} {message}",
            "style": "{",
        },
    },
}
```

`style` 키워드를 사용하면 ```str.format`에 ``{``를 지정하거나 :class:`string.Template()``` 형식에 $\`\`를 지정할 수 있습니다. 기본값은 $\`\`입니다.

include할 수 있는 [`LogRecord`](https://docs.python.org/3/library/logging.html#logging.LogRecord) 속성에 대해  :ref:logrecord-attributes\`를 참조하십시오.

포맷터를 핸들러에 적용하려면, 이름으로 포맷터를 참조하는 핸들러의 사전에 `formatter` 항목을 추가하십시오. 예를 들면 다음과 같습니다:

```python
"handlers": {
    "file": {
        "class": "logging.FileHandler",
        "filename": "general.log",
        "formatter": "verbose",
    },
}
```

#### 로거 네임스페이싱 사용

명명되지 않은 로깅 설정 ’’은 모든 Python 응용 프로그램에서 로그를 캡처합니다. 명명된 로깅 구성은 이름이 일치하는 로거에서만 로그를 캡처합니다.

로거 인스턴스의 네임스페이스는 :func:~logging.getLogger\`를 사용하여 정의됩니다. 예를 들어 my\_app\`\`의 views.py\`\`에서:

```
logger = logging.getLogger(__name__)
```

는 `my_app.views` 네임스페이스에 로거를 생성합니다. \_\_name\_\_\`\`을 사용하면 프로젝트의 애플리케이션 내에서 출처에 따라 로그 메시지를 자동으로 구성할 수 있습니다. 또한 이름 충돌이 발생하지 않도록 보장해줍니다.

my\_app.views\`\`라는 로거 매핑은 이 로거에서 레코드를 캡처합니다:

```python
LOGGING = {
    # ...
    "loggers": {
        "my_app.views": {...},
    },
}
```

```my_app``이라는 이름의 로거 매핑은 ``my_app``` 네임스페이스(`my_app.views`, `my_app.utils` 등 포함) 내의 모든 로거에서 레코드를 캡처하기 떄문에 더 관대합니다:

```python
LOGGING = {
    # ...
    "loggers": {
        "my_app": {...},
    },
}
```

다음과 같이 로거 네임스페이스를 명시적으로 정의할 수도 있습니다:

```
logger = logging.getLogger("project.payment")
```

그리고 그에 따라 로거 매핑을 설정합니다.

##### 로거 계층 및 전파 사용

로거 이름 지정은 계층적\*입니다. ```my_app``은 ``my_app.views.private``의 부모인 ``my_app.views``의 부모입니다. 달리 지정하지 않는 한, 로거 매핑은 처리하는 레코드를 부모에게 전파합니다. ``my_app.views.private``` 네임스페이스에 있는 로거의 레코드는 `my_app` 및 `my_app.views` 모두에 대한 매핑에 의해 처리됩니다.

이 동작을 관리하려면, 당신이 정의한 매핑에서 전파 키를 설정합니다.

```
LOGGING = {
    # ...
    "loggers": {
        "my_app": {
            # ...
        },
        "my_app.views": {
            # ...
        },
        "my_app.views.private": {
            # ...
            "propagate": False,
        },
    },
}
```

propagate\`\`의 기본값은 True\`\`입니다. 이 예에서 my\_app.views.private\`\`의 로그는 상위에서 처리되지 않지만 my\_app.views\`\`의 로그는 처리됩니다.

### 반응형 로깅 구성

로깅은 필요하지 않은 정보를 제외한 가능한 많은 정보를 포함할 때 가장 유용합니다. 필요한 정보의 양은 수행 중인 작업에 따라 다릅니다. 디버깅할 때는 프로덕션에서는 과도하고 도움이 되지 않는 수준의 정보가 필요합니다.

필요할 때 필요한 세부 수준을 제공하도록 로깅을 구성할 수 있습니다. 이를 위해 수동으로 구성을 변경하는 것보다, 환경에 따라 자동으로 구성을 적용하는 것이 더 좋은 방법입니다.

예를 들어, 개발 및 스테이징 환경에서 `DJANGO_LOG_LEVEL` 환경 변수를 적절하게 설정하여 로거 매핑에서 사용할 수 있습니다:

```
"level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")
```

\- 따라서 환경이 더 낮은 로그 수준을 지정하지 않는 한 이 구성은 `WARNING` 이상의 심각도를 가진 레코드만 핸들러로 전달합니다.

구성의 다른 옵션(예: 핸들러의 `level` 또는 `formatter` 옵션)도 유사하게 관리할 수 있습니다.
