[엉박사] 2.5.1 Logging

impala·2023년 1월 12일
0
post-thumbnail

2.5.1 Logging

프로젝트 막바지에는 서버를 배포하여 실제 환경에서 테스트하면서 새로운 기능들을 추가하는 방식으로 개발을 이어나갔는데, 로그의 중요성을 모르고 Nginx와 Django에 로깅 설정을 하지 않고 서버를 돌렸다. 그 결과, 서비스에 접속하여 테스트를 할 때 문제가 생기면 어떤 이유로 문제가 생긴건지 알수없어 그때마다 서버를 재부팅하고 같은 문제를 발생시켜 실시간으로 로그를 모니터링하면서 디버깅을 했다. 그 때라도 로그를 남기도록 설정을 할 수 있었지만 마감기한이 코앞이라 서비스 보수 외에는 신경을 쓸 겨를이 없어 불편함을 감수하고 그대로 진행하여 프로젝트를 마무리하게 되었다.

이를 계기로 코드를 서버에 올려 배포만 하면 끝인줄 알았지만 서비스의 유지보수도 꽤 비중이 있는 작업이라는 것을 깨달아서 다음부터는 같은 실수를 하지 않기 위해 로그에 대한 내용을 정리하였다.

Logging

Logging이란 로그를 남기는 행위로 로그란 소프트웨어가 실행중에 발생하는 이벤트나 통신 메세지를 시간 순서에 따라 기록한 파일이다. 로그를 남기는 이유는 로그의 종류에 따라 다르지만 공통적으로는 소프트웨어의 동작을 추적하기 위해 로그를 남기고, 이를 통해 버그에 대한 정보나 성능에 관한 통계정보를 얻을 수 있다.

로그에는 여러 정보가 포함되지만 아래의 항목들은 제외하는 것이 좋다

  • 큰 메세지나 파일내용 : 로그를 남기는 것 또한 비용에 속하기 때문에 큰 메세지는 요약해서 넣는 것이 좋음
  • 오류가 정상 실행과정의 일부일 경우 : 로그를 읽을 때 혼란을 줄 수 있음
  • 반복적인 에러 : 로그를 에러로 가득 채우게 되면 실제 오류를 숨길 수 있음

로그는 일반적으로 6가지 레벨로 나눈다

  1. TRACE : DEBUG보다 상세한 정보. 개발시 필요. DEBUG로 대체 가능
  2. DEBUG : 프로그램 디버깅 정보
  3. INFO : 상태변경 등 정보성 메세지
  4. WARN : 처리가능한 문제, 향후 문제가 될 가능성이 있는 것. INFO로 대체 가능
  5. ERROR : 요청 처리중 발생한 문제
  6. FATAL : 어플리케이션이 작동할 수 없는 심각한 에러. ERROR로 대체 가능

Nginx log

Nginx의 로그는 Access LogError Log 두 종류가 있다.

  • Access Log : 서버 접근 기록
    • /var/log/nginx/access.log에 저장
    • nginx.conf 파일의 http블록 안 access_log 항목에 로그가 저장될 경로와 형식을 지정할 수 있다.
      access_log  <로그 경로> <로그 형식>;
  • Error Log : 서버 에러 기록
    • /var/log/nginx/error.log에 저장
    • nginx.conf 파일 상단에 error_log 항목에 에러로그가 저장될 경로와 위에서 설명한 로그 레벨을 통해 원하는 레벨의 로그를 남길 수 있다
      ```conf
      error_log  <에러로그 경로> <에러로그 레벨>;
      ```
      위의 설정들을 server블록 안에 작성하면 각 서버별로 다른 파일에 로그를 남길 수 있다.

Nginx의 기본 로그 형식은 아래와 같다.

log_format  main    '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

로그의 형식은 http블록 안 log_format 항목을 통해 설정이 가능하다

log_format <포맷 이름>  '포맷'
                        '포맷'
                         ...;

Django log

장고 어플리케이션을 배포할 때에는 보안상 클라이언트에게 오류의 원인을 보여주면 안되기 때문에 settings.py의 DEBUG설정을 False로 바꾸어준다. 그렇기 때문에 배포 이후부터는 로컬환경에서 디버깅을 하던 방식으로는 디버깅을 할 수 없기 때문에 로그를 보고 문제를 고쳐야 한다.

장고에서 가장 기본적인 로그를 남기기 위해서는 settings.py의 LOGGING항목에 아래의 코드를 추가하면 로그를 파일로 남길 수 있다.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',                           # 로그 레벨
            'class': 'logging.FileHandler',
            'filename': '/path/to/django/debug.log',    # 로그 경로
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'WARNING',
    },
}

자세한 로그 설정은 장고 공식문서에서 확인할 수 있다.

Docker 설정

마지막으로 우리 서버는 도커 컨테이너 안에서 돌아가고 있기 때문에 컨테이너를 삭제하면 그 안에 있는 정보들도 지워지게 된다. 그러므로 로그와 같은 정보들은 볼륨마운트나 바인딩을 통해 컨테이너가 삭제되어도 영구적으로 남을 수 있도록 꺼내주는 것이 좋다.

우리는 docker-compose를 사용하여 컨테이너를 관리하므로 docker-compose.yml에 아래의 설정을 추가하여 로그를 컨테이너 외부에서도 확인할 수 있도록 한다.

services:
        # 서비스 이름
        nginx:
                volumes:
                # 컨테이너 속 /var/log/nginx경로의 파일을 컨테이너 외부 ./logs/ngnix와 연결
                    - ./logs/ngnix:/var/log/nginx
        django:
                volumes:
                # 장고에서 설정한 로그파일의 경로를 컨테이너 외부 ./logs/django와 연결
                    - ./logs/django:/path/to/django

이제 서비스에 문제가 생기면 서버 컨테이너에 직접 들어가지 않고도 컨테이너 외부에서 로그를 확인할 수 있다.

0개의 댓글