본문으로 건너뛰기

로깅 설정 (LoggingConfig)

개요

LoggingConfig는 애플리케이션 로깅 시스템의 동작 방식을 설정합니다. 로그 레벨, 출력 형식, 저장 위치, 알림 설정 등 로깅 관련 설정을 정의합니다. 특히 GCP BigQuery를 활용한 로그 저장 및 분석을 지원합니다.

구성 요소

핵심 설정 값

설정 키환경 변수타입필수 여부기본값설명
levelLOG_LEVELstring선택'info'로그 레벨 ('error', 'warn', 'info', 'debug', 'verbose')
jsonLOG_JSONboolean선택falseJSON 형식으로 로그 출력 여부
consoleLOG_CONSOLE_ENABLEDboolean선택true콘솔 로그 출력 여부

BigQuery 설정

설정 키환경 변수타입필수 여부기본값설명
bigquery.enabledLOG_BIGQUERY_ENABLEDboolean선택falseBigQuery 로깅 활성화 여부
bigquery.projectIdLOG_BIGQUERY_PROJECT_IDstring조건부 필수*-BigQuery 프로젝트 ID
bigquery.datasetIdLOG_BIGQUERY_DATASET_IDstring조건부 필수*-BigQuery 데이터셋 ID
bigquery.tableIdLOG_BIGQUERY_TABLE_IDstring조건부 필수*-BigQuery 테이블 ID
bigquery.retentionDaysLOG_BIGQUERY_RETENTION_DAYSnumber선택365로그 보존 기간(일)

* BigQuery 로깅이 활성화된 경우 필수

알림 설정

설정 키환경 변수타입필수 여부기본값설명
alerts.enabledLOG_ALERTS_ENABLEDboolean선택false로그 알림 활성화 여부
alerts.emailLOG_ALERTS_EMAILstring조건부 선택*-이메일 알림 수신 주소
alerts.slackLOG_ALERTS_SLACK_WEBHOOKstring조건부 선택*-Slack Webhook URL

* 알림이 활성화된 경우 이메일 또는 Slack 중 하나 이상 필요

사용 예시

구성 정의

// libs/core/config/src/lib/namespaces/logging.config.ts
import { registerAs } from '@nestjs/config';

export const loggingConfig = registerAs('logging', () => ({
level: process.env.LOG_LEVEL || 'info',
json: process.env.LOG_JSON === 'true',
console: process.env.LOG_CONSOLE_ENABLED !== 'false',
bigquery: {
enabled: process.env.LOG_BIGQUERY_ENABLED === 'true',
projectId: process.env.LOG_BIGQUERY_PROJECT_ID,
datasetId: process.env.LOG_BIGQUERY_DATASET_ID,
tableId: process.env.LOG_BIGQUERY_TABLE_ID,
retentionDays: parseInt(process.env.LOG_BIGQUERY_RETENTION_DAYS || '365', 10),
},
alerts: {
enabled: process.env.LOG_ALERTS_ENABLED === 'true',
email: process.env.LOG_ALERTS_EMAIL,
slack: process.env.LOG_ALERTS_SLACK_WEBHOOK,
},
}));

유효성 검증 스키마

// libs/core/config/src/lib/schemas/logging.schema.ts
import * as Joi from 'joi';

export const loggingConfigSchema = {
LOG_LEVEL: Joi.string()
.valid('error', 'warn', 'info', 'debug', 'verbose')
.default('info'),
LOG_JSON: Joi.boolean().default(false),
LOG_CONSOLE_ENABLED: Joi.boolean().default(true),

LOG_BIGQUERY_ENABLED: Joi.boolean().default(false),
LOG_BIGQUERY_PROJECT_ID: Joi.string().when('LOG_BIGQUERY_ENABLED', {
is: true,
then: Joi.string().required(),
otherwise: Joi.string().optional(),
}),
LOG_BIGQUERY_DATASET_ID: Joi.string().when('LOG_BIGQUERY_ENABLED', {
is: true,
then: Joi.string().required(),
otherwise: Joi.string().optional(),
}),
LOG_BIGQUERY_TABLE_ID: Joi.string().when('LOG_BIGQUERY_ENABLED', {
is: true,
then: Joi.string().required(),
otherwise: Joi.string().optional(),
}),
LOG_BIGQUERY_RETENTION_DAYS: Joi.number().default(365),

LOG_ALERTS_ENABLED: Joi.boolean().default(false),
LOG_ALERTS_EMAIL: Joi.string().email().optional(),
LOG_ALERTS_SLACK_WEBHOOK: Joi.string().uri().optional(),
};

로거 서비스에서 사용

// 로깅 설정 사용 예시
import { Injectable, LoggerService } from '@nestjs/common';
import { ConfigService } from '@core/config';
import { createLogger, Logger, format, transports } from 'winston';
import { BigQuery } from '@google-cloud/bigquery';

@Injectable()
export class AppLogger implements LoggerService {
private logger: Logger;
private context: string = 'Application';

constructor(private readonly configService: ConfigService) {
// 로깅 설정 로드
const logConfig = this.configService.getNamespace<{
level: string;
json: boolean;
console: boolean;
bigquery: {
enabled: boolean;
projectId?: string;
datasetId?: string;
tableId?: string;
};
}>('logging');

// Winston 로거 구성
this.logger = createLogger({
level: logConfig.level,
format: logConfig.json
? format.combine(format.timestamp(), format.json())
: format.combine(
format.timestamp(),
format.colorize(),
format.printf(({ timestamp, level, message, context, ...metadata }) => {
return `${timestamp} [${context || this.context}] ${level}: ${message} ${
Object.keys(metadata).length ? JSON.stringify(metadata) : ''
}`;
})
),
transports: [],
});

// 콘솔 로그 설정
if (logConfig.console) {
this.logger.add(new transports.Console());
}

// BigQuery 로그 설정
if (logConfig.bigquery?.enabled &&
logConfig.bigquery.projectId &&
logConfig.bigquery.datasetId &&
logConfig.bigquery.tableId) {
// BigQuery 로깅 트랜스포트 추가 (여기서는 간략하게 표현)
this.setupBigQueryTransport(
logConfig.bigquery.projectId,
logConfig.bigquery.datasetId,
logConfig.bigquery.tableId
);
}
}

setContext(context: string) {
this.context = context;
return this;
}

log(message: string, context?: string, ...metadata: any[]) {
this.logger.info(message, { context: context || this.context, ...metadata });
}

error(message: string, trace?: string, context?: string, ...metadata: any[]) {
this.logger.error(message, { trace, context: context || this.context, ...metadata });
}

warn(message: string, context?: string, ...metadata: any[]) {
this.logger.warn(message, { context: context || this.context, ...metadata });
}

debug(message: string, context?: string, ...metadata: any[]) {
this.logger.debug(message, { context: context || this.context, ...metadata });
}

verbose(message: string, context?: string, ...metadata: any[]) {
this.logger.verbose(message, { context: context || this.context, ...metadata });
}

private setupBigQueryTransport(projectId: string, datasetId: string, tableId: string) {
// BigQuery 로깅 로직 구현
// 실제 구현은 winston-bigquery-transport와 같은 라이브러리 사용 가능
// 또는 커스텀 트랜스포트 구현
}
}

환경별 설정 가이드

로컬 개발 환경

로컬 개발 환경에서는 서비스별 JSON 설정 파일을 통해 로깅 설정을 구성합니다. 일반적으로 콘솔 로깅을 주로 사용하고 자세한 디버그 정보를 출력합니다.

// cloudrun-deploy/secret/local/dev/dta-wide-api.json
{
"LOG_LEVEL": "debug",
"LOG_JSON": "false",
"LOG_CONSOLE_ENABLED": "true",
"LOG_BIGQUERY_ENABLED": "false"
}

클라우드 런 개발 환경

개발 환경의 클라우드 런에서는 서비스별 JSON 설정 파일을 통해 구조화된 로깅과 BigQuery 로깅을 활성화합니다.

// cloudrun-deploy/secret/cloudrun/dev/dta-wide-api.json
{
"LOG_LEVEL": "debug",
"LOG_JSON": "true",
"LOG_CONSOLE_ENABLED": "true",
"LOG_BIGQUERY_ENABLED": "true",
"LOGGING_BIGQUERY_PROJECT_ID": "dta-cloud-de-dev",
"LOGGING_BIGQUERY_DATASET_ID": "logging",
"LOGGING_BIGQUERY_SYSTEM_LOGS_TABLE": "system_logs",
"LOGGING_BIGQUERY_ERROR_LOGS_TABLE": "error_logs",
"LOGGING_BIGQUERY_METRIC_LOGS_TABLE": "metric_logs",
"LOGGING_RETENTION_SYSTEM_DAYS": "30",
"LOG_ALERTS_ENABLED": "false"
}

클라우드 런 프로덕션 환경

프로덕션 환경에서는 서비스별 JSON 설정 파일을 통해 필요한 정보만 로깅하고 알림 기능을 활성화합니다.

// cloudrun-deploy/secret/cloudrun/prod/dta-wide-api.json
{
"LOG_LEVEL": "info",
"LOG_JSON": "true",
"LOG_CONSOLE_ENABLED": "true",
"LOG_BIGQUERY_ENABLED": "true",
"LOGGING_BIGQUERY_PROJECT_ID": "dta-cloud-de-prod",
"LOGGING_BIGQUERY_DATASET_ID": "logging",
"LOGGING_BIGQUERY_SYSTEM_LOGS_TABLE": "system_logs",
"LOGGING_BIGQUERY_ERROR_LOGS_TABLE": "error_logs",
"LOGGING_BIGQUERY_METRIC_LOGS_TABLE": "metric_logs",
"LOGGING_RETENTION_SYSTEM_DAYS": "30",
"LOGGING_RETENTION_ERROR_DAYS": "90",
"LOGGING_RETENTION_METRIC_DAYS": "365",
"LOG_ALERTS_ENABLED": "true",
"LOG_ALERTS_EMAIL": "alerts@weltcorp.com",
"LOG_ALERTS_SLACK_WEBHOOK": "https://hooks.slack.com/services/xxx/yyy/zzz"
}

로그 데이터 구조

BigQuery에 저장되는 로그 데이터의 스키마는 다음과 같습니다:

필드타입설명
timestampTIMESTAMP로그 발생 시간
serviceSTRING서비스 이름
levelSTRING로그 레벨
messageSTRING로그 메시지
contextSTRING로그 컨텍스트
traceSTRING오류 추적 정보
environmentSTRING환경 (dev, staging, prod)
versionSTRING애플리케이션 버전
metadataJSON추가 로그 메타데이터
request_idSTRING요청 ID (추적용)
user_idSTRING사용자 ID (추적용)

주의 사항

  • 민감한 정보: 로그에 개인 식별 정보(PII)나 민감한 데이터를 포함하지 않도록 주의하세요.
  • 로그 볼륨: 과도한 로깅은 성능에 영향을 미치고 비용을 증가시킬 수 있습니다. 적절한 로그 레벨을 사용하세요.
  • BigQuery 비용: BigQuery 로깅을 사용할 때는 데이터 볼륨과 쿼리 비용을 고려하세요.
  • 로그 보존: 정책에 따라 적절한 로그 보존 기간을 설정하세요.
  • 구조화된 로깅: 클라우드 환경에서는 구조화된 로깅(JSON)을 사용하여 로그 분석과 검색을 용이하게 하세요.