winston
ããŒãžã§ã³ïŒ_winston@2
winston@3
node -v
åºåïŒ_ v8.11.3
3.xxã®å ŽåïŒ
const winston = require('winston')
const logger = winston.createLogger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
åºåïŒ
{"level":"info","message":"test log"}
2.xxã®å ŽåïŒ
const winston = require('winston')
const logger = new winston.Logger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
åºåïŒ
info: test log with a second parameter
次ã®ããã«åºåãããŸãã
{"level":"info","message":"test log with a second parameter"}
ç§ã¯ä»æ¥åãåé¡ã«ééããŸããã ã¢ããã°ã¬ãŒãããã¥ã¡ã³ãã«ããã®ãããªäŸãããã®ã§ãããã¯ãã°ã ãšæããŸãïŒ
logger.info('transaction ok', { creditCard: 123456789012345 });
çŸåšããããåé¿ããããã«ãwinstonã«æž¡ãããåã«åŒæ°ã解æããé¢æ°ãäœæã§ããŸãã
@ mulligan121ããããŸããããã³ãŒãããŒã¹å ã®ãã¹ãŠã®ãã°ã¹ããŒãã¡ã³ãã眮ãæããããããŸãã...
@indexzeroããã¯ããªãã®ã¬ãŒããŒã®äžã«ãããŸããïŒ ããã¯å€§ããªå€åã ãšæããŸãã ãã¹ãŠã®ãã°ãšã³ããªãå€æŽããå¿ èŠããããããå®éã«ã¯2.xãã3.xã«ç§»åã§ããŸããã
äžæçãªåé¿çïŒ
const wrapper = ( original ) => {
return (...args) => original(args.join(" "));
};
winstonLogger.error = wrapper(winstonLogger.error);
winstonLogger.warn = wrapper(winstonLogger.warn);
winstonLogger.info = wrapper(winstonLogger.info);
winstonLogger.verbose = wrapper(winstonLogger.verbose);
winstonLogger.debug = wrapper(winstonLogger.debug);
winstonLogger.silly = wrapper(winstonLogger.silly);
ããã¯ç§ãã¡ã«ãšã£ãŠå€§ããªå€é©ã§ãã æå³çãªãã®ã§ããå Žåã¯ã httpsïŒ//github.com/winstonjs/winston/blob/master/UPGRADE-3.0.mdã§è©³ãã説æããå¿ èŠããã
ãããã£ãŠãããã«èª¿æ»ããçµæãè€æ°ã®åŒæ°ãåºåããã«ã¯ãã¹ãã©ãããã©ãŒããã¿ãå¿
èŠã§ããããšãããããŸããã ããã¯åŒæ°ã®è£éïŒã€ãŸããïŒ
sãªã©ãå«ãŸããŠãããã®ïŒã®ããã ãã ãšæããŸãããã logger.info("something", value)
ãå®è¡ããããã ãã«å¿
èŠãªããã§ãã
ããããããã¯ç§ã«ãšã£ãŠã¯ãŸã å°ãå¥åŠã§ã-JSON圢åŒã䜿çšããŠããªããŠããåºåã«ãã¡ã¿ãããŒãæã€JSONã®ãããªãã®ã衚瀺ãããŸãã
logger.info('Test: %s', 1, 2, 3, 4);
çç£ïŒ
info: Test: 1 {"meta":[2,3,4]}
äŸã®äŸã§ããããããèšãããšãçã¿åºããŸããïŒ
https://github.com/winstonjs/winston/blob/master/examples/interpolation.js#L20 -L21
info: test message first, second {"meta":{"number":123}}
ç§ã¯ãããã®ç·ã«æ²¿ã£ãäœãã䜿çšããŠããã解決ããŸããïŒ
const { version } = require('../package');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, colorize, label, printf, align } = format;
const { SPLAT } = require('triple-beam');
const { isObject } = require('lodash');
function formatObject(param) {
if (isObject(param)) {
return JSON.stringify(param);
}
return param;
}
// Ignore log messages if they have { private: true }
const all = format((info) => {
const splat = info[SPLAT] || [];
const message = formatObject(info.message);
const rest = splat.map(formatObject).join(' ');
info.message = `${message} ${rest}`;
return info;
});
const customLogger = createLogger({
format: combine(
all(),
label({ label: version }),
timestamp(),
colorize(),
align(),
printf(info => `${info.timestamp} [${info.label}] ${info.level}: ${formatObject(info.message)}`)
),
transports: [new transports.Console()]
});
è€æ°ã®ãã©ã¡ãŒã¿ãèš±å¯ããããã®äžè¬çãªåé¿çã¯æ¬¡ã®ãšããã§ãã
https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
é¢é£ïŒ
https://github.com/winstonjs/winston/issues/1377
åãããã«æ©èœããªããã®ãå€ãããŸãã
ããã«ã¡ã¯ãããã«æŽæ°ã¯ãããŸããïŒ ããããšãã
ãŸãããŠã£ã³ã¹ãã³ã§console.log(...args)
ããšãã¥ã¬ãŒãããé©åãªæ¹æ³ãåŸ
ã£ãŠããŸã...
ç§ãã¡ã¯ãåšãã®ãšããž/ã³ãŒããŒã±ãŒã¹ã®æ°ãåºå®splat
ãšmeta
ã§3.2.0
ããããã¯ãŸã åé¡ïŒåç
§ã§è¡šç€ºãããŸããhttps://github.com / winstonjs / winston / pull / 1576ïŒ CHANGELOG.md
ïŒã
ããã3.3.0
åŠçãããããšã確èªããŸãã ããªãã®å¿èã®äººã
ã«æè¬ããŸãã
ããã¯ç§ã«ãšã£ãŠã®åé¿çã§ããïŒ
'use strict';
const { createLogger, format, transports } = require('winston');
const { SPLAT } = require('triple-beam');
const { combine, timestamp, label, printf, colorize } = format;
const formatObject = (param) => {
if (typeof param === 'string') {
return param;
}
if (param instanceof Error) {
return param.stack ? param.stack : JSON.stringify(param, null, 2);
}
return JSON.stringify(param, null, 2);
};
const logFormat = printf((info) => {
const { timestamp: ts, level, message } = info;
const rest = info[SPLAT] || [];
const msg = info.stack ? formatObject(info.stack) : formatObject(message);
let result = `${ts} ${level}: ${msg}`;
if (rest.length) {
result += `\n${rest.map(formatObject).join('\n')}`;
}
return result;
});
const logger = createLogger({
format: combine(
label({ label: 'app' }),
timestamp(),
logFormat,
),
transports: [
new transports.Console({
format: combine(colorize()),
handleExceptions: true,
}),
],
exceptionHandlers: [
new transports.File({ filename: 'exceptions.log' }),
],
});
åŒæ°ã䜿çšããŠãã°ã«èšé²ããããšãããšãå¥åŠãªåºåãåŸãããŸãvar s = "Hello"
log.info("asdasda", s)
åºåãååŸãã
{"0":"H","1":"e","2":"l","3":"l","4":"o","service":"XXXX","level":"info","message":"asdasda","timestamp":"2019-04-15 13:58:51"}
éåžžã®ã¯ã€ãã¯ã¹ã¿ãŒãã³ãŒãã䜿çšããŸãã
ç§ãæ°ã¥ããããšã®1ã€ã¯ããã§ãïŒ
ãããä¿®æ£ã§ãã/ä¿®æ£ãããããšãé¡ã£ãŠããŸã
泚ïŒWinstonã®ææ°ãªãªãŒã¹ããŒãžã§ã³ã§ããããã¹ãããŸãããã³ãŒãããã£ãšèŠãŠã¿ããšããã¹ã¿ãŒã§ã¯ãŸã ãã®ããã«ãªã£ãŠããããã§ãïŒä»ã®ä¿®æ£ãããããã§ãïŒ
@luisloboã®ãœãªã¥ãŒã·ã§ã³ã«å¯Ÿããããã€ãã®æ¹åð
logger.info(`hello %s`,'world')
ãããªã¡ãã»ãŒãžã«%s %d or %j
ãå«ãŸããŠããå Žåã¯ãã¡ãã»ãŒãžãç¡èŠããŸãprintf
twiseformateObjectãåé€ããŸããtrimEnd
const { version } = require('../package');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, colorize, label, printf, align } = format;
const { SPLAT } = require('triple-beam');
const { isObject,trimEnd } = require('lodash');
function formatObject(param) {
if (isObject(param)) {
return JSON.stringify(param);
}
return param;
}
const all = format((info) => {
const splat = info[SPLAT] || []
const isSplatTypeMessage =
typeof info.message === 'string' &&
(info.message.includes('%s') || info.message.includes('%d') || info.message.includes('%j'))
if (isSplatTypeMessage) {
return info
}
const message = formatObject(info.message)
const rest = splat
.map(formatObject)
.join(' ')
info.message = trimEnd(`${message} ${rest}`)
return info
});
const customLogger = createLogger({
format: combine(
colorize(),
all(),
label({ label: version }),
timestamp(),
align(),
printf(info => `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`)
),
transports: [new transports.Console()]
});
ç§ãè¡æ¹äžæã«ãªã£ãŠãããããããªããããžã®ãããªãæŽæ°ã¯ãããŸããïŒ ãã®æ©èœãå床远å ããããšã¯ããªã匷åã«ãµããŒããããŠããããã§ãããããã«å¯ŸããæåŸã®åãçµã¿ã¯ã»ãŒ6ãæåã§ããã
ããã«ã¡ã¯ã巚倧ãªãã³ããŒãšã·ã§ãŒã¹ããããŒã3.Xã«ç§»è¡ããããšãããšããããããã°ããã®é2.xãç¶æããŸãã
å°ããã£ãã:(
ããã¯ç§ã®ããã«åãããã®ã§ãïŒ
const { format, createLogger, transports } = require('winston');
const jsonStringify = require('fast-safe-stringify');
const logLikeFormat = {
transform(info) {
const { timestamp, label, message } = info;
const level = info[Symbol.for('level')];
const args = info[Symbol.for('splat')];
const strArgs = args.map(jsonStringify).join(' ');
info[Symbol.for('message')] = `${timestamp} [${label}] ${level}: ${message} ${strArgs}`;
return info;
}
};
const debugFormat = {
transform(info) {
console.log(info);
return info;
}
};
const logger = createLogger({
format: format.combine(
// debugFormat, // uncomment to see the internal log structure
format.timestamp(),
format.label({ label: 'myLabel' }),
logLikeFormat,
// debugFormat, // uncomment to see the internal log structure
),
transports: [
new transports.Console()
]
});
logger.info('foo', 'bar', 1, [2, 3], true, { name: 'John' });
çµæã¯æ¬¡ã®ããã«ãªããŸãïŒ 2019-07-04T21:30:08.455Z [myLabel] info: foo "bar" 1 [2,3] true {"name":"John"}
åºæ¬çã«ã format.combine
ã¯info
ãªããžã§ã¯ãã®ãã€ãã©ã€ã³ãèšå®ããŸãã ãã©ãŒãããé¢æ°ããšã«ã transform
ãåŒã³åºãããæçµçãªãã°ã¡ãã»ãŒãžãinfo[Symbol.for('message')]
æžã蟌ãŸããå¿
èŠããããŸãã
ã圹ã«ç«ãŠãã°
%d
ã %o
ãªã©ããµããŒããããœãªã¥ãŒã·ã§ã³ãå¿
èŠ%d
ãããã©ã«ãã§ã¯æ®ãã®åŒæ°ãå«ãŸããŠããããã logger.info('hello %d %j', 42, {a:3}, 'some', 'more', 'arguments')
ã¯æ¬¡ã®ããã«ã¬ã³ããªã³ã°ãããŸãã
hello 42 {"a": 3} some more arguments
ããã«å¯Ÿããç§ã®è§£æ±ºçã¯ãæçµçã«splat
ã·ã³ãã«ã䜿çšããŸãããã printf
ããçŽæ¥util.format()
æåã§åŒã³åºããŸãããããã«ã¯ãããã©ã«ãã§æ®ãã®åŒæ°ãå«ãŸããŠããŸãã
const {format} = require('util');
const winston = require('winston');
const {combine, timestamp, printf} = winston.format;
const SPLAT = Symbol.for('splat');
const transport = new winston.transports.Console({
format: combine(
timestamp(),
printf(({timestamp, level, message, [SPLAT]: args = []}) =>
`${timestamp} - ${level}: ${format(message, ...args)}`)
)
})
printf
å¿
èŠãªãå Žåã¯ããã¡ããã代ããã«åŒæ°ãinfo.message
ã«å±éããå€æãè¿œå ããŠãæçµçµæã奜ããªããã«ãã©ãŒãããããããšãã§ããŸãã
format: combine(
{
transform(info) {
const {[SPLAT]: args = [], message} = info;
info.message = format(message, ...args);
return info;
}
},
simple()
)
format.splat()
ã䜿çšããå Žåã®åé¡ã¯ãäžèŽããåŒæ°ãæ¶è²»ããŸãããæ®ããç Žæ£ããããã«èŠããããšã§ãã util.format()
èªåã§åŒã³åºãããšã§ããã®åäœããªãŒããŒã©ã€ãã§ããŸãã
åãåé¡ãããã«é¢ããæŽæ°ã¯ãããŸããïŒ Winstonã¯å€§å¥œãã§ããããã¬ãŒã«æž¡ããããã¹ãŠã®åŒæ°ãåºåã§ããªããšãé ããããããªããŸããããã¯ã console.log()
å®è¡ã§ããŸãã
@ fr1skäžèšã®ãã©ãŒããããè©ŠããŸãããïŒ console.log()
ãããªåäœãæäŸããŸãïŒããŒãã®console.log()
å®è£
ã¯å
éšçã«util.format()
afaikã䜿çšããŸãïŒã
ãã®åé¡ããŸã 解決ãããŠããããé¢é£ããåé¡ãããã¯ãããŠããã®ã¯æ®å¿µã§ãã
ç§ã¯å€ãã®ç°ãªãããŒã ãšååããŠãããv3ã«ç§»è¡ãããšãã«ä»¥åã®DXã倱ãããšãžã®ãã©ã¹ãã¬ãŒã·ã§ã³ãå
±æããŠããŸãã
ç§ã¯äžæ¥äžç©äºãè©ŠããŠã¿ãŸããã
äžèšã®è§£æ±ºçã¯è¿ããã®ã§ããããäœåãªåŒæ°ã®è²ä»ããšæ¹è¡ããããŸããã§ããã
IMOãã³ã³ãœãŒã«ãžã®ãã°èšé²ã¯æ¥œããã¯ãã§ãã
ããããããå®çŸããããã®ç§ã®è©Šã¿ã§ã...
const winston = require('winston');
const chalk = require('chalk');
const logger = new winston.Logger({
transports: [
new winston.transports.Console({
level: 'info',
colorize: true,
prettyPrint: true,
timestamp: true
})
]
});
logger.info({ one: 1, two: 2, three: 3 });
logger.info(chalk.blue('[TEST]:'), { one: 1, two: 2, three: 3 }, [4, 5, 6]);
logger.info(chalk.blue('[TEST]:'), null, undefined, 'one', 2, { 3: 3, 4: '4' });
logger.info(chalk.blue('[TEST]:'), chalk.yellow('Bombastic'), () => {}, /foo/);
logger.error(chalk.blue('[ERR]:'), new Error('Error number 1'));
logger.error(new Error('Error number 2'));
const { createLogger, format, transports } = require('winston');
const { inspect } = require('util');
const chalk = require('chalk');
const hasAnsi = require('has-ansi');
function isPrimitive(val) {
return val === null || (typeof val !== 'object' && typeof val !== 'function');
}
function formatWithInspect(val) {
const prefix = isPrimitive(val) ? '' : '\n';
const shouldFormat = typeof val !== 'string' || !hasAnsi(val);
return prefix + (shouldFormat ? inspect(val, { depth: null, colors: true }) : val);
}
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.errors({ stack: true }),
format.colorize(),
format.printf(info => {
const msg = formatWithInspect(info.message);
const splatArgs = info[Symbol.for('splat')] || [];
const rest = splatArgs.map(data => formatWithInspect(data)).join(' ');
return `${info.timestamp} - ${info.level}: ${msg} ${rest}`;
})
),
transports: [new transports.Console()]
});
logger.info({ one: 1, two: 2, three: 3 });
logger.info(chalk.blue('[TEST]:'), { one: 1, two: 2, three: 3 }, [4, 5, 6]);
logger.info(chalk.blue('[TEST]:'), null, undefined, 'one', 2, { 3: 3, 4: '4' });
logger.info(chalk.blue('[TEST]:'), chalk.yellow('Bombastic'), () => {}, /foo/);
logger.error(chalk.blue('[ERR]:'), new Error('Error number 1'));
logger.error(new Error('Error number 2'));
chalk
ã䜿çšãããªã©ãANSIãšã¹ã±ãŒãã³ãŒããå«ãæååinfo.message
ãåãªãæååã§ãããã¹ã¿ãã¯ãã©ã¯ããstack
ããããã£ã«ããããã§ããmessage
第äžåŒæ°ã®ã¿å°å·ããŠããããã£message
ä»ã®ããããã£ãç Žæ£ããinfo.message
ïŒéåžžã¯1çªç®ã®åŒæ°ã®å€ïŒã®äžã«é£çµããããšã©ãŒã¡ãã»ãŒãžã2å衚瀺ãããŸããerrors
ãã©ãŒããã¿ãŒãããã£ãŠã¿ãŠã圹ã«ç«ã¡ãŸããã§ããã
ãšã©ãŒã®ãã©ãŒãããã¯åŠçã§ããŸãããããããŒã§ãã
function formatWithInspect(val) {
+ if (val instanceof Error) {
+ return '';
+ }
const prefix = isPrimitive(val) ? '' : '\n';
const shouldFormat = typeof val !== 'string' || !hasAnsi(val);
return prefix + (shouldFormat ? inspect(val, { depth: null, colors: true }) : val);
}
...
format.printf((info) => {
const msg = formatWithInspect(info.message);
const splatArgs = info[Symbol.for('splat')] || [];
const rest = splatArgs.map((data) => formatWithInspect(data)).join(' ');
+ const stackTrace = info.stack ? `\n${info.stack}` : '';
return `${info.timestamp} - ${info.level}: ${msg} ${rest}${stackTrace}`;
})
...
info[Symbol.for('splat')]
ã䜿çšããŠåäœããŸã
const logger = winston.createLogger({
level: 'debug',
transports: [
...
],
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf((info: any) => {
const timestamp = info.timestamp.trim();
const level = info.level;
const message = (info.message || '').trim();
const args = info[Symbol.for('splat')];
const strArgs = (args || []).map((arg: any) => {
return util.inspect(arg, {
colors: true
});
}).join(' ');
return `[${timestamp}] ${level} ${message} ${strArgs}`;
})
)
});
ã¡ãžã£ãŒããŒãžã§ã³ã§ã¯é倧ãªå€æŽãå°å ¥ãããŠããããšã¯ç解ããŠããŸãããç§ã®è¯ãã¯...
ã©ã®ãœãªã¥ãŒã·ã§ã³ããwinstonv2ãšåãåäœãããŸããã§ããã
@henhalãš@yamadashyã®ãœãªã¥ãŒã·ã§ã³ã«ã¯ãã©ã¡ããåãåé¡ããããŸããã¡ãã»ãŒãžå€ãæååãšããŠè¡šç€ºãããŸãã
logger.debug(err)
ãã°ã¡ãã»ãŒãžã®äœæïŒ
debug: Error: ETIMEDOUT
äžæ¹ã logger.debug('anystringhere', err)
ã¯ä»¥äžãäœæããŸãã
debug: anystringhereError: ETIMEDOUT { RequestError: Error: ETIMEDOUT
at new RequestError (/path/to/node_modules/request-promise-core/lib/errors.js:14:15)
<the rest of full error stack here>
2çªç®ã®åé¡ã¯ãæ å ±ã¬ãã«ã§äœ¿çšãããšè¿œå ã®åŒæ°ãæå¶ãããããšã§ããwinstonv3ã¯ããã©ãŒãããããåã«ãããéã«åŠçããããã§ãã
3çªç®ã®åé¡ã¯ã2ã€ã®ã¡ãã»ãŒãžã®éã«ã¹ããŒã¹ããªãããšã§ãïŒãanystringhereErrorãã«æ³šæããŠãã ããïŒã
ç§ã®çŸåšã®v3ãã¬ãŒæ§æïŒ
const { format } = require('util');
const winston = require("winston");
const logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: 'debug'
format: winston.format.combine(
winston.format.colorize(),
winston.format.align(),
winston.format.printf(
({level, message, [Symbol.for('splat')]: args = []}) => `${level}: ${format(message, ...args)}`
)
)
}),
]
});
module.exports = logger;
ç§ã¯ãããååã«æã£ãŠããŠãããã ãã§ãŠã£ã³ã¹ãã³v2ã«æ»ãã€ããã§ãïŒ
const Winston = require("winston");
const logger = new Winston.Logger({
transports: [
new Winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
})
],
});
module.exports = logger;
ãã®v2æ§æã«ã¯ãäžèšã®åé¡ã¯ãããŸããã
ãŠã£ã³ã¹ãã³ã®èšå®ãå ±æãããïŒ
const util = require('util');
const { createLogger, format, transports } = require('winston');
const { combine, colorize, timestamp, printf, padLevels} = format;
const myFormat = printf(({ level, message, label, timestamp, ...rest }) => {
const splat = rest[Symbol.for('splat')];
const strArgs = splat ? splat.map((s) => util.formatWithOptions({ colors: true, depth: 10 }, s)).join(' ') : '';
return `${timestamp} ${level} ${util.formatWithOptions({ colors: true, depth: 10}, message)} ${strArgs}`;
});
const logger = createLogger({
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
format: combine(
colorize(),
timestamp({
format: 'YYYY-M-DD HH:mm:ss',
}),
padLevels(),
myFormat
),
transports: [new transports.Console()],
});
logger.info('test info');
logger.error('test error');
logger.debug('test debug');
è€æ°ã®ãã©ã¡ãŒã¿ãèš±å¯ããããã®äžè¬çãªåé¿çã¯æ¬¡ã®ãšããã§ãã
https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
ããã«ææ¡ããããœãªã¥ãŒã·ã§ã³ãžã®æŽæ°ããããªã³ã¯ããããŸã
https://github.com/rooseveltframework/roosevelt/blob/0.13.0/lib/tools/logger.js
ç§ã®ã¯@alexilyaevã®çŽ æŽãããææ¡ã®ããªãšãŒã·ã§ã³ã§ãïŒ
const { omit } = require('lodash');
const hasAnsi = require('has-ansi');
function isPrimitive(val) {
return val === null || (typeof val !== 'object' && typeof val !== 'function');
}
function formatWithInspect(val) {
if (val instanceof Error) {
return '';
}
const shouldFormat = typeof val !== 'string' && !hasAnsi(val);
const formattedVal = shouldFormat
? inspect(val, { depth: null, colors: true })
: val;
return isPrimitive(val) ? formattedVal : `\n${formattedVal}`;
}
// Handles all the different log formats for console
function getDomainWinstonLoggerFormat(format) {
return format.combine(
format.timestamp(),
format.errors({ stack: true }),
format.colorize(),
format.printf((info) => {
const stackTrace = info.stack ? `\n${info.stack}` : '';
// handle single object
if (!info.message) {
const obj = omit(info, ['level', 'timestamp', Symbol.for('level')]);
return `${info.timestamp} - ${info.level}: ${formatWithInspect(obj)}${stackTrace}`;
}
const splatArgs = info[Symbol.for('splat')] || [];
const rest = splatArgs.map(data => formatWithInspect(data)).join('');
const msg = formatWithInspect(info.message);
return `${info.timestamp} - ${info.level}: ${msg}${rest}${stackTrace}`;
}),
);
}
次ã®ãããªãã°ã®å ŽåïŒ
logger.info({
joe: 'blow',
});
logger.info('Single String');
logger.info('With Func ', () => {}, /foo/);
logger.info('String One ', 'String Two');
logger.info('String One ', 'String Two ', 'String Three');
logger.info('Single Object ', {
test: 123,
});
logger.info(
'Multiple Objects ',
{
test: 123,
},
{
martin: 5555,
},
);
logger.error('Error: ', new Error('Boom!'));
ããã¯æ¬¡ã®ããã«åºåãããŸã-ããã¯ç§ã®ãã¹ãŠã®ã·ããªãªã«é©ããŠããŸãïŒ
ãããç§ã¯Winstonããå§ããŠãããv2ã䜿çšããããšããªãã®ã§ãv3.2.1ã䜿çšããŠããŸãã
ç§ã¯åçŽã«ããããšããŠããŸããïŒ
import winston, { format } from 'winston';
winston.format(format.combine(format.splat(), format.simple()));
winston.info('buildFastify dataPath %s', opts.dataPath);
ãããŠãæååè£éãæ©èœããããšãæåŸ ããŠããŸãã ããããéããŸãã
{"level":"info","message":"buildFastify dataPath %s"}
æåŸ ããŠããæ
{"level":"info","message":"buildFastify dataPath /My/Data/Path"}
ãã®åé¡ã¯ã©ããããããåãããšã§ããïŒ ãŸãã¯ã代ããã«logger.log('info', .....)
é¢æ°ã䜿çšããå¿
èŠããããŸããïŒ
ãããè©Šè¡ããã€ãã³ãã¯æ©èœããŸããã
winston.log('info', 'buildFastify dataPath %s', opts.dataPath);
åºåïŒ
{"level":"info","message":"buildFastify dataPath %s"}
äžèšã®ææ¡ãæçš¿ããŠããã人ã«æè¬ããŸãã
ãããŒç§ã¯ç§ã®ãããžã§ã¯ãã«ãŠã£ã³ã¹ãã³3ãçµ±åããããã ãã«ããæ¥æšãŠãŸããïŒ/
ããã¯ä»æ¥ç§ã襲ã£ã-ç§ã®æŽŸæãªæ°ãããã¬ãŒãç§ã®ãã¹ãŠã®...rest
åŒæ°ãæããŠããããšã«æ°ã¥ããã ããã¯ãã¹ãŠã®ãŠãŒã¹ã±ãŒã¹ãŸãã¯ãã¹ãŠã®ãŠãŒã¹ã±ãŒã¹ã§æ©èœãããšã¯éããŸããããç§ã®å Žåã¯ããã°ã«èšé²ããããã®ãã¹ãŠãé
åãšããŠã©ããããã ãã§åé¡ãªãããšãããããŸããã ããã¯æãçŸããããã§ã¯ãããŸããããããå€ãã®ã³ãŒããå¿
èŠãšãã[éåžžã«è³¢ã]åé¿çã®ããã€ãããã軜éã§ãã ãããä»ã®èª°ãã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãïŒ
logger.info(["Something happened!", foo, bar]);
圌ããããã»ã©å€§ããªå€æŽãå ããããšã決å®ããããšã«æ¬åœã«è ¹ãç«ãŠã
éåžžã«ã³ã³ãã¯ãã§ãããŒãjsãutil.format
ã䜿çšããŠconsole.logãå®è£
ããæ¹æ³ã«åŸããœãªã¥ãŒã·ã§ã³ãå
±æãããã£ãã®ã§ãã
const winstonLogger= createLogger(...);
const writeLogType = (logLevel) => {
return function () {
const args = Array.from(arguments);
winstonLogger[logLevel](util.format(...args));
};
};
const logger = {
silly: writeLogType('silly'),
debug: writeLogType('debug'),
verbose: writeLogType('verbose'),
info: writeLogType('info'),
warn: writeLogType('warn'),
error: writeLogType('error'),
};
ãã£ã€ã ã鳎ãããŠããã®æ©èœãã³ã¢Winstonã«è¿œå ããããã«èŠæ±ããããšæããŸãã çŸåšãç§ã¯ãã®æ©èœãå®çŸããããã«splat
ã®ã«ã¹ã¿ã ãã©ãŒããã¿ãŒã䜿çšããŠããŸãããããã¯æ£çŽãªãšããéåžžã«ããããŒãªæããããŸãã console.log
äžèŽããæ©èœããããšäŸ¿å©ã§ã
æŽæ°ã¯ãããŸããïŒ
äžèšã®v3ã®åäœã«å ããŠããããè¿œå ããããšæããŸãã
logger.info('param 1', { propInJson1: 'propInJson 1', propInJson2: 'propInJson 2' });
ãããçæããŸã
{"propInJson1":"propInJson 1","propInJson2":"propInJson 2","level":"info","message":"param 1"}
ç§ã䜿çšããŠããããŒãžã§ã³ïŒïŒv3.2.1ïŒ
æ§æïŒ
winstonLogger.add(new winston.transports.Console());
Winstonã§è€æ°ã®å€ãåºåããæ¹æ³ããŸã ããããŸããã
console.log('Hello', var1, '!')
ãlogger.log('Hello', var1, '!')
ã«çœ®ãæãããã£ãã ãã§ãã
æ£çŽãªãšãããWinstonã䜿çšããããšãããšãåžžã«å€ãã®æéãç¡é§ã«ãªãããã®ã³ã°ã§é©ãã¹ãåé¡ãçºçããŸãã
圌ããããã»ã©å€§ããªå€æŽãå ããããšã決å®ããããšã«æ¬åœã«è ¹ãç«ãŠã
éåžžã«ã³ã³ãã¯ãã§ãããŒãjsã
util.format
ã䜿çšããŠconsole.logãå®è£ ããæ¹æ³ã«åŸããœãªã¥ãŒã·ã§ã³ãå ±æãããã£ãã®ã§ããconst winstonLogger= createLogger(...); const writeLogType = (logLevel) => { return function () { const args = Array.from(arguments); winstonLogger[logLevel](util.format(...args)); }; }; const logger = { silly: writeLogType('silly'), debug: writeLogType('debug'), verbose: writeLogType('verbose'), info: writeLogType('info'), warn: writeLogType('warn'), error: writeLogType('error'), };
ãŸãã util.formatWithOptions({ colors: true }, ...args);
ã䜿çšããŠãéåžžã®console.log
ããã«ã«ã©ãŒå°å·åºåãååŸããŸã
ããã¯ç§ã®ããã«åããŸãã util.formatã䜿çšããŠã¡ãã»ãŒãžãšã¹ãã©ãããçµã¿åãããcombineMessageAndSplat
const winston = require("winston");
const util = require('util');
const combineMessageAndSplat = () => {
return {transform: (info, opts) => {
//combine message and args if any
info.message = util.format(info.message, ...info[Symbol.for('splat')] || [] )
return info;
}
}
}
const logger = winston.createLogger({
format:
winston.format.combine(
combineMessageAndSplat(),
winston.format.simple()
)
});
logger.add(new winston.transports.Console({
level: 'info'
})
);
logger.info("string"); // info: string
logger.info({a:1,b:[{c:[1]}]}); // info: { a: 1, b: [ { c: [Array] } ] }
logger.info("1","2",{a:1}); // info: 1 2 { a: 1 }
logger.info([{},""]); // info: [ {}, '' ]
logger.error(new Error()); // error: Error ... at Object.<anonymous>
ç§ã¯consoleã*ã¡ãœããã«æºæ ããå¿ èŠããããäžèšã®ãã¹ãŠãéèŠãã...
ãã ãããã¡ã€ã«åºåã«ã¯ãªããžã§ã¯ãã®è©³çŽ°ã衚瀺ãããŸãã
ã ããç§ã¯çµå±ïŒ
// make File and FileList parseable // from: https://stackoverflow.com/a/51939522/1644202
File.prototype.toObject = function () {
return Object({
name: String(this.name),
path: String(this.path),
lastModified: parseInt(this.lastModified),
lastModifiedDate: String(this.lastModifiedDate),
size: parseInt(this.size),
type: String(this.type)
});
};
FileList.prototype.toArray = function () {
return Array.from(this).map(function (file) {
return file.toObject()
});
};
// this fixes: winston console transport to use the original console functions and all the colorization/folding/etc that comes with it
const Transport = require('winston-transport');
class WebDeveloperConsole extends Transport {
constructor(opts) {
super(opts);
}
log(info, callback) {
(window.console[info.level] || window.console.log).apply(window.console, [info.timestamp, ...info.message]);
callback();
}
};
// Electron app console output
class AppConsole extends Transport {
constructor(opts) {
super(opts);
const { remote } = require('electron');
this.electronConsole = remote.getGlobal('console');
}
log(info, callback) {
(this.electronConsole[info.level] || this.electronConsole.log).apply(this.electronConsole, [info.timestamp, ...info.message]);
callback();
}
};
const util = require('util');
const {
createLogger,
transports,
format
} = require('winston');
let logger = createLogger({
level: 'trace',
levels: {
error: 0,
warn: 1,
info: 2,
//http: 3, no console.* methods
//verbose: 4,
debug: 3,
trace: 4
},
format: format.combine(
format.prettyPrint(),
format.timestamp({
format: 'DD-MM-YYYY hh:mm:ss A'
}),
{
transform(info) {
const { timestamp, message } = info;
const level = info[Symbol.for('level')];
const args = [message, ...(info[Symbol.for('splat')] || [])]; // join the args back into one arr
info.message = args; // for all custom transports (mainly the console ones)
let msg = args.map(e => {
if (e.toString() == '[object FileList]')
return util.inspect(e.toArray(), true, 10);
else if (e.toString() == '[object File]')
return util.inspect(e.toObject(), true, 10);
else if (e.toString() == '[object Object]') {
return util.inspect(e, true, 5);
}
else if (e instanceof Error)
return e.stack
else
return e;
}).join(' ');
info[Symbol.for('message')] = `${timestamp} - ${level}: ${msg}`; // for inbuild transport / file-transport
return info;
}
},
),
transports: [
//new transports.Console(),
new WebDeveloperConsole(),
new AppConsole(),
...
],
...
});
@indexzeroããæç¹ã§ãŸã ããã«å¯ŸåŠããããšãèšç»ããŠãããã©ããçåã«æã£ãŠããŸãããïŒ
ç§ã¯èªåã®ãããžã§ã¯ãã§äœ¿çšãããŠã£ã³ã¹ãã³ãæ¢ããŠããŸããããã®åé¡ã¯2幎以äžç¶ããŠããã®ã§ããªã¹ã¯ãåã䟡å€ãããã®ã§ã¯ãªãããšèããŠããŸãã ç§ã«ãšã£ãŠãããã¯ãããããã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã®åºæ¬çãªæ©èœã®ããã§ã
æãåèã«ãªãã³ã¡ã³ã
ããã¯ç§ãã¡ã«ãšã£ãŠå€§ããªå€é©ã§ãã æå³çãªãã®ã§ããå Žåã¯ã httpsïŒ//github.com/winstonjs/winston/blob/master/UPGRADE-3.0.mdã§è©³ãã説æããå¿ èŠããã