-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from plus-tdd/feature/add_logger
winston + aws sdk cloudwatch log 사용하여 로깅 컨벤션 적용
- Loading branch information
Showing
9 changed files
with
253 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// /* | ||
// import { CloudWatchLogsClient, PutLogEventsCommand } from "@aws-sdk/client-cloudwatch-logs"; | ||
// import winston from 'winston'; | ||
// import * as process from "process"; | ||
// | ||
// export class CloudWatchTransport extends winston.transports.Stream { | ||
// private cloudwatchLogs: CloudWatchLogsClient; | ||
// private readonly logGroupName: string; | ||
// private readonly logStreamName: string; | ||
// constructor(options: { stream?: any }) { | ||
// super(); | ||
// this.cloudwatchLogs = new CloudWatchLogsClient({ | ||
// credentials: { | ||
// accessKeyId: process.env.AWS_ACCESS_KEY_ID, | ||
// secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, | ||
// }, | ||
// region: process.env.CLOUDWATCH_REGION | ||
// }); | ||
// this.logGroupName = process.env.CLOUDWATCH_GROUP_NAME; | ||
// this.logStreamName = process.env.CLOUDWATCH_STREAM_NAME; | ||
// this.stream = options.stream || process.stdout; | ||
// } | ||
// | ||
// async log(info, callback) { | ||
// setImmediate(() => this.emit('logged', info)); | ||
// | ||
// const { level, message, ...meta } = info; | ||
// | ||
// const params = { | ||
// logEvents: [ | ||
// { | ||
// message: `${level}: ${message} ${JSON.stringify(meta)}`, | ||
// timestamp: new Date().getTime() | ||
// } | ||
// ], | ||
// logGroupName: this.logGroupName, | ||
// logStreamName: this.logStreamName, | ||
// // TODO: sequenceToken should be retrieved and managed. | ||
// }; | ||
// | ||
// try { | ||
// await this.cloudwatchLogs.send(new PutLogEventsCommand(params)); | ||
// callback(); | ||
// } catch (error) { | ||
// callback(error); | ||
// } | ||
// } | ||
// } | ||
// | ||
// const logger = winston.createLogger({ | ||
// transports: [ | ||
// new CloudWatchTransport({ stream: process.stdout }), | ||
// ], | ||
// }); | ||
// | ||
// export default logger;*/ | ||
// import { CloudWatchLogsClient, PutLogEventsCommand } from "@aws-sdk/client-cloudwatch-logs"; | ||
// import * as winston from 'winston'; | ||
// | ||
// export class CloudWatchTransport extends winston.transports.Stream { | ||
// private cloudwatchLogs: CloudWatchLogsClient; | ||
// private readonly logGroupName: string; | ||
// private readonly logStreamName: string; | ||
// private sequenceToken: string; | ||
// | ||
// constructor(options: { stream?: any }) { | ||
// super(); | ||
// this.cloudwatchLogs = new CloudWatchLogsClient({ | ||
// credentials: { | ||
// accessKeyId: process.env.AWS_ACCESS_KEY_ID, | ||
// secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, | ||
// }, | ||
// region: process.env.CLOUDWATCH_REGION | ||
// }); | ||
// this.logGroupName = process.env.CLOUDWATCH_GROUP_NAME; | ||
// this.logStreamName = process.env.CLOUDWATCH_STREAM_NAME; | ||
// this.sequenceToken = null; | ||
// this.stream = options.stream || new Stream(); | ||
// } | ||
// | ||
// async log(info, callback) { | ||
// setImmediate(() => this.emit('logged', info)); | ||
// | ||
// const { level, message, ...meta } = info; | ||
// | ||
// const params = { | ||
// logEvents: [ | ||
// { | ||
// message: `${level}: ${message} ${JSON.stringify(meta)}`, | ||
// timestamp: new Date().getTime() | ||
// } | ||
// ], | ||
// logGroupName: this.logGroupName, | ||
// logStreamName: this.logStreamName, | ||
// sequenceToken: this.sequenceToken, | ||
// }; | ||
// | ||
// try { | ||
// await this.cloudwatchLogs.send(new PutLogEventsCommand(params)); | ||
// this.sequenceToken = params.nextSequenceToken; | ||
// callback(); | ||
// } catch (error) { | ||
// callback(error); | ||
// } | ||
// } | ||
// } | ||
// class Stream { | ||
// public write(message: string): void { | ||
// console.log(message); | ||
// } | ||
// } | ||
// const logger = winston.createLogger({ | ||
// transports: [ | ||
// new CloudWatchTransport({ stream: new Stream() }), | ||
// ], | ||
// }); | ||
// | ||
// export default logger; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import winston from 'winston' | ||
import { CloudWatchLogsClient, PutLogEventsCommand } from "@aws-sdk/client-cloudwatch-logs"; | ||
import * as process from "process"; | ||
import moment from 'moment'; | ||
|
||
const { createLogger, format, transports } = winston | ||
const { combine, timestamp, colorize, printf, simple, json ,logstash} = winston.format | ||
|
||
const now = moment().format("YYYY-MM-DD HH:mm:ss"); | ||
|
||
export default class Logger { | ||
private logger: winston.Logger | ||
private cloudWatchClient: CloudWatchLogsClient | ||
LogGroupName: string | ||
LogStreamName: string | ||
private is_production = process.env.NODE_ENV === "production"; | ||
|
||
constructor(private readonly category : string) { | ||
// 실제 클라우드워치에 보내는 역할 | ||
this.logger = createLogger({ | ||
level: this.is_production ? 'info' : 'silly' | ||
}) | ||
|
||
// 프로덕션일경우 추가적으로 클라우드워치 작업 | ||
if (this.is_production) { | ||
this.cloudWatchClient = new CloudWatchLogsClient({ | ||
credentials: { | ||
accessKeyId: process.env.AWS_ACCESS_KEY_ID, | ||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, | ||
}, | ||
region: process.env.CLOUDWATCH_REGION | ||
}) | ||
this.LogGroupName = process.env.CLOUDWATCH_GROUP_NAME | ||
this.LogStreamName = process.env.CLOUDWATCH_STREAM_NAME | ||
|
||
this.logger.add(new transports.Console({ | ||
format: combine( | ||
colorize(), | ||
timestamp({ | ||
format: 'YYYY-MM-DD HH:mm:ss', | ||
}), | ||
printf(info => { | ||
return `[${info.timestamp}] [${info.level}] [${this.category}] : ${info.message}` | ||
}), | ||
)})) | ||
} else { | ||
this.logger.add(new transports.Console({ | ||
format: combine( | ||
colorize(), | ||
timestamp({ | ||
format: 'YYYY-MM-DD HH:mm:ss', | ||
}), | ||
printf(info => { | ||
return `[${info.timestamp}] [${info.level}] [${this.category}] : ${info.message}` | ||
}), | ||
)})) | ||
} | ||
} | ||
|
||
public info(msg: string, metadata: string = "") { | ||
this.logger.info(msg) | ||
if (this.is_production) { | ||
const info = { | ||
timestamp: now, | ||
level: 'info', | ||
category: this.category, | ||
message: msg, | ||
metadata: metadata | ||
} | ||
this.sendToCloudWatch(info) | ||
} | ||
} | ||
public error(errMsg: string, metadata: string = "") { | ||
this.logger.error(errMsg) | ||
if (this.is_production) { | ||
const info = { | ||
timestamp: now, | ||
level: 'error', | ||
category: this.category, | ||
message: errMsg, | ||
metadata: metadata | ||
} | ||
this.sendToCloudWatch(info) | ||
} | ||
} | ||
public debug(debugMsg: string, metadata: string = "") { | ||
this.logger.debug(debugMsg) | ||
} | ||
public warn(warnMsg: string, metadata: string = "") { | ||
this.logger.warn(warnMsg) | ||
if (this.is_production) { | ||
const info = { | ||
timestamp: now, | ||
level: 'debug', | ||
category: this.category, | ||
message: warnMsg, | ||
metadata: metadata | ||
} | ||
this.sendToCloudWatch(info) | ||
} | ||
} | ||
|
||
private sendToCloudWatch(info) { | ||
const logEvents= [ | ||
{ | ||
timestamp: new Date().getTime(), | ||
message: `[${info.timestamp}] [${info.level}] [${info.category}] ${info.metadata !== "" ? "- " + info.metadata : ''} : ${info.message}`, | ||
} | ||
] | ||
const command = new PutLogEventsCommand({ | ||
logGroupName: this.LogGroupName, | ||
logStreamName: this.LogStreamName, | ||
logEvents | ||
}) | ||
this.cloudWatchClient.send(command) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters