Làm cách nào để thêm dấu thời gian vào nhật ký bằng thư viện Node.js Winston?


93

Tôi muốn thêm dấu thời gian vào nhật ký. cách tốt nhất để đạt được điều này là gì?


Điều này vẫn còn quá rộng vì bạn KHÔNG THỂ làm điều đó từ máy khách.
Joshua

Câu trả lời:


112

Tôi đã tự mình giải quyết vấn đề tương tự. Có hai cách tôi có thể làm điều này.

Khi bạn bao gồm Winston, nó thường được mặc định thêm phương tiện giao thông Console. Để dấu thời gian hoạt động trong trường hợp mặc định này, tôi cần:

  1. Xóa giao diện điều khiển và thêm lại bằng tùy chọn dấu thời gian.
  2. Tạo đối tượng Trình ghi nhật ký của riêng bạn với tùy chọn dấu thời gian được đặt thành true.

Đầu tiên:

var winston = require('winston');
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {'timestamp':true});

Tùy chọn thứ hai và rõ ràng hơn:

var winston = require('winston');
var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({'timestamp':true})
    ]
});

Bạn có thể tìm thấy một số tùy chọn khác cho vận chuyển Console tại đây :

  • level: Mức độ thông báo mà quá trình truyền tải này sẽ ghi lại (mặc định là 'gỡ lỗi').
  • im lặng: Cờ Boolean cho biết có chặn đầu ra hay không (mặc định là false).
  • chỉnh màu: Cờ Boolean cho biết chúng ta có nên chỉnh màu cho đầu ra hay không (mặc định là false).
  • dấu thời gian: Cờ Boolean cho biết liệu chúng ta có nên thêm đầu ra với dấu thời gian (mặc định là sai). Nếu hàm được chỉ định, giá trị trả về của nó sẽ được sử dụng thay vì dấu thời gian.

1
Tuyệt vời và đơn giản cùng một lúc. Cảm ơn bạn!
kolrie

7
Điều đó thật tuyệt. Tôi thường bọc nó trong một tệp chuyên dụng để tôi có thể dễ dàng lấy trình ghi đã định cấu hình của mình từ bất kỳ tệp nào, tức là tôi đặt đoạn mã trên (tùy chọn 2) vào tệp logger.js mới, theo sau là module.exports = logger; sau đó từ bất kỳ tệp nào tôi thực hiện var logger = request ('./ logger.js') và sau đó có thể thực hiện logger.info ('hello') từ bất kỳ tệp nào và nhận được cùng một cấu hình của Winston.
JHH

Lỗi Loại: (giá trị trung gian) không phải là một chức năng
Urasquirrel

79

Câu trả lời trên không làm việc cho tôi. Trong trường hợp bạn đang cố gắng thêm dấu thời gian vào nhật ký của mình bằng phiên bản mới nhất của Winston - 3.0.0-rc1, điều này hoạt động giống như sự quyến rũ:

    const {transports, createLogger, format} = require('winston');

    const logger = createLogger({
        format: format.combine(
            format.timestamp(),
            format.json()
        ),
        transports: [
            new transports.Console(),
            new transports.File({filename: 'logs/error/error.log', level: 'error'}),
            new transports.File({filename: 'logs/activity/activity.log', level:'info'})
        ]
    });

Tôi đã sử dụng 'format.combine ()'. Vì tôi cần dấu thời gian trên tất cả các phương tiện vận chuyển của mình, nên tôi đã thêm tùy chọn định dạng trong createLogger, thay vì bên trong mỗi phương tiện vận chuyển. Đầu ra của tôi trên bảng điều khiển và trên tệp (activity.log) như sau:

{"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}
{"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}

Chúng tôi có thể thêm định dạng cho dấu thời gian này trong 'format.combine ()' như thường lệ bằng cách sử dụng:

format.timestamp({format:'MM-YY-DD'})

14

Chúng tôi cũng có thể làm như thế này

var winston = require('winston');
    const { createLogger, format, transports } = require('winston')
    var config = require('../configurations/envconfig.js');

    var loggerLevel = process.env.LOGGERLEVEL ||  config.get('LOGGERLEVEL');

    var logger = winston.createLogger({ format: format.combine(
            format.timestamp({
                format: 'YYYY-MM-DD HH:mm:ss'
            }),
            format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`+(info.splat!==undefined?`${info.splat}`:" "))
        ), 
        transports: [
            new (winston.transports.Console)({ level: loggerLevel }),
           ]
    });
    module.exports = logger;

Điều này cũng làm việc cho logger.info('Message', someObject)? Tôi thiết lập một định dạng tùy chỉnh bằng cách sử dụng kết hợp và tôi dường như không thể nhận được someObjectbao gồm trong thông báo nhật ký.
SomethingOn vào

1
Tôi đã có thể được someObjectđưa vào bằng cách sử dụng câu lệnh printf sau ${info.timestamp} [${info.level.toUpperCase()}]: ${info.message} ${JSON.stringify(info)}. Nó bao gồm cấp độ, dấu thời gian và tin nhắn mà tôi đoán tôi có thể xóa.
SomethingOn vào

9

Bạn có thể sử dụng tiện ích tích hợp sẵnmãi mãi để ghi nhật ký với bản đồ thời gian cho máy chủ nodejs của mình. Khi bạn khởi động máy chủ, hãy thêm đầu ra nhật ký như một phần của tham số:

forever start -ao log/out.log server.js

Và sau đó bạn có thể viết sử dụng trong server.js của mình

server.js

var util = require('util');
util.log("something with timestamp");

Đầu ra sẽ giống như thế này đối với tệp out.log:

out.log

15 Mar 15:09:28 - something with timestamp

1
Thật không may, util.error()bỏ qua dấu thời gian đầu ra.
Saran

4

Mặc dù tôi không biết về wonton, nhưng đây là một gợi ý. Tôi sử dụng log4js để ghi nhật ký và nhật ký của tôi theo mặc định trông như thế này

[2012-04-23 16:36:02.965] [INFO] Development - Node Application is running on port 8090
[2012-04-23 16:36:02.966] [FATAL] Development - Connection Terminated to  '127.0.0.1' '6379'

Phát triển là môi trường của quy trình nút của tôi & [INFO | FATAL] là cấp nhật ký

Có thể duy trì các cấu hình khác nhau để ghi nhật ký trong log4js. Tôi có hồ sơ Phát triển & Sản xuất. Ngoài ra còn có các loại trình ghi nhật ký như ứng dụng tệp cuộn, trình ứng dụng bảng điều khiển, v.v. Là một phần bổ trợ, tệp nhật ký của bạn sẽ có nhiều màu sắc dựa trên cấp độ nhật ký [Trace, Info, Debug, Error, Fatal];)

log4js sẽ ghi đè bảng điều khiển của bạn.log Đây là một tham số có thể định cấu hình bây giờ ở 0.5+


FYI: Các phiên bản mới hơn của log4js-node (0.5+) không tự động ghi đè console.log.
Jeff Hiltz

@jeffhiltz Ya bạn là đúng :) Bây giờ nó là một tham số cấu hình
Tamil

2

Đôi khi định dạng dấu thời gian mặc định có thể không thuận tiện cho bạn. Bạn có thể ghi đè nó bằng cách triển khai của mình.

Thay vì

var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
  new (winston.transports.Console)({'timestamp':true})
]
});

bạn có thể viết

var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
  new (winston.transports.Console)({
     'timestamp': function() {
        return <write your custom formatted date here>;
     }
  })
]
});

Xem https://github.com/winstonjs/winston#custom-log-format để biết chi tiết



0

Một giải pháp khác là gói trình ghi nhật ký vào một tệp xuất một số hàm như logger.info (), logger.error (), v.v. sau đó bạn chỉ cần chuyển một khóa bổ sung được gửi trên mọi nhật ký thư.

loggerService.js

const logger = winston.createLogger({ ... })

function handleLog(message, level) {
  const logData = {
    timestamp: Date.now(),
    message,
  }

  return logger[level](logData)
}

function info(message) {
  handleLog(message, 'info')
}

function error(message) {
  handleLog(message, 'error')
}

function warn(message) {
  handleLog(message, 'warn')
}

module.exports = {
  info,
  error,
  warn
}

any-file.js

const logger = require('./services/loggerService')

logger.info('Hello World!')

your-log.log

{"timestamp":"2019-08-21 06:42:27","message":"Hello World!","level":"info"}

0

Tôi đã lấy câu trả lời của Biswadev và tạo một đối tượng JSON được xâu chuỗi. Bằng cách này, nếu tôi cần xử lý nhật ký sau này, nó sẽ ở định dạng có cấu trúc tốt.

const winston = require('winston');
const { createLogger, format, transports } = require('winston');

const dotenv = require('dotenv');
dotenv.config();

var logger = createLogger({
    level: 'info',
    format: format.combine(
        format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss',
        }),
        format.printf((info) =>
            JSON.stringify({
                t: info.timestamp,
                l: info.level,
                m: info.message,
                s: info.splat !== undefined ? `${info.splat}` : '',
            }) + ','
        )
    ),
});

if (process.env.NODE_ENV !== 'PRODUCTION') {
    logger.add(new transports.Console({ format: winston.format.cli() }));

    // Turn these on to create logs as if it were production
    // logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
    // logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
    // logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
} else {
    logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
    logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
    logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
}

module.exports = {
    logger,
};

Sử dụng:

app.listen(port, () => logger.info(`app is running on port ${port}`));

Đầu ra:

tệp info.log:

{"t":"2020-08-06 08:02:05","l":"info","m":"app is running on port 3001","s":""},

Bảng điều khiển:

info:    app is running on port 3001
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.