GardenCloud & systems

Rotating Winston logs with a fixed UTC offset

An earlier logging configuration combining hourly filenames, retention limits, and formatted timestamps.

A log’s timestamp format and its file-rotation policy solve different problems. This earlier Winston setup formatted timestamps with a +0700 offset and sent the same record to the console and rotating files.

The original dependencies

npm i moment
npm i winston
npm i winston-daily-rotate-file

These unpinned commands record the old setup rather than a reproducible dependency lock.

The configuration

import moment from "moment";
const winston = require('winston');
require('winston-daily-rotate-file');


const environment = process.env.NODE_ENV || 'dev';
// @nhancv 2019-09-10: Format log with specific timezone
const logFormat = winston.format.combine(
  winston.format.colorize(),
  winston.format.timestamp(),
  winston.format.align(),
  winston.format.printf(
    info => moment(info.timestamp).utc().utcOffset("+0700").format() + '-' + environment + '-message:' + info.message
  ),
);
// @nhancv 2019-09-10: Config for file transport
const fileTransport = new winston.transports.DailyRotateFile({
  filename: './logs/%DATE%.log',
  datePattern: 'YYYY-MM-DD-HH',
  handleExceptions: true,
  zippedArchive: false,
  maxSize: '20m',
  maxFiles: '15d'
});
// @nhancv 2019-09-10: Config for console transport
const consoleTransport = new winston.transports.Console({
  handleExceptions: true,
});


// @nhancv 2019-09-10: Create new logger id
winston.loggers.add('Logger', {
  format: logFormat,
  transports: [
    fileTransport,
    consoleTransport,
  ]
});


// @nhancv 2019-09-10: Get logger from logger ID
const logger = winston.loggers.get('Logger');


// @nhancv 2019-09-06: Catch all unhandled Promise rejections
process.on('unhandledRejection', function (err) {
  logger.error(err);
}); 

The date pattern names files by hour, while maxSize and maxFiles limit file size and retention. The shared formatter includes colorization, which also affects file output.

A numeric UTC offset is not a named timezone with historical or daylight-saving rules. The source also mixes import and require, so its module environment matters.

The unhandled-rejection handler records an error; it does not prove that the process is healthy or that failed work recovered. This historical configuration has not been run for this revision.

← Back to the garden