대부분의 사람들은 로그가 가장 필요할 때만 로그의 필요성을 깨닫습니다. 하지만 애플리케이션이 중단되고 사용자 불만이 넘쳐나기 시작하면 이를 해결하는 방법을 전혀 모르므로 도움이 될 만한 로그 메시지를 추가하기에는 너무 늦습니다.
좋은 통나무는 그 자체로 10배의 가치를 지닙니다. 까다로운 버그를 쉽게 진단할 수 있으며, 로그를 올바르게 작성하면 사용자가 알기 전에도 문제에 대해 경고할 수 있습니다. 그런데 '로깅을 제대로 한다'는 게 무슨 뜻인가요?
로깅은 시작하기 쉽지만 마스터하기는 어렵습니다. 이 게시물에서는 Rails 애플리케이션의 로그를 최대한 활용하는 방법에 대해 자세히 알아보겠습니다.
Rails에 로그인
먼저 기본 사항에 대해 이야기 해 봅시다. 새로운 Rails 애플리케이션을 시작하면 로깅이 이미 설정되어 있습니다. Rails는 ActiveSupport::Logger의 새 인스턴스를 초기화합니다. 애플리케이션 내 어디에서나 사용할 수 있습니다.
Rails 로거는 표준 출력 또는 log/<environment>.log에 씁니다. 명시적으로 작성한 로그 메시지 외에 들어오는 요청이나 실행된 쿼리를 자동으로 기록합니다.
Rails 문서에 훌륭하게 설명되어 있듯이 Rails 로그를 구성할 수 있는 방법은 다양합니다.
로그를 최대한 활용하기 위해 로그 수준 및 로그 형식을 삽입하는 데 특히 관심이 있습니다.
하지만 그 문제를 다루기 전에 로그를 작성해야 하는 이유에 대해 이야기해 보겠습니다.
좋은 로깅, 나쁜 로깅
로그의 목적은 시스템 이벤트에 대해 알리고 이에 대응할 수 있도록 하는 것입니다. 예를 들어, 오류가 발생하면 로그 메시지를 통해 사용자가 이해할 수 있는 방식으로 이에 대해 알려주어야 합니다.
로그 메시지를 얼마나 잘 이해하는지는 메시지가 얼마나 설명적이고 상황에 맞는지에 따라 달라집니다. 설명 로그 메시지는 발생한 일에 대한 관련 정보를 제공합니다. 상황별 로그 메시지에는 시스템이 기록할 당시의 시스템 상태에 대한 정보가 포함됩니다.
두 가지가 모두 필요한 이유를 알아보기 위해 간단한 예를 살펴보겠습니다. 다음은 외부 API를 호출하고 사용자가 요청을 수행할 때 응답을 반환하는 코드입니다.
이제 고객이 문제를 보고하고 도움을 받기 위해 로그를 조사하는 상황을 상상해 보겠습니다. 다음과 같은 내용을 보실 수 있습니다:
이러한 로그 메시지는 일부 정보를 제공하지만 거의 충분하지 않습니다. 고객이 보고한 오류의 원인을 찾는 데 더 이상 가까워지지 않았습니다. 이러한 로그 메시지에는 설명과 컨텍스트가 부족합니다. 그들은 소음이 있습니다. 어떻게 개선할 수 있나요?
Rails의 로그 수준
기본 Rails 로거는 로그 수준 DEBUG를 제공합니다. , INFO , WARN 및 ERROR . 이를 사용하면 로그 메시지를 다양한 관련 카테고리로 그룹화할 수 있습니다. 이는 로그 메시지를 필터링하는 데 도움이 될 뿐만 아니라 일부 컨텍스트도 제공합니다.
언제 어떤 로그 수준을 사용할지 결정하는 것은 어려울 수 있습니다. 다음은 몇 가지 경험 법칙입니다:
DEBUG:시스템 내에서 발생하는 작업에 대한 자세한 정보를 보려면 이 로그 수준을 사용하세요. 메소드가 시작되거나 종료될 때 또는 디버깅 중에 가치를 추가할 수 있다고 생각되는 모든 곳에서 디버그 문을 사용할 수 있습니다.INFO:시스템 상태가 변경되거나 관련 이벤트가 발생할 때마다INFO에 도달하세요. 수준. Rails 애플리케이션의 맥락에서 일반적인 정보 메시지의 예로는 요청 수신, 외부 API로 전송된 요청, 작업 시작 및 종료 등이 있습니다.WARN:이 로그를 사용하여 예상치 못한 일이 발생했음을 나타냅니다. 아직은 문제가 되지 않습니다(애플리케이션에서 처리할 수 있기 때문에). 그러나 문제가 계속 발생하면 주의를 기울여야 할 수도 있습니다.ERROR:오류가 발생한 경우 이 로그 수준을 사용합니다. 오류는 가능한 한 빨리 해결해야 하는 잘못된 애플리케이션 상태입니다.
해당 환경 파일을 수정하여 애플리케이션이 작성하는 로그 메시지의 종류를 변경할 수 있습니다. 일반적으로 Rails는 DEBUG을 삭제합니다. 메시지는 제작 중이지만 변경할 수 있습니다.
위의 로그 수준 제안을 코드 샘플에 적용해 보겠습니다.
디버깅할 때 이제 WARN를 조사하여 문제의 근본 원인을 식별할 수 있습니다. 및 ERROR 메시지. 안타깝게도 우리의 로그 메시지는 더 이상 설명적이지 않습니다.
설명 로그 메시지
설명적인 로그 메시지는 해석의 여지를 남기지 않습니다. 독자에게 무슨 일이 일어났는지 즉각적으로 알리는 데 필요한 세부 정보를 제공합니다.
'An error occurred'와 같은 메시지를 읽을 때 , 오류가 무엇인지 궁금합니다. 로그 메시지를 작성할 때 이러한 혼란을 피하고 싶습니다. 설명적인 로그 메시지를 작성할 때 가장 중요한 것은 로그 판독기의 입장에서 생각하는 것입니다. 로그를 읽을 때 필요한 모든 정보를 얻을 수 있나요?
'An error occurred' 메시지를 변경해 보겠습니다. 메시지를 포함하여 오류 자체에 대한 정보입니다.
그것은 개선입니다. 예제에서 다른 로그 메시지를 확인해 보겠습니다. 'Method entered' 어떤 메소드가 호출되었는지 알려주지 않습니다('Response success'). 실제 응답을 생략하고 'Response failure' 오류의 성격에 대한 정보를 제공하지 않습니다. 바꿔보자.
참고 :로그에 문자열 보간을 수행할 때 블록 구문을 사용한다는 것을 눈치채셨을 것입니다. 이를 사용하면 애플리케이션의 로그 수준이 로그 메시지 수준보다 높을 때 불필요한 계산을 피할 수 있습니다. 예를 들어 log.debug("Some #{concatenation}") 항상 문자열 연결을 수행하지만 log.debug { "Some #{concatenation}" } 로그 수준이 디버그로 설정된 경우에만 그렇게 합니다.
이제 로그를 훨씬 더 잘 읽을 수 있습니다. 각 로그 메시지가 무엇을 의미하는지에 대해서는 의심의 여지가 없습니다.
로그 메시지에 대한 추가 컨텍스트
새로운 로그 메시지는 무슨 일이 일어났는지 명확하게 보여줍니다. 이것은 간단한 예이기 때문에 우리는 왜 어떤 일이 일어났는지 잘 이해하고 있습니다. 실제로는 대개 그렇게 쉽지 않습니다.
시스템이 각 메시지를 작성한 컨텍스트에 대한 추가 정보를 제공하면 디버깅에 큰 도움이 될 수 있습니다.
예를 들어, 요청이나 응답을 기록할 때 누가 요청을 수행했는지 아는 것이 도움이 될 수 있습니다. 오류에 대한 스택 추적을 첨부하면 오류가 발생한 이유에 대한 추가 정보를 수집할 수 있어 유용할 수 있습니다.
참고 :Rails의 기본 로거를 사용할 때 상황별 정보가 포함된 로그 메시지를 생성하는 것이 번거로울 수 있다는 점을 눈치채셨을 것입니다. 다행히 Ougai 또는 MrLogaLoga와 같은 맞춤 로거를 사용하면 이 작업이 훨씬 쉬워집니다.
구조화된 로깅
로그를 사람이 읽을 수 있도록 만들면 다음 단계로 나아갈 준비가 된 것입니다. 이제 모니터링 및 데이터 분석에 사용할 수 있도록 로그를 컴퓨터에서 읽을 수 있도록 설정해야 합니다.
제가 선호하는 형식은 JSON이지만 사용하는 도구에 따라 Logstash와 같은 다른 로그 형식을 선호할 수도 있습니다. 사용자 정의 로그 포맷터를 생성하여 로그 메시지의 형식을 변경할 수 있습니다.
사용자 정의 포맷터를 직접 작성하는 대신 사용자 정의 로그 포맷터를 제공하는 많은 gem 중 하나를 사용할 수 있습니다. 즉시 사용 가능한 형식을 제공할 뿐만 아니라 Rails의 다소 장황한 요청 형식을 정리하여 읽기가 훨씬 쉬운 Lograge를 권장합니다.
AppSignal을 사용한 Rails 로깅
이제 로그가 훌륭하고 읽기 쉬우므로 더 쉽게 접근할 수 있게 만드는 것이 좋습니다. 결국, 일부 시스템에 SSH를 통해 로그를 추적하거나 수집하고 싶지는 않을 것입니다. 그렇죠?
다행히 AppSignal은 최근 베타 버전의 로깅 기능을 출시했습니다! 이를 통해 AppSignal 웹 인터페이스에서 직접 Rails 로그를 검사하고 분석할 수 있습니다.
왼쪽 메뉴의 '로깅' 탭을 통해 로깅 베타에 액세스할 수 있습니다:

Ruby 로깅 문서의 단계를 따르면 AppSignal::Logger을 사용하도록 Rails Logger를 구성할 수 있습니다. config/environment.rb에 아래 코드를 삽입하여 클래스를 만듭니다. initialization 이전 파일 :
JSON 형식이나 Lograge를 사용하여 구조화된 로그를 수집할 수도 있습니다.
모든 설정이 완료되면 AppSignal에 Rails 로그가 표시됩니다!

로깅 및 오류 보고
AppSignal 블로그에서 이 내용을 읽고 계시다면 '이미 훌륭한 오류 보고 플랫폼을 사용하고 있는데 왜 로깅에 신경을 써야 합니까?'라고 궁금해하실 수도 있습니다.
좋은 질문입니다. 오류 추적 도구는 응용 프로그램 오류에 대한 자세한 정보를 제공합니다. 이는 모든 애플리케이션 오류의 전체 스택 추적을 캡처하고 즉시 사용할 수 있는 많은 컨텍스트 정보를 제공합니다.
그러나 대부분의 도구를 사용하면 오류 이외의 이벤트를 캡처할 수 있지만 이러한 도구에 임의의 양의 메시지를 보내는 것은 일반적으로 불가능합니다. 잘 작성된 로그가 제공하는 상세한 기록 정보는 대체할 수 없습니다.
실제로 잘 작성된 로그는 오류 추적 도구를 강화하고 지원합니다. 둘 다 사용해야 할 것 같습니다.
마무리
이번 게시물에서는 로그를 최대한 활용하는 방법을 살펴보았습니다. Rails에 로그인을 시작하는 것은 쉽지만 유용한 로그를 작성하는 것은 어려울 수 있다는 것을 확인했습니다.
설명이나 컨텍스트가 부족한 로그는 가치를 거의 제공하지 못하고 디스크만 가득 채우게 됩니다. 그러나 올바른 로그 수준을 사용하고 독자에게 필요한 정보를 제공하는 로그는 훌륭한 자산입니다.
훌륭한 로그 메시지 작성을 마스터한 후에는 더 나아가 로그 분석 및 간편한 필터링이 가능한 방식으로 형식을 지정할 수 있습니다.
또한 AppSignal의 새로운 로깅 기능을 사용하여 로그에 쉽게 액세스하는 방법도 살펴보았습니다. 마지막으로 로그가 오류 추적 도구를 대체하기보다는 어떻게 강화해야 하는지에 대해 다루었습니다.
즐거운 기록 되세요!
추신 Ruby Magic 게시물이 보도되는 즉시 읽으려면 Ruby Magic 뉴스레터를 구독하고 단 하나의 게시물도 놓치지 마세요!
한스 외르크 슈네들리츠
객원 저자인 Hans는 오스트리아 비엔나 출신의 Rails 엔지니어입니다. 그는 대부분의 시간을 코딩하거나 코딩에 관한 독서를 하며 보내고 때로는 블로그에 이에 관한 글을 쓰기도 합니다! 그가 스크린 앞에 앉아 있지 않을 때는 아마도 밖에서 산을 오르고 있는 모습을 볼 수 있을 것입니다.
Hans-Jörg Schnedlitz의 모든 기사