Designing Logging and Monitoring Infrastructure: Claude Code 활용 가이드
designing logging and monitoring infrastructure: Claude Code 활용. 실용적인 코드 예시를 포함합니다.
모니터링基盤の구축にClaude Codeを활용する
프로덕션 환경のトラブルシューティングには、적절한로그と모니터링が필수적입니다。Claude Code는 構造化로그、分散トレーシング、メトリクス収集の基盤を一括で구축でき、可観測性(Observability)の高いシステムを효율적으로実現します。
構造化로그の구현
> pino를 사용한構造化로그のセットアップ를 생성해줘。
> 요청ID、사용자ID、処理시간を含めて。
> 環境ごとに로그レベルを전환られるようにして。
// src/lib/logger.ts
import pino from 'pino';
export const logger = pino({
level: process.env.LOG_LEVEL || (process.env.NODE_ENV === 'production' ? 'info' : 'debug'),
transport: process.env.NODE_ENV !== 'production'
? { target: 'pino-pretty', options: { colorize: true } }
: undefined,
formatters: {
level(label) {
return { level: label };
},
},
base: {
service: process.env.SERVICE_NAME || 'my-app',
env: process.env.NODE_ENV,
},
timestamp: pino.stdTimeFunctions.isoTime,
redact: ['password', 'token', 'authorization', 'cookie'],
});
// 요청スコープのロガー
export function createRequestLogger(requestId: string, userId?: string) {
return logger.child({
requestId,
userId,
});
}
요청로그미들웨어
// src/middleware/request-logger.ts
import { Request, Response, NextFunction } from 'express';
import { createRequestLogger } from '@/lib/logger';
import { randomUUID } from 'crypto';
export function requestLogger(req: Request, res: Response, next: NextFunction) {
const requestId = (req.headers['x-request-id'] as string) || randomUUID();
const start = Date.now();
const log = createRequestLogger(requestId, req.user?.id);
req.log = log;
res.setHeader('X-Request-Id', requestId);
log.info({
method: req.method,
url: req.url,
userAgent: req.headers['user-agent'],
}, 'Request started');
res.on('finish', () => {
const duration = Date.now() - start;
const level = res.statusCode >= 500 ? 'error' : res.statusCode >= 400 ? 'warn' : 'info';
log[level]({
method: req.method,
url: req.url,
statusCode: res.statusCode,
duration,
}, 'Request completed');
});
next();
}
OpenTelemetry에 의한分散トレーシング
> OpenTelemetry를 사용한分散トレーシングを설정して。
> HTTP、DB、Redis呼び出しの自動計装を유효にして。
// src/instrumentation.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { Resource } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
const sdk = new NodeSDK({
resource: new Resource({
[ATTR_SERVICE_NAME]: process.env.SERVICE_NAME || 'my-app',
[ATTR_SERVICE_VERSION]: process.env.APP_VERSION || '1.0.0',
}),
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
}),
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/metrics',
}),
exportIntervalMillis: 30000,
}),
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-http': { enabled: true },
'@opentelemetry/instrumentation-express': { enabled: true },
'@opentelemetry/instrumentation-pg': { enabled: true },
'@opentelemetry/instrumentation-redis': { enabled: true },
}),
],
});
sdk.start();
process.on('SIGTERM', () => {
sdk.shutdown().then(() => process.exit(0));
});
カスタムメトリクスの収集
// src/lib/metrics.ts
import { metrics } from '@opentelemetry/api';
const meter = metrics.getMeter('my-app');
// 요청カウンター
export const requestCounter = meter.createCounter('http_requests_total', {
description: 'Total HTTP requests',
});
// 응답タイムのヒストグラム
export const responseTime = meter.createHistogram('http_response_time_ms', {
description: 'HTTP response time in milliseconds',
unit: 'ms',
});
// アクティブ사용자数のゲージ
export const activeUsers = meter.createUpDownCounter('active_users', {
description: 'Number of active users',
});
// ビジネスメトリクス
export const orderCounter = meter.createCounter('orders_total', {
description: 'Total orders placed',
});
// Usage example
export function recordRequest(method: string, path: string, statusCode: number, duration: number) {
requestCounter.add(1, { method, path, statusCode: String(statusCode) });
responseTime.record(duration, { method, path });
}
ヘルスチェック엔드포인트
// src/app/api/health/route.ts
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/db';
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL!);
export async function GET() {
const checks = {
status: 'ok' as 'ok' | 'degraded' | 'error',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
checks: {} as Record<string, { status: string; latency?: number }>,
};
// DB接続チェック
try {
const start = Date.now();
await prisma.$queryRaw`SELECT 1`;
checks.checks.database = { status: 'ok', latency: Date.now() - start };
} catch {
checks.checks.database = { status: 'error' };
checks.status = 'degraded';
}
// Redis接続チェック
try {
const start = Date.now();
await redis.ping();
checks.checks.redis = { status: 'ok', latency: Date.now() - start };
} catch {
checks.checks.redis = { status: 'error' };
checks.status = 'degraded';
}
const statusCode = checks.status === 'ok' ? 200 : 503;
return NextResponse.json(checks, { status: statusCode });
}
에러トラッキング
// src/lib/error-tracker.ts
import { logger } from './logger';
export function trackError(error: Error, context?: Record<string, unknown>) {
logger.error({
err: {
name: error.name,
message: error.message,
stack: error.stack,
},
...context,
}, 'Unhandled error');
// Sentryなどの外部サービスへ전송
if (process.env.SENTRY_DSN) {
// Sentry.captureException(error, { extra: context });
}
}
// グローバル에러핸들러ー
process.on('uncaughtException', (error) => {
trackError(error, { type: 'uncaughtException' });
process.exit(1);
});
process.on('unhandledRejection', (reason) => {
trackError(reason instanceof Error ? reason : new Error(String(reason)), {
type: 'unhandledRejection',
});
});
정리
Claude Code를 활용하면 構造化로그、分散トレーシング、メトリクス収集、ヘルスチェックを含む모니터링基盤を효율적으로구축할 수 있습니다。本番운영に必要な可観測性を最初から組み込むことで、トラブルシューティングの시간を大幅に短縮할 수 있습니다。개발 환경の설정はCLAUDE.mdに記述しておくと、Claude Code가 一貫した구성を생성します。마이크로서비스での모니터링は마이크로서비스설계도 참고하세요.
Claude Code의 상세 정보는Anthropic공식 문서를 확인하세요.OpenTelemetry의 상세 정보는OpenTelemetry공식 사이트를 참고하세요.
Claude Code 워크플로우를 한 단계 업그레이드하세요
지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code Agent SDK 입문 ― 자율 에이전트를 빠르게 구축하는 방법
Claude Code Agent SDK로 자율형 AI 에이전트를 구축하는 방법을 해설합니다. 설정부터 도구 정의, 멀티스텝 실행까지 실전 코드와 함께 소개합니다.
Claude Code 컨텍스트 관리 테크닉 완전 가이드
Claude Code의 컨텍스트 윈도우를 최대한 활용하는 실전 테크닉을 해설합니다. 토큰 절약, 대화 분할, CLAUDE.md 활용법까지 소개합니다.
Claude Code MCP Server 설정 및 실전 활용 가이드
Claude Code의 MCP Server 기능을 종합적으로 소개합니다. 외부 도구 연결, 서버 설정, 실전 통합 사례까지 한 번에 알아보세요.