language/Python

[Python] Logging 라이브러리 정리, Airflow에서 Logging사용하기

스파이디웹 2023. 11. 20. 21:35
728x90

Airflow에서 PythonOperator를 실행할 때 로그가 나오지 않아서 테스크가 잘 진행되고 있는지 확인하기가 어려웠던 상황이 있었습니다.

 

logging 라이브러리를 사용해도 airflow UI에서 확인 할 수가 없었는데 관련해서 정리를 해보고자 합니다.


1. Logging

The only time that print is a better option than logging is when the goal is to display a help statement for a command line application.

Shell과 같은 커맨드 인터페이스에서 
--help 옵션을 받아 사용법 도움말을 출력할 때 이외에는 항상 logging print보다 낫다는 뜻으로, 사실상 웬만한 상황에서는 print 대신 logging을 사용하는 것이 나음

 

  • 로깅 이벤트를 통해 생성되는 로그 기록에는 파일명, 파일 경로, 함수명이나 라인 넘버 등 로깅 이벤트 발생 시점의 정보가 자세하게 담겨 있어 프로그램 사후 진단이 편함
  • 사용하고 있는 하위 모듈에서 발생하는 로깅 이벤트들도 쉽게 접근 가능
  • 로깅 레벨 설정 등을 통해 기록될 로그를 선택적으로 필터링 할 수 있음

Log Level

로그는 아래 목록 중 하나의 레벨을 가지며, 각 레벨의 로그는 각기 다른 용도를 지니고 있음

  • DEBUG: 프로그램 작동에 대한 상세한 정보를 가지는 로그. 문제의 원인을 파악할 때에만 이용
  • INFO: 프로그램 작동이 예상대로 진행되고 있는지 트래킹하기 위해 사용
  • WARNING: 예상치 못한 일이나 추후 발생 가능한 문제를 표시하기 위함
  • ERROR: 심각한 문제로 인해 프로그램이 의도한 기능을 수행하지 못하고 있는 상황을 표시
  • CRITICAL: 더욱 심각한 문제로 인해 프로그램 실행 자체가 언제라도 중단될 수 있음을 표시

Logger instance 생성

logger = logging.getLogger(__name__)
  • __name__ 자리에는 사용자가 지정하는 로거의 이름이 들어감
  • airflow에서는 __name__ 대신에 "airflow.task"를 사용하게 되면 task name에 대한 로그를 확인 할 수 있음
  • 비워 놓으면 자동으로 root 로거가 생성되며, 출력 시에도 로거 이름 자리에 root가 출력

Logger level 설정

logger.setLevel(logging.INFO) # logging level은 case sensitive하다
  • Airflow에서 로그가 안나오던 문제도 이 로깅레벨과 관련이 있었는데, airflow.cfg파일의 logging_level property가 error로 설정되어 있었던 것. 따라서 error 레벨 이상의 문제가 생기지 않는 이상 로그가 출력되지 않았던 현상
    -> code 내에서 setLevel로 logging level을 지정하거나, airflow.cfg에서 default logging level을 설정

Logger message 보내기

logger.info("원하는 로그")
logger.info(변수)
logger.info(f"출력되는 결과: {변수}")
  • 위의 Logger level이 info로 설정되거나 그보다 낮은 레벨로 설정되었다면, logger.info의 메세지가 airflow UI의 log에서도 확인 할 수 있게 됨

Handler, Formatter, Filter

1) Handler

  • 로그 이벤트를 파일이나 네트워크 소켓 등 적절한 곳으로 보내주는 역할
  • StreamHandler 클래스나 FileHandler 클래스를 인스턴스화해 로거에 attach 해 주는 식으로 이용

2) Formatter

  • 핸들러 클래스에 붙여 사용 asctime, levelname, message등을 로깅에 표현할 수 있음

3) Filter

  • 거 계층 구조에서 특정 구조 하위의 로거에서 처리하는 이벤트만을 처리하도록 필터링

2. Airflow에서 적용한 코드

import logging

task_logger = logging.getLogger("airflow.task")
task_logger.setLevel(logging.INFO)

def 함수():
	~~~
    task_logger.info(f"history data: {변수} has been deleted!")
    
##################################
# airflow 코드들                 #
##################################

 

 

다음 포스트에는 log4j를 정리하면서 logging과 비교해보겠습니다.

728x90