ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] logging + argparse: 실무형 CLI 스크립트 패턴
    업무 자동화/Python 2025. 12. 7. 07:48

    1. argparse 기본 사용법

    import argparse
    
    parser = argparse.ArgumentParser(description="간단한 예제 스크립트")
    parser.add_argument("--name", required=True, help="인사할 이름")
    args = parser.parse_args()
    
    print(f"안녕, {args.name}!")

    실행 예시:

    python script.py --name Alice

    1-1. 다양한 인자 타입

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--count", type=int, default=1)
    parser.add_argument("--debug", action="store_true")
    args = parser.parse_args()
    
    print("count:", args.count)
    print("debug:", args.debug)
    • type=int : 정수로 변환
    • default : 기본값
    • action="store_true" : 플래그 옵션 (있으면 True, 없으면 False)

    1-2. 필수 인자와 위치 인자

    parser = argparse.ArgumentParser()
    parser.add_argument("input", help="입력 파일 경로")     # 위치 인자
    parser.add_argument("output", help="출력 파일 경로")    # 위치 인자
    python script.py input.txt output.txt

     

    2. logging 기본 사용법

    import logging
    
    logging.basicConfig(level=logging.INFO)
    
    logging.debug("디버그 메시지")
    logging.info("정보 메시지")
    logging.warning("경고 메시지")
    logging.error("에러 메시지")
    logging.critical("치명적 에러")
    • levelINFO로 두면 DEBUG는 출력되지 않음
    • 기본 포맷: LEVEL:root:메시지

    2-1. 포맷 커스터마이즈

    import logging
    
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(levelname)s] %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )
    
    logging.info("로그 설정 예시")

    출력 예시:

    2025-12-02 13:45:00 [INFO] 로그 설정 예시

     

    3. logging으로 파일 로그 남기기

    import logging
    
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(levelname)s] %(message)s",
        handlers=[
            logging.FileHandler("app.log", encoding="utf-8"),
            logging.StreamHandler(),  # 콘솔에도 동시에 출력
        ],
    )
    
    logging.info("프로그램 시작")
    logging.error("에러 발생 예시")
    • handlers 리스트를 사용해 여러 출력 채널을 동시에 설정
    • FileHandler로 파일에, StreamHandler로 콘솔에 로그 저장

     

    4. argparse + logging 통합 패턴

    4-1. verbose 옵션으로 로그 레벨 조절

    import argparse
    import logging
    
    def parse_args():
        parser = argparse.ArgumentParser(description="데모 스크립트")
        parser.add_argument("--input", required=True, help="입력 파일 경로")
        parser.add_argument("--output", required=True, help="출력 파일 경로")
        parser.add_argument(
            "--verbose",
            action="store_true",
            help="디버그 로그 출력 여부",
        )
        return parser.parse_args()
    
    def setup_logging(verbose: bool):
        log_level = logging.DEBUG if verbose else logging.INFO
        logging.basicConfig(
            level=log_level,
            format="%(asctime)s [%(levelname)s] %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )
    
    def main():
        args = parse_args()
        setup_logging(args.verbose)
    
        logging.info("입력: %s", args.input)
        logging.info("출력: %s", args.output)
        logging.debug("디버그 상세 정보 예시")
    
        # 실제 처리 로직 자리
        logging.info("처리 완료")
    
    if __name__ == "__main__":
        main()

    실행:

    python app.py --input in.txt --output out.txt
    python app.py --input in.txt --output out.txt --verbose
    • --verbose 추가 여부에 따라 INFO/DEBUG 레벨 전환

     

    5. 에러 처리 + 종료 코드 패턴 (sys와 함께)

    import argparse
    import logging
    import sys
    
    def parse_args():
        parser = argparse.ArgumentParser(description="리포트 생성기")
        parser.add_argument("--source", required=True)
        parser.add_argument("--dest", required=True)
        return parser.parse_args()
    
    def setup_logging():
        logging.basicConfig(
            level=logging.INFO,
            format="%(asctime)s [%(levelname)s] %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )
    
    def main():
        args = parse_args()
        setup_logging()
    
        logging.info("리포트 생성 시작")
        logging.info("source=%s, dest=%s", args.source, args.dest)
    
        try:
            # TODO: 실제 리포트 생성 로직
            # 예: 파일 읽기, 가공, 결과 저장 등
            logging.info("리포트 생성 성공")
            return 0
        except Exception as e:
            logging.exception("리포트 생성 중 에러 발생: %s", e)
            return 1
    
    if __name__ == "__main__":
        code = main()
        sys.exit(code)
    • logging.exception(...) 은 traceback까지 함께 출력
    • sys.exit(code)로 종료 코드를 반환 → 상위 시스템/배치에서 성공/실패 판단 가능
Designed by Tistory.