Як я можу додати позначку часу до журналів за допомогою бібліотеки Node.js Winston?


93

Я хочу додати позначку часу до журналів. Який найкращий спосіб цього досягти?


Це залишається занадто широким, оскільки ви НЕ МОЖЕТЕ зробити це з клієнтської машини.
Джошуа

Відповіді:


112

Я сам мав справу з тим самим питанням. Є два способи, якими я зміг це зробити.

Коли ви включаєте Winston, зазвичай за замовчуванням додається транспорт консолі. Щоб отримати мітки часу для роботи у цьому випадку за замовчуванням, мені потрібно було:

  1. Видаліть транспорт консолі та додайте знову за допомогою опції позначки часу.
  2. Створіть власний об'єкт реєстратора, встановивши для параметра часу позначку true.

Перший:

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

Другий і чистий варіант:

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

Деякі інші варіанти консольного транспорту можна знайти тут :

  • рівень: Рівень повідомлень, які цей транспорт повинен реєструвати (за замовчуванням 'налагодження').
  • беззвучний: логічний прапор, який вказує, чи слід придушити вихід (за замовчуванням false).
  • colorize: логічний прапорець, який вказує, чи слід розфарбовувати вихід (типово false)
  • timestamp: логічний прапорець, який вказує, чи слід додавати результат до позначок часу (за замовчуванням false). Якщо функція вказана, замість позначок часу використовуватиметься її повернене значення.

1
Дивовижно і просто водночас. Дякую!
kolrie

7
Це чудово. Зазвичай я обертаю це у виділений файл, щоб я міг легко отримати налаштований реєстратор з будь-якого файлу, тобто я помістив наведений вище код (варіант 2) у новий файл logger.js, за яким слід module.exports = logger; тоді з будь-якого файлу я роблю var logger = require ('./ logger.js'), а потім можу зробити logger.info ('привіт') з будь-якого файлу і отримати ту саму конфігурацію Winston.
JHH

TypeError: (проміжне значення) не є функцією
Urasquirrel

81

Наведені вище відповіді для мене не працювали. Якщо ви намагаєтеся додати позначку часу до своїх журналів, використовуючи останню версію Winston - 3.0.0-rc1, це спрацювало як чарівність:

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

Я використовував 'format.combine ()'. Оскільки мені потрібна була мітка часу на всіх моїх транспортах, я додав опцію форматування всередині createLogger, а не всередині кожного транспорту. Мої результати на консолі та у файлі (Activity.log) такі:

{"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"}

Ми можемо додати форматування до цієї позначки часу у форматі 'format.combine ()', як зазвичай, використовуючи:

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

14

Ми можемо робити і це

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;

Це також працює logger.info('Message', someObject)? Я встановлюю власний формат за допомогою комбінації, і, здається, не можу отримати someObjectвключене в повідомлення журналу.
Something,

1
Мені вдалося долучитися someObject, використовуючи наступну заяву printf ${info.timestamp} [${info.level.toUpperCase()}]: ${info.message} ${JSON.stringify(info)}. Він включає рівень, позначку часу та повідомлення, які, напевно, я міг би видалити.
Something,

9

Ви можете використовувати вбудований Util і назавжди досягти протоколювання з timestap для nodejs сервера. Під час запуску сервера додайте вихідні дані журналу як частину параметра:

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

А потім ви можете написати util у своєму server.js

server.js

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

Результат буде виглядати приблизно так у файлі out.log:

out.log

15 Mar 15:09:28 - something with timestamp

1
На жаль, util.error()пропускає позначення часу на виході.
Саран,

4

Хоча я не знаю про Вінстона, це пропозиція. Я використовую log4js для ведення журналу, і мої журнали за замовчуванням виглядають так

[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'

Розробка - це середовище мого вузлового процесу, а [INFO | FATAL] - рівень журналу

Ведення різних профілів для ведення журналу можливо в log4js. У мене є профілі розробки та виробництва. Також існують типи реєстраторів, такі як додаток для прокручування файлів, додаток консолі тощо. Як аддон, ваші файли журналів будуть кольоровими на основі рівня журналу [Трасування, Інформація, Налагодження, Помилка, Фатальний];)

log4js замінить вашу консоль. log Це налаштовуваний параметр, який зараз становить 0,5+


FYI: новіші версії log4js-node (0.5+) не перевизначають автоматично console.log.
Jeff Hiltz

@jeffhiltz Я маєш рацію :) Тепер це налаштовуваний параметр
Таміль

2

Іноді формат мітки часу за замовчуванням може бути для вас не зручним. Ви можете замінити це своїм втіленням.

Замість

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

ти можеш писати

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

Див https://github.com/winstonjs/winston#custom-log-format для деталей


2

ми могли б використовувати штамп console, щоб додати позначку часу та рівень журналу до існуючої консолі: require('console-stamp')(console, '[yyyy-mm-dd HH:MM:ss.l]')

Див https://github.com/starak/node-console-stamp для деталей


0

Іншим рішенням є загортання реєстратора у файл, який експортує деякі функції, такі як logger.info (), logger.error () тощо. Тоді ви просто передаєте додатковий ключ для надсилання у кожному журналі повідомлень.

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
}

whatever-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

Я взяв відповідь Бісвадева і створив розширений об'єкт JSON. Таким чином, якщо мені потрібно буде обробити журнали пізніше, це буде в добре структурованому форматі.

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,
};

Використання:

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

Вихід:

файл info.log:

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

Консоль:

info:    app is running on port 3001
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.