소개
효과적인 로깅 솔루션은 어떤 애플리케이션의 성공에 있어서 중요합니다. Winston은 다양한 저장 옵션, 로그 레벨, 로그 쿼리 및 내장 프로파일러를 지원하는 유연한 로깅 라이브러리로, Node.js 애플리케이션에서 사용할 수 있는 인기 있는 로깅 솔루션입니다.
이 자습서에서는 이 프로세스의 일부로 생성할 Node/Express 애플리케이션을 로깅하기 위해 Winston을 사용합니다. 또한 Node.js용 다른 인기 있는 HTTP 요청 미들웨어 로거 인 Morgan을 Winston과 결합하여 HTTP 요청 데이터 로그를 다른 정보와 통합하는 방법을 살펴볼 것입니다. 이 자습서를 완료하면 Ubuntu 서버에서 작은 Node/Express 애플리케이션이 실행되며 Winston이 오류와 메시지를 파일과 콘솔에 기록하는 방법을 구현하게 됩니다.
필수 조건
이 자습서를 따르려면 다음이 필요합니다:
-
초기 서버 설정을 따라 설정할 수 있는 sudo 비루트 사용자가 있는 Ubuntu 20.04 서버.
-
Node.js는 공식 PPA(개인 패키지 아카이브)를 사용하여 설치되었습니다. 이에 대한 설명은 Ubuntu 20.04에 Node.js 설치 방법, 옵션 2에서 설명되어 있습니다.
단계 1 — 기본 Node/Express 앱 생성
Winston은 Node.js로 작성된 웹 애플리케이션에서 이벤트를 로깅하는 데 자주 사용됩니다. 이 단계에서는 Express 프레임워크를 사용하여 간단한 Node.js 웹 애플리케이션을 만들 것입니다. 빠르게 Node/Express 웹 애플리케이션을 실행하기 위해 명령줄 도구인 express-generator
를 사용할 것입니다.
선행 작업 중에 Node Package Manager가 설치되었으므로 npm
명령을 사용하여 express-generator
를 설치할 수 있습니다:
-g
플래그는 패키지를 전역적으로 설치하며, 이는 기존의 노드 프로젝트/모듈 외부에서 명령줄 도구로 사용할 수 있음을 의미합니다.
express-generator
가 설치되어 있으면 express
명령 다음에 프로젝트에 사용할 디렉토리 이름을 붙여 앱을 만들 수 있습니다:
이 튜토리얼에서 프로젝트는 myApp
이라고 하겠습니다.
참고: 또한 전역으로 시스템 전체 명령어로 먼저 설치하지 않고 express-generator
도구를 직접 실행할 수도 있습니다. 이를 위해 다음 명령을 실행하십시오:
npx
명령은 노드 패키지 매니저와 함께 제공되는 명령 실행기로, npm
레지스트리에서 명령줄 도구를 쉽게 실행할 수 있습니다.
첫 실행 시 패키지를 다운로드할 것에 동의하는지 물어봅니다:
Need to install the following packages:
express-generator
Ok to proceed? (y)
y
를 입력하고 ENTER
를 누르세요. 이제 npx express-generator
를 express
대신 사용할 수 있습니다.
다음으로 Nodemon을 설치하세요. 이는 변경 사항이 있을 때마다 응용 프로그램을 자동으로 다시로드합니다. 노드.js 응용 프로그램은 변경 사항이 있을 때마다 소스 코드가 변경되어야 하므로 변경 사항이 적용되기 위해 재시작해야 합니다. 따라서 Nodemon은 변경 사항을 자동으로 감지하고 응용 프로그램을 다시 시작합니다. nodemon
을 명령줄 도구로 사용할 수 있어야 하므로 -g
플래그로 설치하세요:
응용 프로그램 설정을 완료하려면 응용 프로그램 디렉토리로 이동하여 다음과 같이 종속성을 설치하세요:
기본적으로 express-generator
로 생성된 애플리케이션은 포트 3000
에서 실행되므로 방화벽이 해당 포트를 차단하지 않도록해야합니다.
포트 3000
을 열려면 다음 명령을 실행하십시오:
이제 웹 애플리케이션을 시작하는 데 필요한 모든 것이 준비되었습니다. 다음 명령을 실행하여 시작하십시오:
이 명령은 애플리케이션을 포트 3000
에서 시작합니다. 작동 여부를 확인하려면 브라우저를 http://your_server_ip:3000
으로 지정하십시오. 다음과 같은 내용이 표시됩니다:
이 시점에서 튜토리얼의 나머지 부분을 위해 서버에 두 번째 SSH 세션을 시작하여 방금 시작한 웹 애플리케이션을 원래 세션에서 실행한 채로 남겨둘 수 있습니다. 이제 이 세션은 세션 A라고합니다. 세션 A에서 실행되는 모든 명령은 이와 같이 진한 남색 배경에 나타납니다:
새로운 SSH 세션은 명령을 실행하고 파일을 편집하는 데 사용됩니다. 이 세션은 세션 B라고합니다. 세션 B에서 실행되는 모든 명령은 이와 같이 연한 파란색 배경에 나타납니다:
그렇지 않은 경우에는 모든 남은 명령을 세션 B에서 실행합니다.
이 단계에서 기본 앱을 만들었습니다. 다음으로 사용자 정의할 것입니다.
단계 2 — 로깅 변수 사용자 정의
기본 응용 프로그램은 express-generator
에 의해 생성되었으며 좋은 시작입니다. 그러나 필요할 때 올바른 로거를 호출하도록 응용 프로그램을 사용자 정의해야 합니다.
express-generator
에는 모든 HTTP 요청에 대한 데이터를 로그로 기록할 Morgan HTTP 로깅 미들웨어가 포함되어 있습니다. Morgan은 출력 스트림을 지원하므로 Winston에 내장된 스트림 지원과 잘 어울립니다. 이를 통해 HTTP 요청 데이터 로그를 Winston으로 기록하는 것 외에도 선택한 다른 모든 것을 로그로 통합할 수 있습니다.
express-generator
보일러플레이트는 morgan
패키지를 참조할 때 logger
변수를 사용합니다. 여기서는 morgan
과 winston
을 모두 사용할 예정이므로 둘 중 하나를 logger
라고 부르는 것은 혼란스러울 수 있습니다. 어떤 변수를 원하는지 지정하려면 app.js
파일을 편집하여 변수 선언을 변경할 수 있습니다.
app.js
를 편집하려면 nano
또는 즐겨 사용하는 텍스트 편집기를 사용하세요:
파일 상단 근처에 다음 라인을 찾으세요:
변수 이름을 logger
에서 morgan
으로 변경하세요:
이 업데이트는 선언된 변수 morgan
이 Morgan 요청 로거에 연결된 require()
메서드를 호출하도록 지정합니다.
logger
변수가 파일에서 어디에서 또 참조되었는지 찾아서 morgan
으로 변경해야합니다. 또한 morgan
패키지에서 사용되는 로그 형식을 combined
으로 변경해야합니다. 이것은 표준 Apache 로그 형식이며 로그에 원격 IP 주소와 사용자 에이전트 HTTP 요청 헤더와 같은 유용한 정보가 포함됩니다.
이를 위해 다음 줄을 찾으세요:
다음과 같이 업데이트하십시오:
이 변경 사항은 Winston 구성을 통합 한 후에 언제든지 어떤 로깅 패키지가 참조되는지 이해하는 데 도움이됩니다.
작업을 마치면 파일을 저장하고 닫으십시오.
이제 앱이 설정되었으므로 Winston을 사용할 수 있습니다.
단계 3 — Winston 설치 및 구성
이 단계에서는 Winston을 설치하고 구성합니다. 또한 winston
패키지의 구성 옵션을 살펴보고 파일과 콘솔에 정보를 로깅하기위한 로거를 만듭니다.
다음 명령을 사용하여 winston
을 설치하십시오:
응용 프로그램의 지원 또는 유틸리티 구성 파일을 특별한 디렉토리에 유지하는 것이 유용합니다. winston
구성이 포함 된 config
폴더를 만드십시오:
다음으로 로그 파일을 포함할 폴더를 만듭니다:
마지막으로 app-root-path
를 설치합니다:
app-root-path
패키지는 Node.js에서 경로를 지정할 때 유용합니다. 이 패키지는 직접적으로 Winston과 관련은 없지만 Node.js에서 파일의 경로를 지정하고 미관적인 상대 경로 구문을 피하는 데 유용합니다. 프로젝트 루트에서 Winston 로그 파일의 위치를 지정하고 지저분한 상대 경로 구문을 피하기 위해 사용합니다.
이제 로깅을 처리하는 구성이 마련되었으므로 설정을 정의할 수 있습니다. 편집을 위해 ~/myApp/config/winston.js
파일을 만들고 엽니다:
winston.js
파일에는 winston
구성이 포함됩니다.
다음으로 app-root-path
및 winston
패키지를 요구하는 다음 코드를 추가합니다:
이러한 변수가 준비되면 트랜스포트의 구성 설정을 정의할 수 있습니다. 트랜스포트는 로그에 대한 저장/출력 메커니즘을 나타내는 Winston에 의해 소개된 개념입니다. Winston은 기본적으로 네 가지 핵심 트랜스포트를 제공합니다: Console, File, HTTP, 그리고 Stream.
이 튜토리얼에서는 콘솔과 파일 트랜스포트에 중점을 둘 것입니다. 콘솔 트랜스포트는 정보를 콘솔에 기록하고 파일 트랜스포트는 지정된 파일에 정보를 기록합니다. 각 트랜스포트 정의에는 파일 크기, 로그 수준 및 로그 형식과 같은 구성 설정이 포함될 수 있습니다.
각 트랜스포트에 사용할 설정의 간략한 요약은 다음과 같습니다:
레벨
: 로그할 메시지의 레벨입니다.파일명
: 로그 데이터를 기록할 파일입니다.예외처리
: 처리되지 않은 예외를 잡아 로그에 기록합니다.최대크기
: 새 파일이 생성되기 전의 로그 파일의 최대 크기(바이트 단위)입니다.최대파일수
: 로그 파일 크기가 초과될 때 생성되는 파일의 최대 수를 제한합니다.형식
: 로그 출력 형식입니다.
로그 레벨은 메시지 우선순위를 나타내며 정수로 표시됩니다. Winston은 0부터 6까지 우선순위가 지정된 npm
로깅 레벨을 사용합니다(높은 순부터 낮은 순):
- 0: 오류
- 1: 경고
- 2: 정보
- 3: HTTP
- 4: 상세
- 5: 디버그
- 6: 무식함
특정 전송에 로깅 레벨을 지정할 때 해당 레벨 또는 그 이상의 레벨이 로그에 기록됩니다. 예를 들어 info
레벨을 설정하면 error
, warn
, 또는 info
레벨의 모든 것이 로그에 기록됩니다.
로그 레벨은 로거를 호출할 때 지정되며, 따라서 다음 명령을 실행하여 오류를 기록할 수 있습니다: logger.error('테스트 오류 메시지')
.
구성 파일에서 아직도 winston
구성 내에서 파일
및 콘솔
전송을 위한 구성 설정을 정의하는 다음 코드를 추가합니다.
다음으로, 다음 코드를 추가하여 options
변수에서 정의된 속성을 사용하여 파일 및 콘솔 전송을 사용하여 새 winston
로거를 인스턴스화합니다:
기본적으로 morgan
은 콘솔에만 출력되므로 morgan
에서 생성된 출력을 winston
로그 파일로 가져올 수 있는 스트림 함수를 정의합니다. 출력을 양 전송 (파일 및 콘솔)에서 가져 오도록 info
수준을 사용합니다. 다음 코드를 구성 파일에 추가하십시오:
마지막으로, 로거를 내보내어 응용 프로그램의 다른 부분에서 사용할 수 있도록 아래 코드를 추가하십시오:
완성된 winston
구성 파일은 이제 다음과 같습니다:
파일을 저장하고 닫습니다.
이제 로거가 구성되었지만, 응용 프로그램은 아직 이를 인식하거나 사용하는 방법을 알지 못합니다. 따라서 로거를 응용 프로그램과 통합해야 합니다.
단계 4 — Winston을 응용 프로그램과 통합하기
로그가 응용 프로그램과 함께 작동하려면 express
가 이를 인식하도록 해야 합니다. 단계 2에서 express
구성이 app.js
에 있다는 것을 보았으므로 로거를 이 파일에 가져올 수 있습니다.
편집할 파일을 엽니다:
다른 require
문과 함께 파일 상단에 winston
변수 선언을 추가합니다:
첫 번째로 winston
을 사용할 곳은 morgan
입니다. 여전히 app.js
에서 다음 줄을 찾으십시오:
이를 stream
옵션을 포함하도록 업데이트하십시오:
여기에서 stream
옵션을 winston
구성의 일부로 생성한 스트림 인터페이스로 설정합니다.
파일을 저장하고 닫으십시오.
이 단계에서 Express 애플리케이션을 Winston과 함께 작동하도록 구성했습니다. 다음으로 로그 데이터를 검토하겠습니다.
단계 5 — 로그 데이터 접근 및 사용자 지정 로그 메시지 기록
이제 애플리케이션이 구성되었으므로 로그 데이터를 볼 준비가 되었습니다. 이 단계에서 로그 항목을 검토하고 샘플 사용자 지정 로그 메시지로 설정을 업데이트하게 됩니다.
웹 브라우저에서 페이지를 다시로드하면 SSH 세션 A의 콘솔에서 다음과 유사한 출력을 볼 수 있습니다:
Output[nodemon] restarting due to changes...
[nodemon] starting `node bin/www`
info: ::1 - - [25/Apr/2022:18:10:55 +0000] "GET / HTTP/1.1" 200 170 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
info: ::1 - - [25/Apr/2022:18:10:55 +0000] "GET /stylesheets/style.css HTTP/1.1" 304 - "http://localhost:3000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
여기에는 두 개의 로그 항목이 있습니다: 첫 번째는 HTML 페이지에 대한 요청이며, 두 번째는 연관된 스타일 시트입니다. 각 전송이 info
수준 로그 데이터를 처리하도록 구성되어 있으므로 ~/myApp/logs/app.log
에있는 파일 전송에서도 유사한 정보를 볼 수 있어야 합니다.
로그 파일의 내용을 보려면 다음 명령을 실행하십시오:
tail
은 파일의 끝 부분을 터미널에 출력합니다.
다음과 유사한 내용이 표시됩니다:
{"level":"info","message":"::1 - - [25/Apr/2022:18:10:55 +0000] \"GET / HTTP/1.1\" 304 - \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n","timestamp":"2022-04-25T18:10:55.573Z"}
{"level":"info","message":"::1 - - [25/Apr/2022:18:10:55 +0000] \"GET /stylesheets/style.css HTTP/1.1\" 304 - \"http://localhost:3000/\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n","timestamp":"2022-04-25T18:10:55.588Z"}
파일 전송에서의 출력은 파일 전송 구성에서 winston.format.json()
을 사용했으므로 JSON 객체로 작성될 것입니다. JSON에 대한 자세한 내용은 JSON 소개에서 알아볼 수 있습니다.
지금까지 로거는 HTTP 요청 및 관련 데이터만 기록하고 있습니다. 이 정보는 로그에 포함되어야 하는 중요한 정보입니다.
향후에는 오류 기록 또는 데이터베이스 쿼리 성능 프로파일링과 같은 사용자 정의 로그 메시지를 기록할 수 있습니다. 예를 들어, 에러 핸들러 라우트에서 로거를 호출할 것입니다. 기본적으로 express-generator
패키지에는 이미 404
및 500
오류 핸들러 라우트가 포함되어 있으므로 해당 항목과 작업할 것입니다.
~/myApp/app.js
파일을 엽니다:
파일 하단에 다음과 같은 코드 블록을 찾습니다:
이 섹션은 클라이언트에게 오류 응답을 최종적으로 보낼 최종 오류 처리 라우트입니다. 모든 서버 측 오류가 이 경로를 통과하게 될 것이므로, 여기에 winston 로거를 포함하는 것이 좋습니다.
이제 오류를 처리하고 있으므로 error
로그 레벨을 사용하려고 합니다. 두 전송 모두 error
레벨 메시지를 기록하도록 구성되어 있으므로 콘솔 및 파일 로그에서 출력을 볼 수 있어야 합니다.
로그에는 다음과 같은 정보를 포함할 수 있습니다:
err.status
: HTTP 오류 상태 코드입니다. 없는 경우 기본값은500
입니다.err.message
: 오류 세부 정보입니다.req.originalUrl
: 요청된 URL입니다.req.path
: 요청 URL의 경로 부분입니다.req.method
: 요청의 HTTP 메소드(GET, POST, PUT 등).req.ip
: 요청의 원격 IP 주소입니다.
오류 핸들러 라우트를 업데이트하여 winston
로깅을 포함시킵니다:
파일을 저장하고 닫습니다.
이 프로세스를 테스트하려면 프로젝트에서 존재하지 않는 페이지에 액세스하십시오. 존재하지 않는 페이지에 액세스하면 404 오류가 발생합니다. 웹 브라우저에서 다음 URL을로드하십시오: http://your_server_ip:3000/foo
. express-generator
에 의해 생성된 보일러플레이트 덕분에 응용 프로그램은 이러한 오류에 응답하도록 설정되어 있습니다.
브라우저에서는 다음과 같은 오류 메시지가 표시됩니다:
SSH 세션 A의 콘솔을 확인하면 오류에 대한 로그 항목이 있어야 합니다. colorize
형식이 적용되어 있으므로 쉽게 찾을 수 있습니다:
Output[nodemon] starting `node bin/www`
error: 404 - Not Found - /foo - GET - ::1
info: ::1 - - [25/Apr/2022:18:08:33 +0000] "GET /foo HTTP/1.1" 404 982 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
info: ::1 - - [25/Apr/2022:18:08:33 +0000] "GET /stylesheets/style.css HTTP/1.1" 304 - "http://localhost:3000/foo" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
파일 로거에 대해서는 tail
명령을 다시 실행하면 새로운 로그 레코드가 표시됩니다:
다음과 같은 메시지가 표시됩니다:
{"level":"error","message":"404 - Not Found - /foo - GET - ::1","timestamp":"2022-04-25T18:08:33.508Z"}
오류 메시지에는 오류 처리기의 일부로 명시적으로 winston
에게 기록하도록 지시한 모든 데이터가 포함됩니다. 이 정보에는 오류 상태 (404 – 찾을 수 없음), 요청된 URL (localhost/foo
), 요청 방법 (GET
), 요청을 한 IP 주소 및 요청이 발생한 타임스탬프가 포함됩니다.
결론
이 튜토리얼에서는 간단한 Node.js 웹 애플리케이션을 구축하고 응용 프로그램 성능에 대한 통찰력을 제공하는 효과적인 도구로 작동하는 Winston 로깅 솔루션을 통합했습니다.
귀하의 응용 프로그램에 대한 견고한 로깅 솔루션을 구축하기 위해 더 많은 작업을 수행할 수 있습니다, 특히 요구 사항이 더 복잡해질 때입니다. Winston 전송에 대해 더 알아보려면 윈스턴 전송 문서를 참조하십시오. 사용자 지정 전송을 만들려면 사용자 지정 전송 추가를 참조하십시오. HTTP 코어 전송과 함께 사용할 HTTP 엔드포인트를 만들려면 winstond
를 참조하십시오. Winston을 프로파일링 도구로 사용하려면 프로파일링을 참조하십시오.