-
Logging LibraryNode.js 2025. 9. 16. 23:02
👍 Logging의 이점
1️⃣ 디버깅 및 문제해결에 도움
로그는 애플리케이션의 상태, 동작에 대한 자세한 정보를 제공해 문제를 더 쉽게 식별하고 해결하는데 도움을 줍니다.
2️⃣ 성능 모니터링
응답시간, 리소스 활용도 등의 성능 측정 항목을 추적하는데 도움을 주어 개발자가 애플리케이션을 최적화할 수 있습니다.
3️⃣ 보안 모니터링
로그를 사용해 잘못된 요청이나 데이터에 무단으로 엑세스 시도하는 보안관련 이벤트를 모니터링할 수 있습니다.
4️⃣ 운영시 정보 수집
사용자 행동 및 시스템 상태 등에 대한 정보를 수집해서 이용할 수 있습니다.
- pageview 등
✅ Node.js 로깅의 Best Practices
Node.js에서 로깅을 할 때 따르면 좋을 best practices를 알아보려고 합니다.
1️⃣ 안정된 로깅 프레임워크 선택
콘솔로 로그를 작성하는 것이 아닌 Node.js 애플리케이션에 로깅 기능을 제공하는 안정된 로깅 프레임워크를 사용
- Winston :다양한 전송 방식(예: 콘솔, 파일, HTTP)을 지원하고 널리 사용되는 로깅 라이브러리입니다.
- Bunyan: 로그 분석을 위한 내장 CLI 도구가 포함된 빠르고 간단한 JSON 로깅 라이브러리입니다.
- Pino: 프로덕션 환경에 적합한 고성능 로깅 라이브러리입니다.
2️⃣ 구조화된 로깅 사용
구조화되지 않은 로그(사람이 읽을 수 있는 문자열)는 우리에게는 직관적일 수 있지만 기계가 처리하는데는 어려움이 있습니다.
image 'file.jpg' was uploaded successfully이런 로그가 계속 발생한다면 파싱을 하는데 매우 복잡한 로직이 필요하고 자동화를 하는데 있어서 일관성이 부족할 수 있습니다.
따라서, 구조화된 형식을 사용하면 로그 데이터를 정리하는데 도움이 됩니다.
{ "level": "info", "timestamp": "2023-10-25T07:12:46.743Z", "filename": "file.jpg", "msg": "image 'file.jpg' was uploaded successfully" }일반적으로 JSON이 널리 사용되는 구조화된 형식입니다.
- LogFmt 와 같은 대안도 존재
🥲 구조화된 로그의 단점 - 가독성
개발중에 쉽게 사람이 더 읽기 쉬운 형식으로 출력하도록 프레임워크를 구성하고 운영환경에서는 구조화된 출력을 보존하는 방법을 사용할 수 있습니다.
- pino-prettey 같은 추가 도구를 사용해 로그를 더 이쁘게 꾸밀 수도 있습니다.
3️⃣ 로그 Level을 올바르게 사용
로그 level은 로그의 중요도와 긴급도에 따라 분류합니다.
Debug 디버깅을 위한 자세한 정보 Info 애플리케이션 이벤트에 대한 일반 정보 Warn 당장은 중요하지 않은 잠재적인 문제 Error 주의가 필요한 오류 Fatal 조기 종료를 발생시키는 심각한 오류 로그 level을 사용하면 로그 메시지를 필터링하고 우선순위를 지정하는 데 도움이 되므로 중요한 문제에 집중하기가 더 쉽습니다.
4️⃣ 자세한 로그 메시지를 작성
로그가 의미있는 정보를 제공하기 위해서는 발생한 이벤트에 대한 자세한 정보를 포함하는 것이 중요합니다.
- 불필요하거나 중복되는 정보는 포함하지 않기
사용자 인증에 실패했습니다.(어떤 사용자?) 오류가 발생했습니다(너무 일반적임).자세한 로그 메시지가 아닌 경우
사용자 'USR-1234'에 대한 인증에 실패했습니다. 주문 ID: 34567에 대한 결제 처리 중 예기치 않은 오류가 발생했습니다.이처럼 자세한 메시지를 제공하면 로그를 훨씬 더 쉽게 이해할 수 있습니다.
5️⃣ 항상 타임스탬프를 포함
로그 내용에 타임스탬프를 작성하는 것은 로그의 맥락을 파악하고 정리하는데 매우 중요합니다.
- 최근 이벤트와 며칠전 이벤트를 구분할 수 없다면 로그를 탐색하는 것이 불가능
대부분의 로깅 프레임워크는 기본으로 로그 출력에 타임스탬프를 포함합니다.
6️⃣ 로그 항목에 상황별 필드를 추가
관련 세부정보를 로그 항목에 추가하는 것을 통해 발생한 이벤트를 전체적으로 파악하고 다양한 시스템에서 발생한 요청, 트랜잭션등을 추적하는 것이 더 쉬워집니다.
- ex) 요청 ID, 사용자 ID 와 같은 고유 식별자를 추가하면 로그의 명확성을 높이고 상호 연관 관계를 더 쉽게 파악가능
{ "level": 30, "timestamp": "2023-10-25T01:06:06.783Z", "userid": 605689, "username": "fedora", "requestID": "f9ed4675f1c53513c61a3b3b4e25b4c0", "msg": "Uploading image.png was successful" }7️⃣ 스택 추적을 사용해 예기치 않은 오류를 기록
Exception 로깅의 주요 목적 중 하나는 문제의 원인을 빠르게 파악하기 위함입니다.
오류 메시지를 확인하면 무엇이 잘못되었는지 충분히 파악할 수 없지만 스택 추적을 통해 오류가 발생한 정확한 위치를 파악하면 문제를 더 빠르게 파악하고 수정할 수 있습니다.
{ "level": 50, "time": "2022-06-15T21:23:04.436Z", "pid": 285659, "hostname": "fedora", "err": { "type": "Error", "message": "an error", "stack": "Error: an error\\n at Object.<anonymous> (/home/ayo/dev/betterstack/betterstack-community/demo/snippets/main.js:23:9)\\n " }, "msg": "an error" }8️⃣ 민감한 데이터가 로그에 포함되지 않도록 합니다.
로그에는 비밀번호, token 같은 데이터가 포함되어서는 안됩니다.
- 경우에 따라 IP 주소도 개인 식별 정보로 간주될 수 있습니다.
9️⃣ 문제 해결 목적 이상의 로그
로깅은 문제해결뿐 아니라 사용자 행동에 대한 정보 수집, 모니터링 등 중요한 역할을 합니다.
이런 것들을 이용해서 서비스 개발 방향에 큰 영향을 미칠 수 있습니다.
- 성능 지표를 추출
🔟 항상 표준 출력에 기록
로깅 프레임워크는 로그 출력 대상을 다양하게 제공해주고 있습니다.
- 다양한 대상(HTTP endpoint, database 등)으로 로그를 전송할 수 있습니다.
이런 옵션들에도 불구하고 애플리케이션 로그를 표준 출력으로 보내는 것이 일반적으로 가장 좋은 방법입니다.
1️⃣1️⃣ 로그 관리 시스템에서 로그를 중앙화
애플리케이션이 출시되는 즉시 호스트 서버에 로그가 생성되기 시작합니다.
각 서버에 접속하여 로그를 확인하는 것은 소수의 사용자에게는 가능할 수 있지만 여러 서버에 걸쳐 접속하는 것은 금세 번거롭고 비효율적이 됩니다.
최적의 전략은 모든 로그 데이터를 수집하여 한곳에 통합하는 것입니다.
- 자주 발생하는 이벤트나 오류 등에 사용자 정의 알림 구성
- 조직의 다른 구성원과 원활하게 공유할 수 있습니다.
- 애플리케이션 서버가 다운되더라도 로그 접근성을 보장합니다.
- 로그 보존 정책을 준수하고 장기 보관을 보장하는 데 도움이 됩니다.
b📚 Node.js의 Logging 라이브러리
Library GitHub Stars Key Strength Best For Winston 20k+ Highly configurable Complex apps Pino 12k+ Performance-focused High-throughput systems Bunyan 7k+ JSON logging Microservices Morgan 9k+ HTTP request logging Express.js apps debug 10k+ Lightweight debugging Small projects log4js 5k+ Familiar API for Java devs Teams with Java background loglevel 2k+ Minimal but flexible Browser-compatible apps roarr 1k+ Serialization performance High-scale services tracer 1k+ Colorized output Development environments 1️⃣ Winston
Node.js에서 가장 널리 사용되는 로깅 라이브러리이며 다양한 로그 포맷팅을 지원합니다.
로그 수준, 포맷, 저장 등의 다양한 측면을 분리하여 로깅의 유연성과 확장성을 높입니다.
👍 장점
- 다양한 전송 및 포맷 옵션
- 풍부한 플러그인
2️⃣ Pino
Pino 는 Node.js를 위한 구조화된 로깅 라이브러리로 기본적으로 JSON 출력을 생성하여 로그 데이터를 쉽게 검색, 모니터링, 시각화할 수 있습니다.
- 성능에 중점을 둔 로깅 라이브러리 입니다.
- 최소한의 오버헤드로 초당 10,000개 이상의 로그를 처리
👍 장점
- 가볍고 빠르다.
- 메모리가 효율적이게 설계되어 로그가 대량으로 생성되는 상황에서도 성능을 유지합니다.
3️⃣ Bunyan
Node.js에서 JSON 로깅에 대해 특화된 라이브러리입니다.
👍 장점
- 각 로그 항목은 일관된 구조를 가진 JSON 객체이므로 자동화된 분석이 용이
4️⃣ Morgan
Morgan은 HTTP 요청을 기록하도록 특별히 설계된 Node.js 라이브러리입니다.
일반적으로 Express.js와 같은 웹 프레임워크에 미들웨어로 통합되어 모든 HTTP 요청을 추적합니다.
다른 범용 로깅 도구와 달리 Morgan은 HTTP 요청 로깅에 중점을 둡니다.
'Node.js' 카테고리의 다른 글
워커 스레드를 통한 멀티 쓰레딩 (1) 2025.08.30 fetch API (1) 2025.08.27 비동기 프로그래밍 - Promise 와 async / await (1) 2025.08.27 Node.js - 싱글 스레드, 이벤트 루프 그리고 libuv (3) 2025.08.23 Express 을 이용해 웹페이지를 표현하는 방법 - 템플릿 엔진 (3) 2025.08.20