winston
๋ฒ์ ?_winston@2
winston@3
node -v
์ถ๋ ฅ:_ v10.12.0PrettyPrint๊ฐ ์๋ํ์ง ์์ต๋๋ค
winston.format.combine(
winston.format.timestamp(),
winston.format.colorize(),
winston.format.prettyPrint(),
winston.format.splat(),
winston.format.simple(), // removing this gives an even worse output
)
winston 2์ ๋์ผํ ๋์์ ๊ฐ์ง
winston 2์์ ๋์ผํ ๋ก๊ทธ ๋์์ ์ป์ผ๋ ค๊ณ ์๋ํ์ง๋ง ์๋ํ์ง ์์ต๋๋ค. ๋ก๊ทธ๊ฐ ๋ชจ๋ ์ค์ผ๋์ด ์ฝ์ ์ ์ก์ ์ฌ์ฉํ์ฌ ์ฝ์ ์ ์์ต๋๋ค.
๋๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ์์๋ค. #1537์ ๋ณด์ญ์์ค.
๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ ๋์ ๋๊ตฐ๊ฐ๊ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ๊ณ ์๋ค๋ฉด ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์ ๋ํด ๋ค์ ํ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
import { format } from 'winston';
const {
colorize,
combine,
timestamp,
errors,
printf,
splat,
} = format;
const devFormat = combine(
format((info) => {
info.level = info.level.toUpperCase();
return info;
})(),
colorize(),
timestamp(),
splat(),
errors(),
printf(
({
timestamp,
level,
message,
...rest
}) => {
let restString = JSON.stringify(rest, undefined, 2);
restString = restString === '{}' ? '' : restString;
return `[${timestamp}] ${level} - ${message} ${restString}`;
},
),
);
๋๋ฅผ ์ํด ์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค :
๋ค์ ์ ๋ชจ์ S3 ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋์ ์ผ๋ก ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๋ช ๊ฐ์ง ์ํ ์ฝ๋์ ๋๋ค.
~/repos/ghe/lambda-logging (master *% u=)> node -r dotenv/config ./src/test-harness.js
{
module: 'app.js',
s3SchemaVersion: '1.0',
configurationId: '828aa6fc-f7b5-4305-8584-487c791949c1',
bucket: {
name: 'lambda-artifacts-deafc19498e3f2df',
ownerIdentity: { principalId: 'A3I5XTEXAMAI3E' },
arn: 'arn:aws:s3:::lambda-artifacts-deafc19498e3f2df'
},
object: {
key: 'b21b84d653bb07b05b1e6b33684dc11b',
size: 1305107,
eTag: 'b21b84d653bb07b05b1e6b33684dc11b',
sequencer: '0C0F6F405D6ED209E1'
},
level: 'INFO',
message: 'processing event',
timestamp: '2020-05-09 20:03:43'
}
{
level: 'ERROR',
module: 'index.js',
timestamp: '2020-05-09 20:03:43',
message: "Cannot read property '0' of undefined",
stack: "TypeError: Cannot read property '0' of undefined\n" +
' at Object.run (/Users/jason.berk/repos/ghe/lambda-logging/src/app.js:5:26)\n' +
' at Object.exports.handler (/Users/jason.berk/repos/ghe/lambda-logging/src/index.js:7:22)\n' +
' at Object.<anonymous> (/Users/jason.berk/repos/ghe/lambda-logging/src/test-harness.js:44:9)\n' +
' at Module._compile (internal/modules/cjs/loader.js:1158:30)\n' +
' at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)\n' +
' at Module.load (internal/modules/cjs/loader.js:1002:32)\n' +
' at Function.Module._load (internal/modules/cjs/loader.js:901:14)\n' +
' at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)\n' +
' at internal/main/run_main_module.js:18:47'
}
๋ด ๋ก๊ฑฐ ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const path = require('path');
const { createLogger, format, transports } = require('winston');
const { combine, errors, timestamp } = format;
const baseFormat = combine(
timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
errors({ stack: true }),
format((info) => {
info.level = info.level.toUpperCase();
return info;
})(),
);
const splunkFormat = combine(
baseFormat,
format.json(),
);
const prettyFormat = combine(
baseFormat,
format.prettyPrint(),
);
const createCustomLogger = (moduleName) => createLogger({
level: process.env.LOG_LEVEL,
format: process.env.PRETTY_LOGS ? prettyFormat : splunkFormat,
defaultMeta: { module: path.basename(moduleName) },
transports: [
new transports.Console(),
],
});
module.exports = createCustomLogger;
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ ๋์ ๋๊ตฐ๊ฐ๊ฐ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ๊ณ ์๋ค๋ฉด ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์ ๋ํด ๋ค์ ํ์์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.