diff --git a/README.md b/README.md index b68d857..875e0c3 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ defaults to false. * __metaKey:__ Configure which key is used to store metadata in the logged info object. Defaults to `'metadata'` to remain compatible with the [metadata format](https://github.com/winstonjs/logform/blob/master/examples/metadata.js) * __expireAfterSeconds:__ Seconds before the entry is removed. Works only if __capped__ is not set. +* __partialFilterExpression:__ Optional condition for the entry to be removed. Works only if __capped__ is not set and __expireAfterSeconds__ is set. *Metadata:* Logged as a native JSON object in 'meta' property. diff --git a/lib/winston-mongodb.d.ts b/lib/winston-mongodb.d.ts index 32418cd..4998cc4 100644 --- a/lib/winston-mongodb.d.ts +++ b/lib/winston-mongodb.d.ts @@ -141,7 +141,14 @@ declare module 'winston-mongodb' { * @memberof MongoDBConnectionOptions */ expireAfterSeconds?: number; + /** + * Optional condition for the entry to be removed. Works only if capped is not set and expireAfterSeconds is set. + * + * @type {*} + * @memberof MongoDBConnectionOptions + */ + partialFilterExpression?: any; } - + const MongoDB: MongoDBTransportInstance; } diff --git a/lib/winston-mongodb.js b/lib/winston-mongodb.js index 8afeefd..1128946 100644 --- a/lib/winston-mongodb.js +++ b/lib/winston-mongodb.js @@ -51,6 +51,8 @@ const helpers = require('./helpers'); * after transport shut down. * @param {number} options.expireAfterSeconds Seconds before the entry is removed. * Do not use if capped is set. + * @param {Object} options.partialFilterExpression Condition for the entry to be removed. + * Do not use if capped is set or expireAfterSeconds is not set. */ let MongoDB = exports.MongoDB = function(options) { Transport.call(this, options); @@ -79,6 +81,7 @@ let MongoDB = exports.MongoDB = function(options) { this.decolorize = options.decolorize; this.leaveConnectionOpen = options.leaveConnectionOpen; this.expireAfterSeconds = !this.capped && options.expireAfterSeconds; + this.partialFilterExpression = !this.capped && this.expireAfterSeconds && options.partialFilterExpression ? options.partialFilterExpression : null; this.metaKey = options.metaKey || 'metadata'; if (this.storeHost) { this.hostname = os.hostname(); @@ -113,15 +116,22 @@ let MongoDB = exports.MongoDB = function(options) { if (self.expireAfterSeconds) { indexOpts.expireAfterSeconds = self.expireAfterSeconds; } + if (self.partialFilterExpression) { + indexOpts.partialFilterExpression = self.partialFilterExpression; + } return col.indexInformation({full: true}).then(info=>{ info = info.filter(i=>i.name === ttlIndexName); if (info.length === 0) { // if its a new index then create it return col.createIndex({timestamp: -1}, indexOpts); - } else { // if index existed with the same name check if expireAfterSeconds param has changed + } else { // if index existed with the same name check if expireAfterSeconds or partialFilterExpression param has changed if (info[0].expireAfterSeconds !== undefined && info[0].expireAfterSeconds !== self.expireAfterSeconds) { return col.dropIndex(ttlIndexName) .then(()=>col.createIndex({timestamp: -1}, indexOpts)); + } else if (info[0].partialFilterExpression !== undefined && + JSON.stringify(info[0].partialFilterExpression) !== JSON.stringify(self.partialFilterExpression)) { + return col.dropIndex(ttlIndexName) + .then(()=>col.createIndex({timestamp: -1}, indexOpts)); } } });