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 });
рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдПрдХ рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд┐рдВрд╕реНрдЯрди рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рддрд░реНрдХреЛрдВ рдХреЛ рдкрд╛рд░ рдХрд░рддрд╛ рд╣реИ
@ 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
рдЖрд╕рдкрд╛рд╕ рдХрдИ рдХрд┐рдирд╛рд░реЗ/рдХреЛрдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рддрдп 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"}
рдореИрдВрдиреЗ рд╕рд╛рдорд╛рдиреНрдп рддреНрд╡рд░рд┐рдд рдкреНрд░рд╛рд░рдВрдн рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛
рдПрдХ рдмрд╛рдд рдЬреЛ рдореИрдВрдиреЗ рдиреЛрдЯрд┐рд╕ рдХреА рд╡рд╣ рдпрд╣ рд╣реИ:
рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рддрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ/
рдиреЛрдЯ: рд╡рд┐рдВрд╕реНрдЯрди рдХреЗ рдирд╡реАрдирддрдо рд░рд┐рд▓реАрдЬрд╝ рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛, рдХреЛрдб рдкрд░ рддреНрд╡рд░рд┐рдд рд░реВрдк рд╕реЗ рджреЗрдЦрдиреЗ рд╕реЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрднреА рднреА рдорд╛рд╕реНрдЯрд░ рдореЗрдВ рдРрд╕рд╛ рд╣реА рд╣реИ (рдЬрд┐рд╕рдореЗрдВ рдЕрдиреНрдп рд╕реБрдзрд╛рд░ рд╣реИрдВ рдЬреЛ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ)
@luislobo рдХреЗ рд╕рдорд╛рдзрд╛рди рдкрд░ рдХреБрдЫ рд╕реБрдзрд╛рд░ ЁЯСП
%s %d or %j
рдЬреИрд╕реЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП logger.info(`hello %s`,'world')
printf
рдлрд╝реЙрд░реНрдореЗрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣рдЯрд╛рдпрд╛ рдЧрдпрд╛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
рдЖрджрд┐ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдХрд┐рд╕реА рднреА рдмрд╛рдХреА рддрд░реНрдХреЛрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдореЗрдВ рдЪреВрдХ рдХрд░рддрд╛ рд╣реИ, рддрд╛рдХрд┐ logger.info('hello %d %j', 42, {a:3}, 'some', 'more', 'arguments')
рдЗрд╕ рддрд░рд╣ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ:
hello 42 {"a": 3} some more arguments
рдЗрд╕рдХреЗ рд▓рд┐рдП рдореЗрд░рд╛ рд╕рдорд╛рдзрд╛рди splat
рдкреНрд░рддреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реБрдЖ рд▓реЗрдХрд┐рди рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ util.format()
рд╕реАрдзреЗ printf
рд╕реЗ рдЖрдордВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХреЛрдИ рднреА рдмрд╛рдХреА рддрд░реНрдХ рд╢рд╛рдорд┐рд▓ рд╣реИ:
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()
рдЖрд╣реНрд╡рд╛рди рдХрд░рдХреЗ рдореИрдВ рдЙрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред
рд╡рд╣реА рдореБрджреНрджрд╛, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЕрдкрдбреЗрдЯ? рдореИрдВ рд╡рд┐рдВрд╕реНрдЯрди рд╕реЗ рдкреНрдпрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рдкрд╛рдЧрд▓ рдХрд░ рджреЗрддрд╛ рд╣реИ рдЬрдм рдореИрдВ рд▓рдХрдбрд╝рд╣рд╛рд░реЗ рдХреЛ рджрд┐рдП рдЧрдП рд╕рднреА рддрд░реНрдХреЛрдВ рдХреЛ рдкреНрд░рд┐рдВрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдЬреЛ рдореИрдВ console.log()
рд╕рд╛рде рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред
@ fr1sk рдХреНрдпрд╛ рдЖрдкрдиреЗ рдКрдкрд░ рдореЗрд░реЗ рд╕реНрд╡рд░реВрдкрдг рдХреА рдХреЛрд╢рд┐рд╢ рдХреА? рдпрд╣ console.log()
рдЬреИрд╕рд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рджреЗрддрд╛ рд╣реИ (рдиреЛрдб рдХрд╛ console.log()
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ util.format()
afaik рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)ред
рдпрд╣ рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдЕрднреА рднреА рд╣рд▓ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ, рдФрд░ рдореЗрд░реА рд╕рдВрдмрдВрдзрд┐рдд рд╕рдорд╕реНрдпрд╛ рдХреЛ рд▓реЙрдХ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдореИрдВ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЯреАрдореЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рд╡реЗ рд╕рднреА v3 рдореЗрдВ рдорд╛рдЗрдЧреНрд░реЗрдЯ рдХрд░рддреЗ рд╕рдордп рдкрд┐рдЫрд▓реЗ рдбреАрдПрдХреНрд╕ рдХреЛ рдЦреЛрдиреЗ рдХреА рдирд┐рд░рд╛рд╢рд╛ рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВред
рдореИрдВрдиреЗ рдкреВрд░рд╛ рджрд┐рди рдЪреАрдЬреЛрдВ рдХреЛ рдЖрдЬрдорд╛рдиреЗ рдореЗрдВ рдмрд┐рддрд╛рдпрд╛ рд╣реИред
рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╛рдзрд╛рди рдХрд░реАрдм рдереЗ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХрд╛ рд░рдВрдЧреАрдХрд░рдг рдФрд░ рд▓рд╛рдЗрди рдмреНрд░реЗрдХрд┐рдВрдЧ рдпрд╛рдж рдЖ рд░рд╣реА рдереАред
рдЖрдИрдПрдордУ, рдХрдВрд╕реЛрд▓ рдореЗрдВ рд▓реЙрдЧрд┐рдВрдЧ рдЖрдирдВрджрджрд╛рдпрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдпрд╣рд╛рдБ рдЗрд╕реЗ рд╕рд╛рдХрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдореЗрд░рд╛ рдкреНрд░рдпрд╛рд╕ рд╣реИ ...
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
info.message
рд╕рд┐рд░реНрдл рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ рдФрд░ рд╕реНрдЯреИрдХ рдЯреНрд░реИрдХреНрдЯ stack
рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рд╣реИmessage
рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдкрд╛рд╕ рдХрд░рдирд╛ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЗрд╡рд▓ message
рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ, рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдЧреБрдгреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░info.message
(рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХрд╛ рдорд╛рди рд╣реЛрддрд╛ рд╣реИ) рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджреЛ рдмрд╛рд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ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}`;
})
)
});
рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдкреНрд░рдореБрдЦ рд╕рдВрд╕реНрдХрд░рдг рдмреНрд░реЗрдХрд┐рдВрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдкреЗрд╢ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореЗрд░реА рдЕрдЪреНрдЫрд╛рдИ ...
рдХрд┐рд╕реА рднреА рд╕рдорд╛рдзрд╛рди рдиреЗ рдореБрдЭреЗ рд╡рд┐рдВрд╕реНрдЯрди v2 рдХреЗ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рджрд┐рдпрд╛ред
@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>
рджреВрд╕рд░рд╛ рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕реВрдЪрдирд╛ рд╕реНрддрд░ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХреЛрдВ рдХреЛ рджрдмрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╡рд┐рдВрд╕реНрдЯрди v3 рд╕реНрд╡рд░реВрдкрдг рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕реЗ рджреВрд╕рд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред
рддреАрд╕рд░рд╛ рдореБрджреНрджрд╛ 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!'));
рдпрд╣ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИ - рдЬреЛ рдореЗрд░реЗ рд╕рднреА рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд╣реИ:
рдЕрд░реЗ, рдореИрдВ рд╡рд┐рдВрд╕реНрдЯрди рд╕реЗ рд╢реБрд░реВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдХрднреА рднреА 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]);
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░реЗрд╢рд╛рди рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрддрдирд╛ рдмрдбрд╝рд╛ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдЕрднреА рднреА рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЧрд╛рдЗрдб рдпрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред
рднрд▓реЗ рд╣реА рдореИрдВ рдЕрдкрдирд╛ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдЬреЛ рдореБрдЭреЗ рдХрд╛рдлреА рдХреЙрдореНрдкреИрдХреНрдЯ рд▓рдЧрд╛ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ рдХрд┐ рдиреЛрдб рдЬреЗрдПрд╕ рдХрдВрд╕реЛрд▓ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред util.format
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЙрдЧ рдЗрди рдХрд░реЗрдВ
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'),
};
рдореИрдВ рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдХреЛрд░ рд╡рд┐рдВрд╕реНрдЯрди рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реВрдВред рд╡рд░реНрддрдорд╛рди рдореЗрдВ, рдореИрдВ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 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());
рдореИрдВ рдЕрднреА рднреА рд╕рдордЭ рдирд╣реАрдВ рдкрд╛ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рд╡рд┐рдВрд╕реНрдЯрди рдореЗрдВ рдПрдХрд╛рдзрд┐рдХ рдорд╛рдиреЛрдВ рдХреЛ рдХреИрд╕реЗ рдЖрдЙрдЯрдкреБрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдореИрдВ рдмрд╕ console.log('Hello', var1, '!')
рдХреЛ logger.log('Hello', var1, '!')
рд╕реЗ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред
рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рдВрд╕реНрдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рд╕реЗ рд╣рдореЗрд╢рд╛ рдмрд╣реБрдд рд╕рдордп рдмрд░реНрдмрд╛рдж рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд▓реЙрдЧрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░реЗрд╢рд╛рди рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЗрддрдирд╛ рдмрдбрд╝рд╛ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдЕрднреА рднреА рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЧрд╛рдЗрдб рдпрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред
рднрд▓реЗ рд╣реА рдореИрдВ рдЕрдкрдирд╛ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдЬреЛ рдореБрдЭреЗ рдХрд╛рдлреА рдХреЙрдореНрдкреИрдХреНрдЯ рд▓рдЧрд╛ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ рдХрд┐ рдиреЛрдб рдЬреЗрдПрд╕ рдХрдВрд╕реЛрд▓ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
util.format
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЙрдЧ рдЗрди рдХрд░реЗрдВ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
рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред combineMessageAndSplat
рдЬреЛ util.format рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрджреЗрд╢ рдФрд░ рд╡рд┐рднрд╛рдЬрди рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИ
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>
рдореБрдЭреЗ рдХрдВрд╕реЛрд▓ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдирд╛ рдерд╛ред * рд╡рд┐рдзрд┐рдпрд╛рдВ, рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдкрд░ рдЙрдиреНрдореБрдЦ, рдФрд░ ...
рд▓реЗрдХрд┐рди: рдлрд╝рд╛рдЗрд▓ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╡рд┐рд╡рд░рдг рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рддреЛ рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реБрдЖ:
// 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 рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред