1. 기본 Rails 로그의 문제점과 개선 필요성
Rails의 기본 로거는 개발 초기에는 유용할 수 있으나, 실제 운영 환경에서는 다음과 같은 한계를 가집니다. - 장황한 멀티라인 출력: 하나의 요청이 여러 줄의 로그를 생성하여, 동시 다발적인 요청이 발생하는 서버에서는 로그가 뒤섞여 특정 요청의 흐름을 파악하기 매우 어렵습니다. - 비정형 데이터: 로그 형식이 표준화되어 있지 않아 EFK(Elasticsearch, Fluentd, Kibana)와 같은 분석 도구에서 필터링하거나 쿼리를 실행하기에 부적합합니다. - 디버깅 효율 저하: 중앙 집중식 로깅 시스템이 없으면 각 서버에 접속하여 tail 명령어로 로그를 확인해야 하며, 이는 확장성 있는 아키텍처에서 큰 비용을 발생시킵니다.
2. Lograge를 이용한 로그 압축 및 최적화
Lograge는 Rails의 기본 로그 출력을 단일 라인으로 변환해주는 강력한 Gem입니다. - 설치 및 설정: Gemfile에 lograge를 추가하고, application.rb 또는 환경별 설정 파일에서 config.lograge.enabled = true를 설정합니다. Lograge는 오랜 기간 커뮤니티에서 검증되었고 설정이 간편하여 Semantic Logger나 Logstasher보다 널리 사용됩니다. - 주요 기능: ActionController::Base를 상속받는 모든 컨트롤러의 로그를 캡처하며, 응답 시간, 상태 코드, 메서드, 경로 등의 핵심 메타데이터를 한 줄에 담아 출력합니다. - 메타데이터 확장: config.lograge.custom_options를 통해 request_id, host, remote_ip와 같은 추가 정보를 로그에 포함할 수 있습니다. 특히 request_id는 분산 시스템에서 요청의 전 과정을 추적하는 핵심 키 역할을 합니다.
3. 커스텀 로거를 통한 JSON 구조화 구현
Lograge는 주로 컨트롤러 로그에 집중하므로, 애플리케이션 내부 로직에서 발생하는 Rails.logger 호출도 구조화할 필요가 있습니다. - JSON 포맷터 정의: ActiveSupport::Logger::SimpleFormatter를 확장하거나 별도의 포맷터를 생성하여 로그 메시지를 JSON 객체로 변환합니다. 단순히 텍스트를 출력하는 것이 아니라 JSON.dump 형식을 취하게 함으로써, 로그 수집기가 별도의 파싱 과정 없이 데이터를 인덱싱할 수 있게 합니다. - 구현 예시: 로그 메시지에 timestamp, level, message, request_id 등을 포함하도록 설정합니다. 이는 CPU 자원 소모를 줄이고 데이터 정확도를 높이는 결과를 가져옵니다. - 통합 검색의 이점: 모든 로그가 JSON 형식이 되면, 로깅 플랫폼에서 특정 필드를 기준으로 정밀한 검색이 가능해지며, 이는 장애 복구 및 성능 분석 시간을 획기적으로 단축시킵니다.
4. 실무 적용 시 고려사항
- 환경별 설정: 개발 환경에서는 가독성을 위해 텍스트 형식을 유지하고, 스테이징 및 프로덕션 환경에서만 JSON 구조화 로깅을 활성화하는 것이 권장됩니다.
- 컨트롤러 상속 구조: config.lograge.base_controller_class 설정을 통해 Lograge가 감시할 컨트롤러 범위를 정확히 지정해야 정보 누락을 방지할 수 있습니다.
- 로그 전파: 획득한 request_id를 하위 서비스 호출이나 비동기 작업에도 전달하여 전체 시스템의 추적성(Traceability)을 확보해야 합니다.