Skip to content

Commit ba2fcaf

Browse files
ledbitDABH
authored andcommitted
fix file rolling when tailing is set to true (#1420)
* fix issue #1194 - where rotation of files isn't done when tailable is set to true * more fixes to tail rolling + fix & enable unit tests * fix unit tests interference from 01-file-maxsize - not sure why a new file gets created on an unrelated transport when adding a new Transport * Update 01-file-maxsize.test.js * Update file.js
1 parent 908c300 commit ba2fcaf

File tree

4 files changed

+122
-110
lines changed

4 files changed

+122
-110
lines changed

lib/winston/transports/file.js

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -594,28 +594,26 @@ module.exports = class File extends TransportStream {
594594

595595
// const isZipped = this.zippedArchive ? '.gz' : '';
596596
const isZipped = this.zippedArchive ? '.gz' : '';
597-
for (let i = this.maxFiles - 1; i > 0; i--) {
598-
tasks.push(() => {
599-
return cb => {
600-
let fileName = `${basename}${(i - 1)}${ext}${isZipped}`;
601-
const tmppath = path.join(this.dirname, fileName);
602-
603-
fs.exists(tmppath, exists => {
604-
if (!exists) {
605-
return cb(null);
606-
}
607-
608-
fileName = `${basename}${i}${ext}${isZipped}`;
609-
fs.rename(tmppath, path.join(this.dirname, fileName), cb);
610-
});
611-
};
612-
});
597+
for (let x = this.maxFiles - 1; x > 1; x--) {
598+
tasks.push(function (i, cb) {
599+
let fileName = `${basename}${(i - 1)}${ext}${isZipped}`;
600+
const tmppath = path.join(this.dirname, fileName);
601+
602+
fs.exists(tmppath, exists => {
603+
if (!exists) {
604+
return cb(null);
605+
}
606+
607+
fileName = `${basename}${i}${ext}${isZipped}`;
608+
fs.rename(tmppath, path.join(this.dirname, fileName), cb);
609+
});
610+
}.bind(this, x));
613611
}
614612

615613
asyncSeries(tasks, () => {
616614
fs.rename(
617615
path.join(this.dirname, `${basename}${ext}`),
618-
path.join(this.dirname, `${basename}1${ext}`),
616+
path.join(this.dirname, `${basename}1${ext}${isZipped}`),
619617
callback
620618
);
621619
});

test/transports/01-file-maxsize.test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ function removeFixtures(done) {
2323
describe('File (maxsize)', function () {
2424
this.timeout(10000);
2525

26+
let testDone = false;
2627
before(removeFixtures);
27-
after(removeFixtures);
28+
after(done => {
29+
testDone = true;
30+
removeFixtures(done);
31+
});
2832

2933
it('should create multiple files correctly when passed more than the maxsize', function (done) {
3034
const fillWith = ['a', 'b', 'c', 'd', 'e'];
@@ -101,6 +105,8 @@ describe('File (maxsize)', function () {
101105
}
102106

103107
maxsizeTransport.on('open', function (file) {
108+
if (testDone) return; // ignore future notifications
109+
104110
const match = file.match(/(\d+)\.log$/);
105111
const count = match ? match[1] : 0;
106112

test/transports/file-tailrolling-test.js

Lines changed: 0 additions & 92 deletions
This file was deleted.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
var assert = require('assert'),
2+
rimraf = require('rimraf'),
3+
fs = require('fs'),
4+
path = require('path'),
5+
winston = require('../../lib/winston'),
6+
helpers = require('../helpers');
7+
const asyncSeries = require('async/series');
8+
9+
10+
11+
const { MESSAGE, LEVEL } = require('triple-beam');
12+
13+
14+
15+
//
16+
// Remove all log fixtures
17+
//
18+
function removeFixtures(done) {
19+
rimraf(path.join(__dirname, '..', 'fixtures', 'logs', 'testtailrollingfiles*'), done);
20+
}
21+
22+
23+
24+
let tailrollTransport = null;
25+
26+
describe('winston/transports/file/tailrolling', function(){
27+
describe("An instance of the File Transport", function(){
28+
before(removeFixtures);
29+
after(removeFixtures);
30+
31+
it('init logger AFTER cleaning up old files', function(){
32+
tailrollTransport = new winston.transports.File({
33+
timestamp: false,
34+
json: false,
35+
filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testtailrollingfiles.log'),
36+
maxsize: 4096,
37+
maxFiles: 3,
38+
tailable: true
39+
})
40+
.on('open', console.log)
41+
});
42+
43+
it("and when passed more files than the maxFiles", function(done){
44+
let created = 0;
45+
let loggedTotal = 0;
46+
47+
function data(ch, kb) {
48+
return String.fromCharCode(65 + ch).repeat(kb*1024 - 1);
49+
};
50+
51+
function logKbytes(kbytes, txt) {
52+
const toLog = {};
53+
toLog[MESSAGE] = data(txt, kbytes)
54+
tailrollTransport.log(toLog);
55+
}
56+
57+
tailrollTransport.on('logged', function (info) {
58+
loggedTotal += info[MESSAGE].length + 1
59+
if (loggedTotal >= 14*1024) { // just over 3 x 4kb files
60+
return done();
61+
}
62+
63+
if(loggedTotal % 4096 === 0) {
64+
created ++;
65+
}
66+
setTimeout(() => logKbytes(1, created), 100);
67+
});
68+
69+
logKbytes(1, created);
70+
});
71+
72+
it("should be 3 log files, base to maxFiles - 1", function () {
73+
var file, fullpath;
74+
for (var num = 0; num < 4; num++) {
75+
file = !num ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + num + '.log';
76+
fullpath = path.join(__dirname, '..', 'fixtures', 'logs', file);
77+
78+
if (num == 3) {
79+
return assert.ok(!fs.existsSync(fullpath));
80+
}
81+
82+
assert.ok(fs.existsSync(fullpath));
83+
}
84+
85+
return false;
86+
});
87+
88+
it("should have files in correct order", function () {
89+
var file, fullpath, content;
90+
['D', 'C', 'B'].forEach(function (letter, i) {
91+
file = !i ? 'testtailrollingfiles.log' : 'testtailrollingfiles' + i + '.log';
92+
content = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'logs', file), 'ascii');
93+
content = content.replace(/\s+/g, '');
94+
95+
assert(content.match(new RegExp(letter, 'g'))[0].length, content.length);
96+
});
97+
});
98+
})
99+
})
100+

0 commit comments

Comments
 (0)