소프트웨어의 버그는 파괴적이고 파악하기 어렵고 짜증나고 침입적일 수 있습니다. 실제로 개발자는 문제를 찾아 해결하기 위해 Edison의 끈기가 필요한 경우가 많습니다.
하지만 그릿만이 개발자에게 필요한 유일한 자산은 아닙니다. 코드를 디버깅하려면 다음과 같은 정보도 필요합니다. 문제의 증상과 영향은 무엇입니까? 빈도는 얼마나 됩니까? 보급성? 기원? 코어 덤프, 스택 추적, 로그, 테스트 사례 등 버그의 증거와 아티팩트는 매우 중요합니다.
문제의 증거를 수집하고 조사하기 위해 Ruby 및 Rails 개발자가 쉽게 사용할 수 있는 몇 가지 기술과 도구를 살펴보겠습니다. 데이터는 끈기를 대체할 수 없지만 노력을 쉽게 하고 잠을 자게 하는 데 도움이 될 수 있습니다.
Rails는 자체 진단과 추가하려는 모든 진단을 캡처하는 configurableLogger를 포함하여 실행 중인 애플리케이션을 들여다볼 수 있는 몇 가지 훌륭한 도구를 제공합니다. Rails는 또한 데이터베이스 쿼리의 출처를 정확히 찾아내는 자세한 쿼리 로그와 백그라운드 작업이 대기 중인 위치를 밝히는 자세한 대기열 로그를 제공합니다. 후자의 두 로그는 development에서 기본적으로 활성화됩니다. 환경; 두 개의 명령문을 사용하여 다른 환경에서 두 가지를 모두 활성화할 수 있습니다.
Rails 7이 각 SQL 쿼리에 주석을 달기 때문에 잘 알려지지 않은 로그 옵션을 사용할 수 있습니다. config/application.rb에 다음을 추가하면 또는 환경 파일:
쿼리 로그는 애플리케이션 이름, 컨트롤러 이름, 작업 이름 또는 백그라운드 작업 이름으로 자동 수정됩니다. 다음 샘플 출력은 Rails 디버깅 가이드에서 직접 가져온 것입니다:
프로덕션에서는 이러한 모든 기능을 활성화하고 싶지 않을 것입니다. 로그 생성은 메모리와 시간(로드 중인 애플리케이션을 위한 한정된 리소스) 측면에서 비용이 많이 들 수 있습니다.
그러나 예외가 있습니다. 특히 개발 중 및 테스트 모드를 디버깅할 때 주문형 기능을 간단히 활성화할 수 있습니다. 진단을 활성화하거나 비활성화하기 위해 코드를 변경(및 재배포)하는 대신 환경 변수를 사용하여 상태를 제어하십시오. Heroku와 같은 일부 환경에서는 환경 변수 설정을 변경해도 새로운 배포가 필요하지 않습니다.
예를 들어, 로깅 및 자세한 정도를 제어하는 변수 세트를 정의할 수 있습니다.
편의를 위해 구성 설정을 쿼리하는 작은 클래스를 만듭니다.
이제 config/application.rb에서 변수와 코드를 사용하여 로깅 기능을 설정합니다. :
셸, dotenv 파일, 지속적 통합 또는 호스팅 및 배포 플랫폼을 사용하여 각 옵션을 설정하세요. 필요에 따라 기능을 사용할 수도 있습니다. 명령줄에 정의된 환경 변수를 사용하여 응용 프로그램을 시작하기만 하면 됩니다.
개발을 위해 Puma 조정
이전 섹션을 바탕으로 환경 변수를 사용하여 개발 환경에서 디버깅할 수 있도록 Puma 구성을 조정하는 방법을 살펴보겠습니다.
일반적으로 Puma는 여러 작업자와 작업자당 많은 스레드를 실행하여 프로덕션 처리량을 최대화하도록 구성됩니다. 개발 중에는 대화형 디버깅을 허용하기 위해 하나의 작업자, 하나의 스레드 및 매우 긴 시간 초과 등의 반대 방법을 원합니다. 이들 각각은 조정할 수 있는 매개변수입니다.
config/puma.rb 변경 다음 코드를 반영합니다.
이제 각 환경에서 Puma를 제어하기 위해 세 가지 환경 변수를 구성할 수 있습니다. 개발 중에는 대화형 디버깅을 위해 최적화할 값을 설정하세요.
Puma 설정을 확인하려면 환경 변수 PUMA_LOG_CONFIG=true를 설정하세요. 그리고 애플리케이션을 시작하세요. Puma는 시작 시 활성 구성을 내보냅니다.
공교롭게도 최신 Rails 릴리스의 기본 Puma 구성은 여기에 표시된 것과 유사합니다(팁을 주신 Nate Matykiewicz에게 감사드립니다).
백그라운드 작업 인라인 실행
복잡한 Rails 애플리케이션은 일반적으로 백그라운드 작업을 활용하여 컴퓨팅 집약적이고 (상대적으로) 장기 실행 작업을 실행합니다. 백그라운드 작업은 요청/응답 주기와 연결이 끊어져 비동기식으로 실행됩니다. "대역 외" 처리에 이상적인 후보로는 보고서 생성, 이메일 전송, 타사 API와의 상호 작용 등이 있습니다. 그러나 작업의 비동기적 특성으로 인해 디버깅도 복잡해집니다.
문제 해결을 단순화하려면 즉시 작업을 실행하세요. 로컬 개발 및 테스트 환경에서. 즉시 모드에서는 작업이 대기열에 추가되지 않고 즉시 실행됩니다. "포그라운드"에서 실행하면 중단점을 설정하고 대화형으로 상태를 검사할 수 있습니다.
인기 있고 관리하기 쉬운 Active Job용 대기열 백엔드인 Delayed Job을 사용한 예를 살펴보겠습니다. 지연된 작업은 대기열을 활성화하는 설정을 제공합니다. 기본적으로 설정은 true입니다. 작업은 평소와 같이 대기열에 추가됩니다. 단, false으로 설정하면 , 작업이 즉시 실행됩니다.
config/initializers/delayed_job.rb의 애플리케이션에 다음 코드를 추가하세요. :
DELAYED_JOBS_DISABLE_JOB_QUEUES인 경우 임의의 값으로 설정되면 대기열이 비활성화됩니다. 환경 변수가 비어 있거나 정의되지 않은 경우 대기열이 활성화됩니다.
그런 다음 셸, 명령줄 또는 도트 파일에서 DELAYED_JOBS_DISABLE_JOB_QUEUES을 설정합니다. 필요에 따라.
대기열을 복원하려면 환경 변수를 아무것도 설정하지 않거나 환경 변수를 삭제하세요.
환경 변수의 이름을 지정하는 규칙은 없습니다. 자신에게 의미 있는 이름을 선택하세요. 변수를 분류하는 데 유용한 규칙 중 하나는 PUMA_와 같이 패키지 이름을 접두사로 추가하는 것입니다. 및 DELAYED_JOB_ . 전자는 푸마에 영향을 미치는 변수를 의미한다. 후자는 지연된 작업에서 사용되는 변수를 의미합니다.
Peer Into Network 통화
백그라운드 작업과 마찬가지로 Rails 애플리케이션도 API(애플리케이션 프로그래밍 인터페이스)를 사용할 수 있습니다. API는 GraphQL 데이터베이스, 전자상거래 거래, 공개 데이터 소스와 같은 외부 서비스에 대한 액세스를 제공합니다.
다음은 Net::HTTP에서 조건부로 HTTP 요청과 응답을 내보내는 또 다른 예입니다. 도서관. 환경 변수가 DEBUG_HTTP인 경우 공백이 아닌 값으로 설정되면 나가는 요청과 들어오는 응답이 STDOUT으로 인쇄됩니다. .
네트워크 활동을 보려면 명령줄에 정의된 환경 변수를 사용하여 애플리케이션을 시작하면 됩니다.
debug? 메소드는 실제 플래그 구현에서 일부 추상화를 제공합니다. 이 코드와 이 코드의 나머지 부분은 프로덕션 코드에서 가져온 이 요점에 표시된 것처럼 모든 네트워크 요청에 대한 기본 클래스를 형성할 수 있습니다.
Ruby gem의 세계는 광대합니다. 디버깅에 사용할 수 있는 훌륭한 gem을 모두 포괄하는 것은 불가능합니다. 대신, 즉각적인 성능 향상을 위해 오늘 추가할 수 있는 몇 가지 도구를 살펴보겠습니다. 아마도 모든 프로젝트에 이들 각각을 추가하게 될 것입니다.
-
awesome_print그리고table_printActive Record 모델을 포함하여 Ruby 데이터 구조에 대한 풍부하고 읽기 쉬운 검사를 생성합니다. gemin 코드를 사용하거나 콘솔에서 사용할 수 있습니다.다음은
awesome_print에서 내보낸 모델의 예입니다. 콘솔에서:p대신 ,ap를 사용하세요 향상된 출력을 보여줍니다. awesome_print 속성은 알파벳 순서로 한 줄에 하나씩 나열됩니다. -
better_errors표준 Rails 오류 페이지를 향상된 스택 역추적, 매개변수 목록 및 예외 현장에서 스택 프레임과 변수를 조사할 수 있는 대화형 콘솔로 대체합니다. 즐겨찾는 편집기에 소스 코드 링크를 연결할 수도 있습니다.better_errors를 연결하는 코드는 다음과 같습니다. Visual Studio Code로:export BETTER_ERRORS_EDITOR=vscode실행 셸에서 Rails 서버를 다시 시작하세요. 이제 파일 링크가 Visual Studio에서 자동으로 열립니다. -
faker를 유지하세요 및factory_botGemfile의 테스트 및 개발 그룹에 있는 gem(또는 그 대안) . 콘솔에서 데이터를 빠르게 생성해야 하는 경우 둘 다 매우 중요합니다.
한 가지 추가 아이디어:AppSignal을 애플리케이션 모니터링 도구로 사용하는 경우 로그를 해석하고 오류 소스를 찾아내는 기능이 있습니다. 자세한 내용은 AppSignal을 사용하여 Ruby에서 디버깅을 참조하세요.
디버깅은 기술입니다
코드 디버깅은 일종의 예술이며 다른 창의적인 노력과 마찬가지로 연습을 많이 할수록 실력이 향상됩니다.
다른 개발자, 특히 숙련된 개발자와 페어링하면서 디버그하세요. 파트너가 의향이 있다면 함께 큰 소리로 생각하고 예감과 통찰력을 교환하세요.
가서 해킹하세요!
추신 Ruby Magic 게시물이 보도되는 즉시 읽으려면 Ruby Magic 뉴스레터를 구독하고 단 하나의 게시물도 놓치지 마세요!
마틴 스트라이허
우리의 게스트 저자인 Martin은 전문적인 Ruby 개발자입니다. 그는 퍼듀 대학교에서 컴퓨터 과학 분야의 고급 학위를 취득했으며, 5년 동안 Linux Magazine(미국)의 편집장을 역임했으며, IBM의 이전 DeveloperWorks 포털에 게재된 "Speaking in Unix" 칼럼의 창립 저자였습니다. 코딩이나 코드에 관한 글을 쓰지 않을 때는 예술품을 수집하고 많은 작은 개들과 논쟁을 벌입니다.
Martin Streicher의 모든 기사