효율적인 로깅을 위한 단계별 접근 방식은 다음과 같습니다.
1. Rails 기본 로거 이해
Rails는 내부적으로 ActiveSupport::Logger를 사용하며, Rails.logger.info, Rails.logger.warn 등으로 접근합니다. 로그 레벨은 debug < info < warn < error < fatal 순서로 심각도가 높아지며, 각각 개발/문제 해결, 비즈니스 이벤트, 예상치 못했지만 복구 가능한 상황, 사용자에게 보이는 실패에 사용됩니다.
2. 환경별 로그 레벨 설정
config/environments/production.rb에서 config.log_level = :info로 설정하고, config/environments/development.rb에서는 config.log_level = :debug로 설정하여 프로덕션 환경에 불필요한 디버그 로그가 쌓이는 것을 방지합니다.
3. 구조화된 로깅 (JSON) 활용
단순 텍스트 로그 대신 구조화된 JSON 로그를 사용하면 Datadog, ELK, CloudWatch와 같은 로그 프로세서에서 데이터를 쉽게 분석하고 활용할 수 있습니다. 예를 들어, Rails.logger.info(event: "user_created", user_id: user.id, email: user.email)와 같이 키-값 쌍으로 정보를 기록합니다.
4. 요청 컨텍스트 추가 (Request ID, User ID)
config/application.rb에 config.log_tags = [:request_id]를 추가하여 모든 로그 라인에 request_id를 자동으로 포함시킵니다. 또한, 현재 사용자(current_user.id)와 같은 추가 컨텍스트를 로그에 명시적으로 포함하여 프로덕션 디버깅을 10배 더 쉽게 만듭니다.
5. 민감 데이터 로깅 금지
비밀번호, 토큰, 신용카드 번호, API 키와 같은 민감한 정보는 절대 로그에 기록해서는 안 됩니다. config.filter_parameters += [:password, :token, :credit_card] 설정을 통해 Rails가 자동으로 이러한 파라미터를 필터링하도록 합니다.
6. 핫 경로 로깅 회피
items.each { |item| Rails.logger.debug item.inspect }와 같이 루프 내부에서 과도하게 로깅하는 것은 I/O 바운드 작업이므로 애플리케이션 성능에 심각한 영향을 미칩니다. 대신 Rails.logger.debug "Processed #{items.size} items"와 같이 요약된 정보를 기록합니다.
7. 도메인별 로거 생성
Rails.logger만 사용하는 대신, PAYMENT_LOGGER = Logger.new("log/payments.log")와 같이 특정 도메인(payments.log)에 대한 전용 로거를 생성하여 로그를 더 깔끔하게 관리하고 소유권을 명확히 합니다.
8. 컨텍스트와 함께 오류 로깅
단순히 “Something went wrong”과 같은 메시지 대신, Rails.logger.error(error: e.class.name, message: e.message, backtrace: e.backtrace.take(5), order_id: order.id)와 같이 오류 클래스, 메시지, 백트레이스 및 관련 컨텍스트를 포함하여 오류를 기록합니다.
9. 오류 및 로그 도구와 통합
Sentry 또는 Bugsnag와 같은 예외 추적 도구와 Datadog 또는 ELK 스택과 같은 로그 및 메트릭 도구를 통합하여 로그를 보완하고 전체적인 가시성을 확보합니다.
이러한 모범 사례를 통해 로깅은 단순한 기록을 넘어 강력한 디버깅 및 모니터링 도구로 기능할 수 있습니다.