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