Skip to content

Commit 0c265b5

Browse files
pataiadammattberther
authored andcommitted
zippedArchive working with DailyRotateFile (#63)
1 parent 244ddc7 commit 0c265b5

File tree

2 files changed

+183
-2
lines changed

2 files changed

+183
-2
lines changed

index.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var Transport = require('winston').Transport;
88
var Stream = require('stream').Stream;
99
var os = require('os');
1010
var winston = require('winston');
11+
var zlib = require('zlib');
1112

1213
var weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
1314

@@ -78,6 +79,7 @@ var DailyRotateFile = module.exports = function (options) {
7879
this.maxRetries = options.maxRetries || 2;
7980
this.prepend = options.prepend || false;
8081
this.localTime = options.localTime || false;
82+
this.zippedArchive = options.zippedArchive || false;
8183

8284
if (this.json) {
8385
this.stringify = options.stringify;
@@ -93,6 +95,7 @@ var DailyRotateFile = module.exports = function (options) {
9395
this._buffer = [];
9496
this._draining = false;
9597
this._failures = 0;
98+
this._archive = false;
9699

97100
// Internal variable which will hold a record of all files
98101
// belonging to this transport which are currently in the
@@ -425,7 +428,7 @@ DailyRotateFile.prototype.open = function (callback) {
425428
//
426429
return callback(true);
427430
} else if (!this._stream || (this.maxsize && this._size >= this.maxsize) ||
428-
this._filenameHasExpired()) {
431+
this._filenameHasExpired()) {
429432
//
430433
// If we dont have a stream or have exceeded our size, then create
431434
// the next stream and respond with a value indicating that
@@ -434,7 +437,7 @@ DailyRotateFile.prototype.open = function (callback) {
434437
callback(true);
435438
return this._createStream();
436439
}
437-
440+
this._archive = this.zippedArchive ? this._stream.path : false;
438441
//
439442
// Otherwise we have a valid (and ready) stream.
440443
//
@@ -560,6 +563,23 @@ DailyRotateFile.prototype._createStream = function () {
560563
// than one second.
561564
//
562565
self.flush();
566+
compressFile();
567+
}
568+
569+
function compressFile() {
570+
var logfile = self._archive;
571+
self._archive = false;
572+
if (logfile && fs.existsSync(String(logfile))) {
573+
var gzip = zlib.createGzip();
574+
575+
var inp = fs.createReadStream(String(logfile));
576+
var out = fs.createWriteStream(logfile + '.gz');
577+
578+
inp.pipe(gzip).pipe(out);
579+
580+
self._created += 1;
581+
fs.unlink(String(logfile));
582+
}
563583
}
564584

565585
fs.stat(fullname, function (err, stats) {

test/simple.tests.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,5 +492,166 @@ describe('winston/transports/daily-rotate-file', function () {
492492
});
493493
});
494494
});
495+
496+
describe('when zippedArchive is true and passed an valid filename with different date patterns for log rotation', function () {
497+
// patterns having one start timestamp for which log file will be creted,
498+
// then one mid timestamp for which log file should not be rotated,
499+
// and finally one end timestamp for which log file should be rotated and
500+
// new logfile should be created.
501+
var patterns = {
502+
'full year pattern .yyyy': {
503+
pattern: '.yyyy',
504+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
505+
mid: 1874993560000, // GMT: Fri, 01 Jun 2029 07:32:40 GMT
506+
end: 1893483160000, // GMT: Tue, 01 Jan 2030 07:32:40 GMT
507+
oldfile: 'test-rotation.log.2029',
508+
newfile: 'test-rotation.log.2030'
509+
},
510+
'small year pattern .yy': {
511+
pattern: '.yy',
512+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
513+
mid: 1874993560000, // GMT: Fri, 01 Jun 2029 07:32:40 GMT
514+
end: 1893483160000, // GMT: Tue, 01 Jan 2030 07:32:40 GMT
515+
oldfile: 'test-rotation.log.29',
516+
newfile: 'test-rotation.log.30'
517+
},
518+
'month pattern .M': {
519+
pattern: '.M',
520+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
521+
mid: 1863156760000, // GMT: Mon, 15 Jan 2029 07:32:40 GMT
522+
end: 1864625560000, // GMT: Thu, 01 Feb 2029 07:32:40 GMT
523+
oldfile: 'test-rotation.log.1',
524+
newfile: 'test-rotation.log.2'
525+
},
526+
'zero padded month pattern .MM': {
527+
pattern: '.MM',
528+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
529+
mid: 1863156760000, // GMT: Mon, 15 Jan 2029 07:32:40 GMT
530+
end: 1864625560000, // GMT: Thu, 01 Feb 2029 07:32:40 GMT
531+
oldfile: 'test-rotation.log.01',
532+
newfile: 'test-rotation.log.02'
533+
},
534+
'daypattern .d': {
535+
pattern: '.d',
536+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
537+
mid: 1861986760000, // GMT: Mon, 01 Jan 2029 18:32:40 GMT
538+
end: 1863156760000, // GMT: Mon, 15 Jan 2029 07:32:40 GMT
539+
oldfile: 'test-rotation.log.1',
540+
newfile: 'test-rotation.log.15'
541+
},
542+
'zero padded day pattern .dd': {
543+
pattern: '.dd',
544+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
545+
mid: 1861986760000, // GMT: Mon, 01 Jan 2029 18:32:40 GMT
546+
end: 1863156760000, // GMT: Mon, 15 Jan 2029 07:32:40 GMT
547+
oldfile: 'test-rotation.log.01',
548+
newfile: 'test-rotation.log.15'
549+
},
550+
'hour pattern .H': {
551+
pattern: '.H',
552+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
553+
mid: 1861947760000, // GMT: Mon, 01 Jan 2029 07:42:40 GMT
554+
end: 1861950760000, // GMT: Mon, 01 Jan 2029 08:32:40 GMT
555+
oldfile: 'test-rotation.log.7',
556+
newfile: 'test-rotation.log.8'
557+
},
558+
'zero padded hour pattern .HH': {
559+
pattern: '.HH',
560+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
561+
mid: 1861947760000, // GMT: Mon, 01 Jan 2029 07:42:40 GMT
562+
end: 1861950760000, // GMT: Mon, 01 Jan 2029 08:32:40 GMT
563+
oldfile: 'test-rotation.log.07',
564+
newfile: 'test-rotation.log.08'
565+
},
566+
'minute pattern .m': {
567+
pattern: '.m',
568+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:50 GMT
569+
mid: 1861947170000, // GMT: Mon, 01 Jan 2029 07:32:50 GMT
570+
end: 1861947760000, // GMT: Mon, 01 Jan 2029 07:42:40 GMT
571+
oldfile: 'test-rotation.log.32',
572+
newfile: 'test-rotation.log.42'
573+
},
574+
'zero padded minute pattern .mm': {
575+
pattern: '.mm',
576+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:50 GMT
577+
mid: 1861947170000, // GMT: Mon, 01 Jan 2029 07:32:50 GMT
578+
end: 1861947760000, // GMT: Mon, 01 Jan 2029 07:42:40 GMT
579+
oldfile: 'test-rotation.log.32',
580+
newfile: 'test-rotation.log.42'
581+
},
582+
'daily rotation pattern .yyyy-MM-dd': {
583+
pattern: '.yyyy-MM-dd',
584+
start: 1861947160000, // GMT: Mon, 01 Jan 2029 07:32:40 GMT
585+
mid: 1861965828000, // GMT: Mon, 01 Jan 2029 12:43:48 GMT
586+
end: 1863156760000, // GMT: Mon, 15 Jan 2029 07:32:40 GMT
587+
oldfile: 'test-rotation.log.2029-01-01',
588+
newfile: 'test-rotation.log.2029-01-15'
589+
}
590+
};
591+
Object.keys(patterns).forEach(function (pattern) {
592+
describe('when passed the pattern ' + pattern, function () {
593+
var transport;
594+
var rotationLogPath = path.join(fixturesDir, 'rotations');
595+
596+
beforeEach(function (done) {
597+
this.time = new Date(patterns[pattern].start);
598+
tk.travel(this.time);
599+
rimraf.sync(rotationLogPath);
600+
mkdirp.sync(rotationLogPath);
601+
transport = new DailyRotateFile({
602+
filename: path.join(rotationLogPath, 'test-rotation.log'),
603+
datePattern: patterns[pattern].pattern,
604+
zippedArchive: true
605+
});
606+
607+
done();
608+
});
609+
610+
afterEach(function () {
611+
tk.reset();
612+
});
613+
614+
it('should create log with proper timestamp', function (done) {
615+
var self = this;
616+
617+
transport.log('error', 'test message', {}, function (err) {
618+
if (err) {
619+
done(err);
620+
}
621+
622+
var filesCreated = fs.readdirSync(rotationLogPath);
623+
expect(filesCreated.length).to.eql(1);
624+
expect(filesCreated).to.include(patterns[pattern].oldfile);
625+
self.time = new Date(patterns[pattern].mid);
626+
tk.travel(self.time);
627+
transport.log('error', '2nd test message', {}, function (err) {
628+
if (err) {
629+
done(err);
630+
}
631+
632+
filesCreated = fs.readdirSync(rotationLogPath);
633+
expect(filesCreated.length).to.eql(1);
634+
expect(filesCreated).to.include(patterns[pattern].oldfile);
635+
self.time = new Date(patterns[pattern].end);
636+
tk.travel(self.time);
637+
transport.log('error', '3rd test message', {}, function (err) {
638+
if (err) {
639+
done(err);
640+
}
641+
642+
filesCreated = fs.readdirSync(rotationLogPath);
643+
expect(filesCreated.length).to.eql(2);
644+
expect(filesCreated).to.include(patterns[pattern].newfile);
645+
expect(filesCreated).to.include(patterns[pattern].oldfile + '.gz');
646+
transport.close();
647+
648+
done();
649+
});
650+
});
651+
});
652+
});
653+
});
654+
});
655+
});
495656
});
496657
});

0 commit comments

Comments
 (0)