使用 Node.js 中的 Winston 在 JSON 对象中输出日志
Outputting Logs inside JSON Object with Winston in Node.js
所以我正在使用 winston.js 登录到一个文件。我已将记录器设置为使用 Winston 默认 JSON 格式输出 JSON。
这是我的记录器配置。
logger.util.js:
'use strict';
const winston = require('winston');
const moment = require('moment');
const logger = winston.createLogger({
format: winston.format.json(),
transports: [
new winston.transports.File({
filename: './logs/' + moment(moment.now()).format('DD-MM-YYYY') + '-API.json',
handleExceptions: true
})
],
});
module.exports = logger;
像这样记录事件时:
logger.log({
'level': 'info',
'timestamp': moment.now(),
'account_id': res.account_id || null,
'action': JSON.stringify(payload),
'request_id': res.request_id,
'status': success.status.code,
'route' : res.method + ' ' + res.route,
'bytes': res.socket.bytesRead || null,
'elapsed': res.elapsed || null,
});
我在我的日志文件中得到以下输出
输出:
{
"level": "error",
"timestamp": 1544708669700,
"account_id": 7,
"action": "SequelizeDatabaseError: column \"alert\" does not exist",
"request_id": "27cc338b-3980-4818-a9e7-83380b1b2c3a",
"status": 500,
"route": "POST /post/new",
"bytes": 714,
"elapsed": 35
}
{
"level": "info",
"timestamp": 1544709322038,
"action": "{\"device\":{\"id\":57},\"removed\":55}",
"status": 200,
"route": "undefined undefined",
"bytes": 517,
"elapsed": null
}
我希望像这样将日志输出到我的文件。以便日后搜索资料。
期望输出:
[
{
"level": "error",
"timestamp": 1544708669700,
"account_id": 7,
"action": "SequelizeDatabaseError: column \"alert\" does not exist",
"request_id": "27cc338b-3980-4818-a9e7-83380b1b2c3a",
"status": 500,
"route": "POST /post/new",
"bytes": 714,
"elapsed": 35
},
{
"level": "info",
"timestamp": 1544709322038,
"action": "{\"device\":{\"id\":57},\"removed\":55}",
"status": 200,
"route": "undefined undefined",
"bytes": 517,
"elapsed": null
}
]
我知道我可能需要使用 Winston 创建自定义格式,想知道是否有人可以给我一个示例?经过我的研究,我无法找到足够相似的东西来解决问题,而且文档也没有给出类似的例子。
希望这就是您要找的。
按以下方式创建自定义传输:
const Transport = require('winston-transport');
const util = require('util');
const fs = require('fs');
module.exports = class CustomTransport extends Transport {
constructor(opts) {
super(opts);
this.filename = opts.filename;
this.setup();
}
initialize() {
try {
fs.writeFileSync(this.filename, [], 'utf8');
} catch (error) {
console.log(error);
}
}
setup() {
// This checks if the file exists
if (fs.existsSync(this.filename)) {
// The content of the file is checked to know if it is necessary to adapt the array
try {
const data = fs.readFileSync(this.filename, 'utf8');
// If the content of the file is not an array, it is set
const content = JSON.parse(data);
if (!Array.isArray(content)) {
this.initialize();
}
} catch (error) {
this.initialize();
console.log(error);
}
}
// Otherwise create the file with the desired format
else {
this.initialize();
}
}
readLog() {
let data = null;
try {
data = fs.readFileSync(this.filename, 'utf8');
} catch (error) {
console.log(error);
}
return data;
}
writeLog(info) {
const data = this.readLog();
let arr = [];
if (data) {
arr = JSON.parse(data);
}
//add data
arr.push(info);
//convert it back to json
const json = JSON.stringify(arr);
try {
// Writing the array again
fs.writeFileSync(this.filename, json, 'utf8');
} catch (error) {
console.log(error)
}
}
log(info, callback) {
setImmediate(() => {
this.emit('logged', info);
});
// Perform the writing
this.writeLog(info);
callback();
}
};
然后按照您放置的代码进行自定义传输器的改编:
'use strict';
const winston = require('winston');
const CustomTransport = require('./CustomTransport');
const moment = require('moment');
const logger = winston.createLogger({
format: winston.format.json(),
transports: [
new CustomTransport({
filename: moment(moment.now()).format('DD-MM-YYYY') + '-API.json',
handleExceptions: true
})
],
});
logger.log({
'level': 'info',
'timestamp': moment.now(),
'account_id': res.account_id || null,
'action': JSON.stringify(payload),
'request_id': res.request_id,
'status': success.status.code,
'route': res.method + ' ' + res.route,
'bytes': res.socket.bytesRead || null,
'elapsed': res.elapsed || null,
});
我尝试了使用虚拟数据的服务,结果是这样的:
[
{
"level": "info",
"timestamp": 1544723041103,
"account_id": 1,
"action": 6,
"request_id": 2,
"status": 3,
"route": 4,
"bytes": 5,
"elapsed": 5
},
{
"level": "info",
"timestamp": 1544724862768,
"account_id": 1,
"action": 6,
"request_id": 2,
"status": 3,
"route": 4,
"bytes": 5,
"elapsed": 5
}
]
所以我正在使用 winston.js 登录到一个文件。我已将记录器设置为使用 Winston 默认 JSON 格式输出 JSON。
这是我的记录器配置。
logger.util.js:
'use strict';
const winston = require('winston');
const moment = require('moment');
const logger = winston.createLogger({
format: winston.format.json(),
transports: [
new winston.transports.File({
filename: './logs/' + moment(moment.now()).format('DD-MM-YYYY') + '-API.json',
handleExceptions: true
})
],
});
module.exports = logger;
像这样记录事件时:
logger.log({
'level': 'info',
'timestamp': moment.now(),
'account_id': res.account_id || null,
'action': JSON.stringify(payload),
'request_id': res.request_id,
'status': success.status.code,
'route' : res.method + ' ' + res.route,
'bytes': res.socket.bytesRead || null,
'elapsed': res.elapsed || null,
});
我在我的日志文件中得到以下输出
输出:
{
"level": "error",
"timestamp": 1544708669700,
"account_id": 7,
"action": "SequelizeDatabaseError: column \"alert\" does not exist",
"request_id": "27cc338b-3980-4818-a9e7-83380b1b2c3a",
"status": 500,
"route": "POST /post/new",
"bytes": 714,
"elapsed": 35
}
{
"level": "info",
"timestamp": 1544709322038,
"action": "{\"device\":{\"id\":57},\"removed\":55}",
"status": 200,
"route": "undefined undefined",
"bytes": 517,
"elapsed": null
}
我希望像这样将日志输出到我的文件。以便日后搜索资料。
期望输出:
[
{
"level": "error",
"timestamp": 1544708669700,
"account_id": 7,
"action": "SequelizeDatabaseError: column \"alert\" does not exist",
"request_id": "27cc338b-3980-4818-a9e7-83380b1b2c3a",
"status": 500,
"route": "POST /post/new",
"bytes": 714,
"elapsed": 35
},
{
"level": "info",
"timestamp": 1544709322038,
"action": "{\"device\":{\"id\":57},\"removed\":55}",
"status": 200,
"route": "undefined undefined",
"bytes": 517,
"elapsed": null
}
]
我知道我可能需要使用 Winston 创建自定义格式,想知道是否有人可以给我一个示例?经过我的研究,我无法找到足够相似的东西来解决问题,而且文档也没有给出类似的例子。
希望这就是您要找的。
按以下方式创建自定义传输:
const Transport = require('winston-transport');
const util = require('util');
const fs = require('fs');
module.exports = class CustomTransport extends Transport {
constructor(opts) {
super(opts);
this.filename = opts.filename;
this.setup();
}
initialize() {
try {
fs.writeFileSync(this.filename, [], 'utf8');
} catch (error) {
console.log(error);
}
}
setup() {
// This checks if the file exists
if (fs.existsSync(this.filename)) {
// The content of the file is checked to know if it is necessary to adapt the array
try {
const data = fs.readFileSync(this.filename, 'utf8');
// If the content of the file is not an array, it is set
const content = JSON.parse(data);
if (!Array.isArray(content)) {
this.initialize();
}
} catch (error) {
this.initialize();
console.log(error);
}
}
// Otherwise create the file with the desired format
else {
this.initialize();
}
}
readLog() {
let data = null;
try {
data = fs.readFileSync(this.filename, 'utf8');
} catch (error) {
console.log(error);
}
return data;
}
writeLog(info) {
const data = this.readLog();
let arr = [];
if (data) {
arr = JSON.parse(data);
}
//add data
arr.push(info);
//convert it back to json
const json = JSON.stringify(arr);
try {
// Writing the array again
fs.writeFileSync(this.filename, json, 'utf8');
} catch (error) {
console.log(error)
}
}
log(info, callback) {
setImmediate(() => {
this.emit('logged', info);
});
// Perform the writing
this.writeLog(info);
callback();
}
};
然后按照您放置的代码进行自定义传输器的改编:
'use strict';
const winston = require('winston');
const CustomTransport = require('./CustomTransport');
const moment = require('moment');
const logger = winston.createLogger({
format: winston.format.json(),
transports: [
new CustomTransport({
filename: moment(moment.now()).format('DD-MM-YYYY') + '-API.json',
handleExceptions: true
})
],
});
logger.log({
'level': 'info',
'timestamp': moment.now(),
'account_id': res.account_id || null,
'action': JSON.stringify(payload),
'request_id': res.request_id,
'status': success.status.code,
'route': res.method + ' ' + res.route,
'bytes': res.socket.bytesRead || null,
'elapsed': res.elapsed || null,
});
我尝试了使用虚拟数据的服务,结果是这样的:
[
{
"level": "info",
"timestamp": 1544723041103,
"account_id": 1,
"action": 6,
"request_id": 2,
"status": 3,
"route": 4,
"bytes": 5,
"elapsed": 5
},
{
"level": "info",
"timestamp": 1544724862768,
"account_id": 1,
"action": 6,
"request_id": 2,
"status": 3,
"route": 4,
"bytes": 5,
"elapsed": 5
}
]