프로그래밍/NODEJS 강좌 BY GEMINI

디버깅 도구 활용 및 로깅의 중요성 🐞📝

lazy_web_devloper 2025. 7. 22. 08:56
728x90
반응형

디버깅 도구 활용 및 로깅의 중요성 🐞📝

좋은 에러 핸들링은 애플리케이션이 예기치 못한 상황에서도 멈추지 않게 해주지만, 근본적인 버그를 수정하려면 코드의 어느 부분에서, 왜 문제가 발생하는지 정확히 알아내야 합니다. 이 과정이 바로 디버깅입니다. 또한, 실시간으로 코드를 들여다볼 수 없는 운영 환경에서는 로깅을 통해 남겨진 기록이 문제 해결의 유일한 단서가 됩니다.

1. 디버깅 도구 활용

  • 가장 간단한 방법: console.log 가장 쉽고 빠르게 변수의 값이나 코드의 실행 흐름을 확인하는 방법입니다. 하지만 console.log는 코드를 지저분하게 만들고, 디버깅이 끝나면 일일이 제거해야 하며, 복잡한 문제를 해결하기에는 기능이 턱없이 부족합니다.
  • 대화형 디버거 (Interactive Debugger) 사용 전문적인 디버깅 도구를 사용하면 코드 실행을 원하는 지점(중단점, Breakpoint)에서 멈추고, 다음과 같은 강력한 기능들을 사용할 수 있습니다.
    • 변수의 현재 값을 실시간으로 확인 및 수정
    • 코드를 한 줄씩 실행 (Step Over, Step Into)
    • 함수의 호출 스택(Call Stack) 확인
    • 조건부 중단점 설정
    Java 개발자를 위한 비유: VS Code의 디버거는 Eclipse나 IntelliJ IDEA의 디버거와 사용법 및 기능이 완전히 동일합니다. Breakpoint를 설정하고, Debug 모드로 실행하며, 변수를 검사하고, 코드를 스텝 단위로 실행하는 모든 경험이 그대로 적용됩니다.
  • VS Code 디버거 활용 (권장) Node.js 개발 시 가장 널리 사용되는 방법입니다.2단계: 디버거 실행
    1. VS Code 왼쪽의 '실행 및 디버그(Run and Debug)' 아이콘 (벌레 모양)을 클릭합니다.
    2. "실행 및 디버그" 버튼을 누르거나 F5 키를 누릅니다.
    3. Node.js 환경을 선택하면, VS Code가 자동으로 프로젝트 루트에 .vscode/launch.json 설정 파일을 생성해 줍니다.
    4. JSON
       
      // .vscode/launch.json
      {
        "version": "0.2.0",
        "configurations": [
          {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": ["<node_internals>/**"],
            "program": "${workspaceFolder}/app.js" // 실행할 메인 파일
          }
        ]
      }
      
    5. 이후 다시 F5 키를 누르면 디버그 모드로 서버가 시작됩니다.
    3단계: 디버깅 Postman이나 브라우저로 중단점이 설정된 라우트에 요청을 보내면, 코드 실행이 해당 지점에서 멈춥니다. 그러면 VS Code 상단에 나타나는 디버그 제어판과 왼쪽의 패널을 통해 변수 값을 확인하고 코드를 한 줄씩 실행하며 문제의 원인을 추적할 수 있습니다.
  • 1단계: 중단점(Breakpoint) 설정 VS Code 편집기에서 코드 라인 번호 왼쪽 여백을 클릭하여 빨간 점(중단점)을 만듭니다. 서버는 이 지점에서 실행을 멈출 것입니다.

2. 로깅(Logging)의 중요성

디버깅이 개발 환경에서 능동적으로 버그를 찾는 과정이라면, 로깅은 운영 환경을 포함한 모든 환경에서 애플리케이션의 동작 상태를 수동적으로 기록하는 과정입니다. console.log는 단순한 정보를 콘솔에 출력할 뿐이지만, 전문 로깅 라이브러리는 다음과 같은 필수 기능을 제공합니다.

  • 로그 레벨 (Log Level): error, warn, info, debug 등 로그의 심각도를 구분하여, 운영 환경에서는 info 레벨 이상의 로그만 기록하고 개발 환경에서는 모든 debug 로그를 보는 등 환경에 따라 출력 수준을 조절할 수 있습니다.
  • 타임스탬프 및 포맷팅: 모든 로그에 시간 정보를 자동으로 추가하고, JSON이나 커스텀 텍스트 등 원하는 형태로 로그의 형식을 지정할 수 있습니다.
  • 출력 대상(Transport) 지정: 로그를 콘솔뿐만 아니라 파일, 데이터베이스, 외부 로깅 서비스 등 다양한 곳으로 보낼 수 있습니다.
  • 주요 로깅 라이브러리
    • Morgan: Express를 위한 대표적인 HTTP 요청 로거 미들웨어입니다. 들어오는 모든 요청에 대한 정보를 (메소드, 경로, 상태 코드, 응답 시간 등) 한 줄로 깔끔하게 기록해 줍니다.
      JavaScript
       
      const morgan = require('morgan');
      // 'dev' 포맷으로 로그를 남김. 'combined', 'short' 등 다양한 포맷 지원
      app.use(morgan('dev'));
      
    • Bash
       
      npm install morgan
      
    • Winston: 가장 널리 쓰이는 범용 로깅 라이브러리입니다. HTTP 요청뿐만 아니라 애플리케이션의 모든 종류의 로그를 원하는 형식과 대상으로 기록할 수 있어 매우 유연하고 강력합니다.

Java 개발자를 위한 비유: Morgan과 Winston은 Java의 로깅 생태계인 SLF4J(추상화) + Logback/Log4j2(구현체) 와 유사한 역할을 합니다. 로그 레벨, Appender(Winston의 Transport), Pattern Layout(Winston의 Format) 등 모든 핵심 개념이 동일하게 적용됩니다.

Winston 설정 예시:

JavaScript
 
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info', // info 레벨 이상의 로그만 기록
  format: winston.format.json(), // JSON 형식으로 기록
  transports: [
    // error 레벨의 로그는 error.log 파일에 저장
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    // 모든 레벨의 로그는 combined.log 파일에 저장
    new winston.transports.File({ filename: 'combined.log' }),
  ],
});

// 개발 환경일 경우, 콘솔에도 로그를 출력
if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.simple(),
  }));
}

// 사용법
logger.info('Server started successfully.');
logger.warn('Deprecation warning: This feature will be removed.');
logger.error('Failed to connect to database.');

이것으로 "7️⃣ 에러 처리 및 디버깅: 안정적인 애플리케이션 만들기 🛡️" 챕터를 마칩니다. 안정적인 에러 처리 전략 위에 강력한 디버깅 및 로깅 시스템을 갖추는 것은, 신뢰할 수 있는 소프트웨어를 만들기 위한 필수 과정입니다.

728x90
반응형