Posts loguru를 사용하여 python 로깅 쉽게하기
Post
Cancel

loguru를 사용하여 python 로깅 쉽게하기

종종 파이썬으로 코딩을 하게되면 무의식적으로 print() 문을 사용하는 경우가 있습니다.

개인적인 사이드 프로젝트에서는 크게 문제되지 않지만 회사, 팀 프로젝트 단위에서는 필요한 데이터를 print()문 하나에 의존해 남기는 것은 매우 위험하다고 생각합니다.

print()는 단지 stdout을 통해 모니터에 출력되기만 하는것이며 다음에 필요할 때 찾기가 매우 까다롭기 때문입니다.

그래서 파이썬에서는 공식적으로 logging 라이브러리가 존재합니다.

하지만 level, filter, handler라는 개념 등이 존재하며 잘 사용하기 위해서는 까다로운 설정이 필요하다고 생각합니다.

loguru란

loguru란 python 기반의 사용할 수 있는 로깅 오픈 소스입니다.

대표적인 특징은 아래와 같습니다.

특징

  • 설정 없이 바로 사용 가능
  • handler, formatter, filter를 하나의 함수에서 정의할 수 있음
  • 회전 / 보존 / 압축을 사용할 수 있는 간편한 파일 로깅
  • 중괄호 스타일을 사용한 최신 문자열(f-string과 비슷한) 서식
  • 스레드 또는 메인 내에서 발생하는 예외 처리
  • 색상으로 예쁜 로깅
  • 비동기식, 스레드 안전, 다중 프로세스에 안전한 로깅

등과 여러 특징이 있습니다. 자세한 기능은 공식 홈페이지에 좀 더 자세하게 설명되어 있습니다.

사용해보기

기본 로깅

1
2
from loguru import logger
logger.debug("hello world")

loguru기본 설정이 되어 있어 다음과 같이 문법으로도 간단하게 로깅할 수 있습니다.

또한 다른 방법으로 로깅을 하고 싶다면 add() 함수를 사용하여 다른 핸들러를 추가할 수 있습니다.

파일에 특정 주기별 주기별 로깅하기

1
2
logger.add("file_1.log", rotation="12:00")  # 매일 12시에 새로운 로그 파일 생성
logger.add("file_X.log", retention="10 days")  # 10일 후에 제거

logururotationretention 기능을 이용해 특정 주기별로 로깅을 남길 수 있습니다.

1
logger.add("test_{time}", rotation="12:00", retention="10 days", compression="zip")

다음과 같은 코드는 로깅할 때 파일 이름은 test_2021-01-05_16-51-05_359452 의 형식이 됩니다.

또한, 매일 12시에 새로운 파일이 생기며 해당 파일은 10일간 유지되며 로깅이 끝난 파일의 경우 zip으로 압축됩니다. ("gz", "bz2", "xz", "lzma", "tar", "tar.gz", "tar.bz2", "tar.xz", "zip" 등의 형식도 지원합니다.)

자세한 파라미터 정보는 여기를 참고하시면 좋습니다.

필터링

로그를 남기다보면 어떤 메세지는 특정 핸들러에 남기고 싶지 않은 경우가 있습니다.

그런 경우 logurufilterbind를 사용하면 됩니다.

1
2
3
logger.add("special.log", filter=lambda record: "special" in record["extra"])
logger.debug("This message is not logged to the file")
logger.bind(special=True).info("This message, though, is logged to the file!")

filtercallable이 들어간다면 record를 받아 사용할 수 있습니다.

위의 코드와 같이 사용할 수 있으며, record다양한 속성이 있습니다.

bind는 해당 메시지의 extra에 특정 값을 종속적으로 묶을수 있으며 바인딩된 logger를 반환합니다. 따라서 다음과 같이 사용할 수도 있습니다.

1
some_logger = logger.bind(special=True)

다음과 같이 사용하면 filter 조건을 만족해서 special.log에 적재되게 됩니다.

새로운 레벨 만들기

loguru는 독특하게 레벨이라는 개념을 만들 수 있습니다. 새로운 레벨을 만들고 로깅을 하는 방법은 다음과 같습니다.

기존 loguru에서 사용하는 레벌 개념은 다음과 같으며, 표준 로거와 같은 동일한 수준으로 로깅과 연결됩니다.

1
2
new_level = logger.level("SNAKY", no=38, color="<yellow>", icon="🐍")
logger.log("SNAKY", "Here we go!")

메시지 포맷 정하기

loguru또한 기본 로깅 라이브러리처럼 메시지 포맷을 정할 수 있습니다.

1
logger.add("file.log", format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}")

또한, 색상 마크 업 등을 지원합니다.

loguru는 그 외에도 표준 로깅 라이브러리에 전파할 수 있는 기능 등 다양한 기능을 지원합니다.

프로덕션에 적용하기

해당 라이브러리를 production 프로젝트에 적용해보았습니다.

처음 프로젝트에 도입할 때 다음과 같은 형식으로 적용하였습니다.

1
2
3
4
if ENV == "production":
  logger.add(...)
elif ENV == "staging":
  logger.add(...)

프로젝트는 Flask와 비슷한 설정을 사용햇습니다.

아쉬운점은 프로젝트 도입 초기에 configure함수를 발견하지 못하고 바쁘게 프로젝트를 진행하여 위와 같이 각각의 환경에 설정을 하게 됐습니다.

코드 리팩토링 할 때 설정 파일을 다음과 같이 리팩토링 하려 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Config(object):
    DEBUG = False
    TESTING = False
    DATABASE_URI = 'sqlite:///:memory:'
    LOGURU_SETTINGS = {}


class ProductionConfig(Config):
    DATABASE_URI = 'mysql://user@localhost/foo'
    LOGURU_SETTINGS = {
        "handler": [
            dict(sink=sys.stderr, format="[{time}] {message}"),
            dict(sink="file.log", enqueue=True, serialize=True),
        ],
        "levels": []
        ...
    }


class StagingConfig(Config):
    DEBUG = True
    LOGURU_SETTINGS = {
        "handler": [
            dict(sink=sys.stdout, format="[{time}] {message}"),
        ],
        "levels": []
        ...
    }


if ENV == "production":
  config = ProductionConfig()
elif ENV == "staging":
  config = StagingConfig()


logger.configure(**config.LOGURU_SETTINGS)

번외

production에 적용을 하니 라이브러리 단 설정 때문에 stderr에 무조건 로깅이 되는 상황이 벌어졌습니다.

따라서 다음과 같은 설정을 적용했습니다.

1
2
3
4
5
6
7
8
9
10
# ...

if ENV == "production":
  config = ProductionConfig()
elif ENV == "staging":
  config = StagingConfig()


logger.remove()  # 기존 모든 로깅 핸들러를 제거
logger.configure(**config.LOGURU_SETTINGS)

loguru를 이용해 간단하게 로깅하는 법을 포스팅해봤습니다.

loguru는 한글 문서가 부족하다는 점이 있지만 사용자 편의 기능을 많이 지원하며 문서화 또한 간단하게 잘 되어 있습니다. 또한, 간단하게 logging 시스템을 쉽게 적용할 수 있다는 장점이 있어 한번쯤 사용해보시면 좋을 것 같습니다.

참고

This post is licensed under CC BY 4.0 by the author.