Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Node.js中使用Winston输出JSON对象内的日志_Node.js_Json_Logging_Winston - Fatal编程技术网

在Node.js中使用Winston输出JSON对象内的日志

在Node.js中使用Winston输出JSON对象内的日志,node.js,json,logging,winston,Node.js,Json,Logging,Winston,因此,我使用登录到一个文件。我已经设置了记录器,以输出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: [

因此,我使用登录到一个文件。我已经设置了记录器,以输出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;
{
   "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
  }
]
记录这样的事件时:

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,
});
我在日志文件中获得以下输出

输出:

'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;
{
   "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
  }
]
我想这样把日志记录到我的文件中。因此,可以在以后搜索数据

所需输出:

'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;
{
   "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
    }
]

非常感谢你这么做。但有一个问题:文件或目录丢失。在打开文件和目录之前,我应该告诉代码在哪里创建文件和目录?
fs.writeFile(文件,数据[,选项],回调)不为文件创建父文件夹,如果不存在则要创建文件夹,则必须在CustomTransport类中的initialize方法中添加此操作。如何停止文件重写自身?目前,它将清除该文件,然后写入新日志,因此将删除以前的日志。@MwikalaKangwa感谢您的评论,将我的回复更新为同步版本,现在一切正常。