winston-cloudwatch
Advanced tools
Comparing version
@@ -0,1 +1,5 @@ | ||
### 1.12.0 | ||
Added ability to specify a retention policy | ||
### 1.11.4 | ||
@@ -2,0 +6,0 @@ |
@@ -17,2 +17,3 @@ 'use strict'; | ||
this.logGroupName = options.logGroupName; | ||
this.retentionInDays = options.retentionInDays || 0; | ||
this.logStreamName = options.logStreamName; | ||
@@ -114,2 +115,3 @@ | ||
this.logStreamName() : this.logStreamName; | ||
var retentionInDays = this.retentionInDays; | ||
@@ -125,2 +127,3 @@ if (_.isEmpty(this.logEvents)) { | ||
this.logEvents, | ||
retentionInDays, | ||
callback | ||
@@ -127,0 +130,0 @@ ); |
@@ -14,3 +14,3 @@ var LIMITS = { | ||
lib.upload = function(aws, groupName, streamName, logEvents, cb) { | ||
lib.upload = function(aws, groupName, streamName, logEvents, retentionInDays, cb) { | ||
debug('upload', logEvents); | ||
@@ -41,3 +41,3 @@ | ||
function safeUpload(cb) { | ||
lib.getToken(aws, groupName, streamName, function(err, token) { | ||
lib.getToken(aws, groupName, streamName, retentionInDays, function(err, token) { | ||
@@ -55,6 +55,6 @@ if (err) { | ||
// unit tests pass null elements | ||
var evSize = ev ? Buffer.byteLength(ev.message, 'utf8') : 0; | ||
var evSize = ev ? Buffer.byteLength(ev.message, 'utf8') : 0; | ||
if(evSize > LIMITS.MAX_EVENT_MSG_SIZE_BYTES) { | ||
evSize = LIMITS.MAX_EVENT_MSG_SIZE_BYTES; | ||
ev.message = ev.message.substring(0, evSize); | ||
ev.message = ev.message.substring(0, evSize); | ||
const msgTooBigErr = new Error('Message Truncated because it exceeds the CloudWatch size limit'); | ||
@@ -82,3 +82,3 @@ msgTooBigErr.logEvent = ev; | ||
debug('InvalidSequenceTokenException, retrying', true) | ||
lib.submitWithAnotherToken(aws, groupName, streamName, payload, cb) | ||
lib.submitWithAnotherToken(aws, groupName, streamName, payload, retentionInDays, cb) | ||
} else { | ||
@@ -97,4 +97,4 @@ debug('error during putLogEvents', err, true) | ||
lib.submitWithAnotherToken = function(aws, groupName, streamName, payload, cb) { | ||
lib.getToken(aws, groupName, streamName, function(err, token) { | ||
lib.submitWithAnotherToken = function(aws, groupName, streamName, payload, retentionInDays, cb) { | ||
lib.getToken(aws, groupName, streamName, retentionInDays, function(err, token) { | ||
payload.sequenceToken = token; | ||
@@ -120,5 +120,5 @@ aws.putLogEvents(payload, function(err) { | ||
lib.getToken = function(aws, groupName, streamName, cb) { | ||
lib.getToken = function(aws, groupName, streamName, retentionInDays, cb) { | ||
async.series([ | ||
lib.ensureGroupPresent.bind(null, aws, groupName), | ||
lib.ensureGroupPresent.bind(null, aws, groupName, retentionInDays), | ||
lib.getStream.bind(null, aws, groupName, streamName) | ||
@@ -138,3 +138,3 @@ ], function(err, resources) { | ||
lib.ensureGroupPresent = function ensureGroupPresent(aws, name, cb) { | ||
lib.ensureGroupPresent = function ensureGroupPresent(aws, name, retentionInDays, cb) { | ||
debug('ensure group present'); | ||
@@ -147,5 +147,7 @@ var params = { logGroupName: name }; | ||
return aws.createLogGroup(params, lib.ignoreInProgress(function(err) { | ||
if(!err) lib.putRetentionPolicy(aws, name, retentionInDays); | ||
cb(err, err ? false : true); | ||
})); | ||
} else { | ||
lib.putRetentionPolicy(aws, name, retentionInDays); | ||
cb(err, true); | ||
@@ -156,2 +158,15 @@ } | ||
lib.putRetentionPolicy = function putRetentionPolicy(aws, groupName, days) { | ||
var params = { | ||
logGroupName: groupName, | ||
retentionInDays: days | ||
}; | ||
if (days > 0) { | ||
debug('setting retention policy for "' + groupName + '" to ' + days + ' days'); | ||
aws.putRetentionPolicy(params, function(err, data) { | ||
if (err) console.error('failed to set retention policy for ' + groupName + ' to ' + days + ' days due to ' + err.stack); | ||
}); | ||
} | ||
}; | ||
lib.getStream = function getStream(aws, groupName, streamName, cb) { | ||
@@ -158,0 +173,0 @@ var params = { |
{ | ||
"name": "winston-cloudwatch", | ||
"version": "1.11.4", | ||
"version": "1.12.0", | ||
"description": "Send logs to Amazon Cloudwatch using Winston.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -1,2 +0,2 @@ | ||
# winston-cloudwatch [v1.11.4](https://github.com/lazywithclass/winston-cloudwatch/blob/master/CHANGELOG.md#1114) | ||
# winston-cloudwatch [v1.12.0](https://github.com/lazywithclass/winston-cloudwatch/blob/master/CHANGELOG.md#1120) | ||
@@ -109,2 +109,3 @@ [](https://travis-ci.org/lazywithclass/winston-cloudwatch) [](https://coveralls.io/github/lazywithclass/winston-cloudwatch?branch=master) [](https://david-dm.org/lazywithclass/winston-cloudwatch) [](https://david-dm.org/lazywithclass/winston-cloudwatch#info=devDependencies) [](https://david-dm.org/lazywithclass/winston-cloudwatch#info=peerDependencies) | ||
* errorHandler - `function`, invoked with an error object, if not provided the error is sent to `console.error` | ||
* retentionInDays - `Number`, defaults to `0`, if set to one of the possible values `1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653` the retention policy on the log group written will be set to the value provided. | ||
@@ -111,0 +112,0 @@ AWS keys are usually picked by aws-sdk so you don't have to specify them, I provided the option just in case. Remember that `awsRegion` should still be set if you're using IAM roles. |
@@ -15,2 +15,3 @@ describe('cloudwatch-integration', function() { | ||
aws.putLogEvents = sinon.stub().yields(); | ||
aws.putRetentionPolicy = sinon.stub().returns(); | ||
sinon.stub(lib, 'getToken').yields(null, 'token'); | ||
@@ -31,4 +32,4 @@ sinon.stub(lib, 'submitWithAnotherToken').yields(); | ||
aws.putLogEvents.onSecondCall().yields(); | ||
lib.upload(aws, 'group', 'stream', events, function(){}); | ||
lib.upload(aws, 'group', 'stream', events, function() { | ||
lib.upload(aws, 'group', 'stream', events, 0, function(){}); | ||
lib.upload(aws, 'group', 'stream', events, 0, function() { | ||
// The second upload call should get ignored | ||
@@ -45,4 +46,4 @@ aws.putLogEvents.calledOnce.should.equal(true); | ||
lib.getToken.onSecondCall().yields(null, 'token'); | ||
lib.upload(aws, 'group', 'stream', events, function(){}); | ||
lib.upload(aws, 'group', 'stream', events, function() { | ||
lib.upload(aws, 'group', 'stream', events, 0, function(){}); | ||
lib.upload(aws, 'group', 'stream', events, 0, function() { | ||
// The second upload call should get ignored | ||
@@ -59,3 +60,3 @@ lib.getToken.calledOnce.should.equal(true); | ||
var errCalled = false; | ||
lib.upload(aws, 'group', 'stream', events, function(err) { | ||
lib.upload(aws, 'group', 'stream', events, 0, function(err) { | ||
if(err) { | ||
@@ -82,7 +83,7 @@ errCalled = true; | ||
]; | ||
lib.upload(aws, 'group', 'stream', events, function(err) { | ||
lib.upload(aws, 'group', 'stream', events, 0, function(err) { | ||
aws.putLogEvents.calledOnce.should.equal(true); | ||
aws.putLogEvents.args[0][0].logEvents.length.should.equal(4); // First Batch | ||
// Now, finish. | ||
lib.upload(aws, 'group', 'stream', events, function(err) { | ||
lib.upload(aws, 'group', 'stream', events, 0, function(err) { | ||
aws.putLogEvents.args[1][0].logEvents.length.should.equal(1); // Second Batch | ||
@@ -95,3 +96,3 @@ done() | ||
it('puts log events', function(done) { | ||
lib.upload(aws, 'group', 'stream', Array(20), function() { | ||
lib.upload(aws, 'group', 'stream', Array(20), 0, function() { | ||
aws.putLogEvents.calledOnce.should.equal(true); | ||
@@ -108,3 +109,3 @@ aws.putLogEvents.args[0][0].logGroupName.should.equal('group'); | ||
lib.getToken.yields(null); | ||
lib.upload(aws, 'group', 'stream', Array(20), function() { | ||
lib.upload(aws, 'group', 'stream', Array(20), 0, function() { | ||
aws.putLogEvents.calledOnce.should.equal(true); | ||
@@ -120,3 +121,3 @@ aws.putLogEvents.args[0][0].logGroupName.should.equal('group'); | ||
it('does not put if events are empty', function(done) { | ||
lib.upload(aws, 'group', 'stream', [], function() { | ||
lib.upload(aws, 'group', 'stream', [], 0, function() { | ||
aws.putLogEvents.called.should.equal(false); | ||
@@ -129,3 +130,3 @@ done(); | ||
lib.getToken.yields('err'); | ||
lib.upload(aws, 'group', 'stream', Array(20), function(err) { | ||
lib.upload(aws, 'group', 'stream', Array(20), 0, function(err) { | ||
err.should.equal('err'); | ||
@@ -138,3 +139,3 @@ done(); | ||
aws.putLogEvents.yields('err'); | ||
lib.upload(aws, 'group', 'stream', Array(20), function(err) { | ||
lib.upload(aws, 'group', 'stream', Array(20), 0, function(err) { | ||
err.should.equal('err'); | ||
@@ -147,3 +148,3 @@ done(); | ||
aws.putLogEvents.yields({ code: 'InvalidSequenceTokenException' }); | ||
lib.upload(aws, 'group', 'stream', Array(20), function(err) { | ||
lib.upload(aws, 'group', 'stream', Array(20), 0, function(err) { | ||
lib.submitWithAnotherToken.calledOnce.should.equal(true); | ||
@@ -156,2 +157,17 @@ done(); | ||
describe('putRetentionPolicy', function() { | ||
var aws = {}; | ||
beforeEach(function() { | ||
aws.putRetentionPolicy = sinon.stub().returns(); | ||
}); | ||
it('only logs retention policy if given > 0', function() { | ||
lib.putRetentionPolicy(aws, 'group', 1); | ||
aws.putRetentionPolicy.calledOnce.should.equal(true); | ||
}); | ||
it('doesnt logs retention policy if given = 0', function() { | ||
lib.putRetentionPolicy(aws, 'group', 0); | ||
aws.putRetentionPolicy.calledOnce.should.equal(false); | ||
}); | ||
}); | ||
describe('getToken', function() { | ||
@@ -172,3 +188,3 @@ | ||
it('ensures group and stream are present', function(done) { | ||
lib.getToken(aws, 'group', 'stream', function() { | ||
lib.getToken(aws, 'group', 'stream', 0, function() { | ||
lib.ensureGroupPresent.calledOnce.should.equal(true); | ||
@@ -185,3 +201,3 @@ lib.getStream.calledOnce.should.equal(true); | ||
}); | ||
lib.getToken(aws, 'group', 'stream', function(err, token) { | ||
lib.getToken(aws, 'group', 'stream', 0, function(err, token) { | ||
should.not.exist(err); | ||
@@ -195,3 +211,3 @@ token.should.equal('token'); | ||
lib.ensureGroupPresent.yields('err'); | ||
lib.getToken(aws, 'group', 'stream', function(err) { | ||
lib.getToken(aws, 'group', 'stream', 0, function(err) { | ||
err.should.equal('err'); | ||
@@ -204,3 +220,3 @@ done(); | ||
lib.getStream.yields('err'); | ||
lib.getToken(aws, 'group', 'stream', function(err) { | ||
lib.getToken(aws, 'group', 'stream', 0, function(err) { | ||
err.should.equal('err'); | ||
@@ -223,8 +239,10 @@ done(); | ||
}; | ||
lib.putRetentionPolicy = sinon.stub(); | ||
}); | ||
it('makes sure that a group is present', function(done) { | ||
lib.ensureGroupPresent(aws, 'group', function(err, isPresent) { | ||
lib.ensureGroupPresent(aws, 'group', 0, function(err, isPresent) { | ||
should.not.exist(err); | ||
isPresent.should.equal(true); | ||
lib.putRetentionPolicy.calledWith(aws, 'group', 0).should.equal(true); | ||
done(); | ||
@@ -239,4 +257,5 @@ }); | ||
lib.ensureGroupPresent(aws, 'group', function(err, isPresent) { | ||
lib.ensureGroupPresent(aws, 'group', 0, function(err, isPresent) { | ||
should.not.exist(err); | ||
lib.putRetentionPolicy.calledWith(aws, 'group', 0).should.equal(true); | ||
isPresent.should.equal(true); | ||
@@ -250,3 +269,3 @@ done(); | ||
lib.ensureGroupPresent(aws, 'group', function(err) { | ||
lib.ensureGroupPresent(aws, 'group', 0, function(err) { | ||
err.should.equal('err'); | ||
@@ -262,4 +281,5 @@ done(); | ||
lib.ensureGroupPresent(aws, 'group', function(err) { | ||
lib.ensureGroupPresent(aws, 'group', 0, function(err) { | ||
err.should.equal('err'); | ||
lib.putRetentionPolicy.calledOnce.should.equal(false); | ||
done(); | ||
@@ -434,3 +454,3 @@ }); | ||
it('gets a token then resubmits', function(done) { | ||
lib.submitWithAnotherToken(aws, 'group', 'stream', {}, function() { | ||
lib.submitWithAnotherToken(aws, 'group', 'stream', {}, 0, function() { | ||
aws.putLogEvents.calledOnce.should.equal(true); | ||
@@ -437,0 +457,0 @@ aws.putLogEvents.args[0][0].sequenceToken.should.equal('new-token'); |
@@ -20,3 +20,3 @@ describe('index', function() { | ||
var stubbedCloudwatchIntegration = { | ||
upload: sinon.spy(function(aws, groupName, streamName, logEvents, cb) { | ||
upload: sinon.spy(function(aws, groupName, streamName, logEvents, retention, cb) { | ||
this.lastLoggedEvents = logEvents.splice(0, 20); | ||
@@ -23,0 +23,0 @@ cb(); |
52220
4.7%23
4.55%1098
4.37%145
0.69%