matt123miller
matt123miller

Reputation: 191

Winston logging to a file that begins with custom multi line text

Our Winston logging is already set up and working great using winston-daily-rotate-file to create daily log files. What I now need to do is create those log files from a specific file template (or any other method) with a few header rows at the start of the file. We want to change our application to use a more stuctured logging for use with a separate internal app so our support team can easier traverse large log files.

Normally the log files append each log into the file, starting with a blank file. To specify, I want that file to begin with a few lines of text before any logging is added.

Is this possible? I can't find any reference to functionality like this in either Winston or winston-daily-rotate-file. Perhaps I'm meant to create hook into the file stream using the options object parameter?

Upvotes: 3

Views: 1103

Answers (1)

evilmandarine
evilmandarine

Reputation: 4553

Handling the rotate event is the way to go.

In the following code, I am rotating every 2 files every minute for demo purposes. I am appending text on top of each new file, and also every rotation. As rotation happens later, you see ROTATE above NEW, which is expected. For your scenario I don't think you need the new event.

Demo

var winston = require('winston');
require('winston-daily-rotate-file');
const fs = require('fs');

var transport = new winston.transports.DailyRotateFile({
    frequency: '1m',
    filename: 'log-%DATE%',
    datePattern: 'YYYY-MM-DD-HH-mm',
    zippedArchive: false,
    maxSize: '1k',
    maxFiles: '2',
    extension: 'log'
});

transport.on('rotate', function (oldFilename, newFilename) {
    console.log("rotate");

    var data = fs.readFileSync(newFilename); //read existing contents into data
    var fd = fs.openSync(newFilename, 'w+');
    var buffer = Buffer.from('ROTATE text inserted on top \n');
    fs.writeSync(fd, buffer, 0, buffer.length, 0); //write new data
    fs.writeSync(fd, data, 0, data.length, buffer.length); //append old data
    fs.close(fd);
});

transport.on('new', function (newFilename) {
    console.log("new");

    var data = fs.readFileSync(newFilename); //read existing contents into data
    var fd = fs.openSync(newFilename, 'w+');
    var buffer = Buffer.from('NEW text inserted on top \n');
    fs.writeSync(fd, buffer, 0, buffer.length, 0); //write new data
    fs.writeSync(fd, data, 0, data.length, buffer.length); //append old data
    fs.close(fd);
});

var logger = winston.createLogger({
    transports: [
        transport
    ]
});

async function demo() {
    for (i = 1; i < 20; i++) {
        logger.info('Hello World ' + i);
        console.log(i);
        await new Promise(r => setTimeout(r, 10000));
    }
}

demo();

Console output

1
2
3
new
rotate
4
5
6
7
8
9
new
rotate
10
11
12
13
14
15
new
rotate
16
17
18
19

Files created

log-2022-06-13-14-36log
log-2022-06-13-14-37log

Files content

1:

ROTATE text inserted on top 
NEW text inserted on top 
{"level":"info","message":"Hello World 10"}
{"level":"info","message":"Hello World 11"}
{"level":"info","message":"Hello World 12"}
{"level":"info","message":"Hello World 13"}
{"level":"info","message":"Hello World 14"}
{"level":"info","message":"Hello World 15"}

2:

ROTATE text inserted on top 
NEW text inserted on top 
{"level":"info","message":"Hello World 16"}
{"level":"info","message":"Hello World 17"}
{"level":"info","message":"Hello World 18"}
{"level":"info","message":"Hello World 19"}

Upvotes: 2

Related Questions