1- // blanc-logger.ts
21import * as chalk from 'chalk' ;
32import { WinstonModule } from 'nest-winston' ;
43import * as util from 'util' ;
@@ -8,7 +7,6 @@ import { generateUUID } from '../helper/uuid';
87import { LOGGING_CONFIG } from './logger.config' ;
98
109const { LOG_DIR , CONSOLE_LOG_LEVEL , FILE_LOG_LEVEL , ROTATION_DAYS , MAX_FILE_SIZE } = LOGGING_CONFIG ;
11-
1210const MAX_OBJECT_DEPTH = 5 ;
1311const MAX_OBJECT_WIDTH = 120 ;
1412
@@ -20,6 +18,7 @@ export interface CustomTransformableInfo extends winston.Logform.TransformableIn
2018 context ?: { moduleName ?: string } | string ;
2119}
2220
21+ /** util.inspect의 사전 정의된 옵션을 사용하여 객체를 문자열로 포맷팅 */
2322const deepInspector = ( obj : unknown ) : string =>
2423 util . inspect ( obj , {
2524 colors : true ,
@@ -29,6 +28,7 @@ const deepInspector = (obj: unknown): string =>
2928 sorted : true ,
3029 } ) ;
3130
31+ /** 로그 레벨에 해당하는 이모지를 매핑 */
3232const emojiMap : Record < string , string > = {
3333 error : '🚨' ,
3434 warn : '⚠️' ,
@@ -37,6 +37,7 @@ const emojiMap: Record<string, string> = {
3737 debug : '🐛' ,
3838} ;
3939
40+ /** 로그 레벨에 해당하는 chalk 색상 함수를 매핑 */
4041const levelColorMap : Record < string , ( text : string ) => string > = {
4142 error : chalk . hex ( '#FF6B6B' ) ,
4243 warn : chalk . hex ( '#FFD93D' ) ,
@@ -45,23 +46,21 @@ const levelColorMap: Record<string, (text: string) => string> = {
4546 verbose : chalk . hex ( '#6BCB77' ) ,
4647} ;
4748
48- const moduleHierarchyFormat = winston . format (
49- ( info : CustomTransformableInfo ) : CustomTransformableInfo => {
50- if ( typeof info . moduleName === 'string' ) {
51- info . moduleName = info . moduleName
52- . split ( '/' )
53- . map ( ( part : string ) => chalk . cyan ( part ) )
54- . join ( chalk . dim ( ' → ' ) ) ;
55- }
56- return info ;
57- } ,
58- ) ;
49+ /** 모듈 경로를 색상이 적용된 계층적 문자열로 변환 */
50+ const moduleHierarchyTransform = ( info : CustomTransformableInfo ) : CustomTransformableInfo => {
51+ info . moduleName =
52+ info . moduleName ?. split ( '/' ) ?. map ( ( part : string ) => chalk . cyan ( part ) ) ?. join ( chalk . dim ( ' → ' ) ) ??
53+ info . moduleName ;
54+ return info ;
55+ } ;
5956
57+ /** 파일 로그에 대한 타임스탬프와 JSON 포맷을 결합 */
6058const fileLogFormat = winston . format . combine (
6159 winston . format . timestamp ( { format : 'YYYY-MM-DD HH:mm:ss' } ) ,
62- winston . format . json ( ) ,
60+ winston . format . json ( )
6361) ;
6462
63+ /** 로그 파일 순환을 위한 DailyRotateFile 전송 객체를 생성 */
6564const createDailyRotateFileTransport = ( filename : string , level : string ) : DailyRotateFile =>
6665 new DailyRotateFile ( {
6766 dirname : LOG_DIR ,
@@ -74,52 +73,52 @@ const createDailyRotateFileTransport = (filename: string, level: string): DailyR
7473 format : fileLogFormat ,
7574 } ) ;
7675
77- const addMetaData = winston . format ( ( info : CustomTransformableInfo ) : CustomTransformableInfo => {
78- if ( ! info . logId ) {
79- info . logId = generateUUID ( ) ;
80- }
76+ /** 로그 메타데이터에 고유한 logId가 없으면 추가 */
77+ const addMetaDataTransform = ( info : CustomTransformableInfo ) : CustomTransformableInfo => {
78+ info . logId ??= generateUUID ( ) ;
79+ return info ;
80+ } ;
81+
82+ /** 제공된 moduleName 또는 context 속성을 사용하여 모듈 이름을 포맷팅 */
83+ const formatModuleName = ( info : CustomTransformableInfo ) : string => {
84+ const moduleName =
85+ info . moduleName ?? ( typeof info . context === 'object' ? info . context ?. moduleName : info . context ) ;
86+ return moduleName ? `[${ moduleName } ]` : '' ;
87+ } ;
88+
89+ /** 로그 메시지를 포맷팅하며, 객체인 경우 deepInspector를 사용하여 포맷팅 */
90+ const formatMessage = ( info : CustomTransformableInfo ) : string => {
91+ const message = info . stack || info . message ;
92+ return typeof message === 'object' ? deepInspector ( message ) : String ( message ) ;
93+ } ;
94+
95+ /** 이모지를 추가하고 대문자로 변환하여 로그 레벨을 변환 */
96+ const transformLogLevel = ( info : CustomTransformableInfo ) : CustomTransformableInfo => {
97+ info . rawLevel = info . level ;
98+ info . level = `${ emojiMap [ info . level ] || '' } ${ info . level . toUpperCase ( ) } ` . padEnd ( 5 ) ;
8199 return info ;
82- } ) ;
100+ } ;
83101
102+ /** 다양한 포맷팅 함수를 결합하여 최종 콘솔 로그 포맷을 생성 */
84103const customConsoleFormat = winston . format . combine (
85- addMetaData ( ) ,
104+ winston . format ( addMetaDataTransform ) ( ) ,
86105 winston . format . timestamp ( { format : 'YYYY-MM-DD HH:mm:ss' } ) ,
87- moduleHierarchyFormat ( ) ,
88- winston . format ( ( info : CustomTransformableInfo ) : CustomTransformableInfo => {
89- info . rawLevel = info . level ;
90- info . level = `${ emojiMap [ info . level ] || '' } ${ info . level . toUpperCase ( ) } ` . padEnd ( 5 ) ;
91- return info ;
92- } ) ( ) ,
106+ winston . format ( moduleHierarchyTransform ) ( ) ,
107+ winston . format ( transformLogLevel ) ( ) ,
93108 winston . format . printf ( ( info : CustomTransformableInfo ) : string => {
94109 const colorFunc =
95110 levelColorMap [ info . rawLevel ?? '' ] || ( ( text : string ) : string => chalk . bold . white ( text ) ) ;
96111 const coloredLevel = colorFunc ( info . level ) ;
97112 const simpleLogId = info . logId ? chalk . hex ( '#00008B' ) ( `[${ info . logId . substring ( 0 , 8 ) } ]` ) : '' ;
98- let moduleName : string | undefined ;
99- if ( ! info . moduleName && info . context ) {
100- if (
101- typeof info . context === 'object' &&
102- info . context !== null &&
103- 'moduleName' in info . context
104- ) {
105- moduleName = ( info . context as { moduleName ?: string } ) . moduleName ;
106- } else if ( typeof info . context === 'string' ) {
107- moduleName = info . context ;
108- }
109- } else {
110- moduleName = info . moduleName ;
111- }
112- const moduleStr = moduleName ? `[${ moduleName } ]` : '' ;
113- let message : unknown = info . stack || info . message ;
114- if ( typeof message === 'object' ) {
115- message = deepInspector ( message ) ;
116- }
117- return `${ simpleLogId } ${ chalk . dim (
118- info . timestamp ,
119- ) } ${ coloredLevel } ${ moduleStr } - ${ chalk . blueBright ( message as string ) } `;
120- } ) ,
113+ const moduleStr = formatModuleName ( info ) ;
114+ const messageStr = formatMessage ( info ) ;
115+ return `${ simpleLogId } ${ chalk . dim ( info . timestamp ) } ${ coloredLevel } ${ moduleStr } - ${ chalk . blueBright (
116+ messageStr
117+ ) } `;
118+ } )
121119) ;
122120
121+ /** 구성된 전송 및 포맷을 사용하여 WinstonModule로 blancLogger를 생성 */
123122export const blancLogger = WinstonModule . createLogger ( {
124123 transports : [
125124 new winston . transports . Console ( {
@@ -133,4 +132,4 @@ export const blancLogger = WinstonModule.createLogger({
133132 ] ,
134133 exceptionHandlers : [ createDailyRotateFileTransport ( 'exceptions' , 'error' ) ] ,
135134 rejectionHandlers : [ createDailyRotateFileTransport ( 'rejections' , 'error' ) ] ,
136- } ) ;
135+ } ) ;
0 commit comments