Squashed commit for the version 0.4.5:

commit 7a1723f211419a1f0e9bbac61788ecd5440ab166
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 09:33:35 2014 +0400

    Changed version to 0.4.5

commit 27aae6ba7942684ff76582c631bc47bc8e411c63
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 09:31:47 2014 +0400

    Fixed #32

commit 8960fb92df6f45c616f11e7d84db14fe110dabd9
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 09:01:25 2014 +0400

    Implemented connection strings support

    fixed #22

commit 88fe2146eea864479977a7ab376820f3e4300b48
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 08:29:35 2014 +0400

    Added support for includeIds option in query and stream methods

    fixed #26

commit d55190870513ea3b2c13c09f921204723b87c08c
Merge: e104e16 fe1120f
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 08:25:25 2014 +0400

    Merge branch 'master' of https://github.com/diosney/winston-mongodb into devel

commit e104e16f01ee869e8848181e3ee7205d5672e6cb
Merge: 3bb126d 116abf7
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 08:18:07 2014 +0400

    Merge branch 'master' of github.com:indexzero/winston-mongodb into devel

commit 116abf7bcf3b8048d7340cfb712ea7127911b7c4
Merge: c069938 3b5a35a
Author: Yurij Mikhalevich <0@39.yt>
Date:   Sat May 24 08:17:50 2014 +0400

    Merge pull request #29 from ognus/master

    Fix for MongoDB transport not handling exceptions (issue #24).

commit 3bb126d466e79c8e49979a4d18fc74df1fb0457f
Author: Yurij Mikhalevich <0@39.yt>
Date:   Fri May 23 20:51:01 2014 +0400

    Patched 'tailable cursor requested on non capped collection' error
    handling hack

    Fix for #28.

commit 7cad72ad8b9e58a2654cf3327e08b1ad6b22087d
Author: Yurij Mikhalevich <0@39.yt>
Date:   Fri May 23 20:35:04 2014 +0400

    Updated mongodb to 1.4.x

commit 318a7da99299e157bb98aa883aedb06a536e34a8
Author: Yurij Mikhalevich <0@39.yt>
Date:   Fri May 23 20:26:39 2014 +0400

    Added .idea to .npmignore

commit 402d20ff84f75a91709164e7f5e5160b88a47529
Author: Yurij Mikhalevich <0@39.yt>
Date:   Fri May 23 20:21:59 2014 +0400

    Implemented logging for circular metadata

    * added lib.helper.makeObjectNonCircular(object) method, which replaces
    any occurences of circular references with '[Circular]' string.

commit c861c1425b5cf410f790d2410684dc7066934c5f
Author: Yurij Mikhalevich <0@39.yt>
Date:   Fri May 23 20:08:54 2014 +0400

    Fixed logging circular structures

    * added lib.helper.makeObjectNonCircular(object) method, which
    replaces all circular references mentioned in object with '[Circular]'
    string.

commit 68bf133ee053df052714767889e577a31ac43e46
Author: Yurij Mikhalevich <0@39.yt>
Date:   Fri May 23 19:21:39 2014 +0400

    Added .idea to .gitignore

commit 3b5a35a536dcce4e86cd47b9c54befad85aca1d1
Author: Tomek Kolasa <kolasa.tomek@gmail.com>
Date:   Tue Mar 11 11:07:08 2014 +1300

    Added missing Transport.call(this, options) call to the MongoDB transport constructor. Fix for handleExceptions: true not working (#24).

commit fe1120f8dcd8c15298c95a814b6bdbf44981ac19
Author: Diosney <diosney.s@gmail.com>
Date:   Mon Feb 10 13:34:37 2014 -0500

    [api] Added new [query & stream] option:

        - To let users specify if they want the `_id`s included.
        - The corresponding documentation.
This commit is contained in:
Yurij Mikhalevich 2014-05-24 09:34:13 +04:00
Родитель c069938103
Коммит f098a0f09d
6 изменённых файлов: 120 добавлений и 19 удалений

3
.gitignore поставляемый
Просмотреть файл

@ -1,2 +1,3 @@
node_modules
npm-debug.log
npm-debug.log
.idea

Просмотреть файл

@ -1,2 +1,3 @@
.git*
npm-debug.log
.idea

Просмотреть файл

@ -25,7 +25,7 @@ The MongoDB transport takes the following options. 'db' is required:
* __level:__ Level of messages that this transport should log, defaults to 'info'.
* __silent:__ Boolean flag indicating whether to suppress output, defaults to false.
* __db:__ The name of the database you want to log to. *[required]*
* __db:__ The name of the database you want to log to.
* __collection__: The name of the collection you want to store log messages in, defaults to 'logs'.
* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true.
* __nativeParser:__ Boolean indicating if you want the driver to use native parser feature or not.
@ -38,9 +38,18 @@ The MongoDB transport takes the following options. 'db' is required:
* __storeHost:__ Boolean indicating if you want to store machine hostname in logs entry, if set to true it populates MongoDB entry with 'hostname' field, which stores os.hostname() value.
* __ssl:__ Boolean indicating if you want to use SSL connections or not.
* __authDb:__ Authentication database object.
* __dbUri:__ Alternative way of specifying database connection data. Note, that __replica sets are unsupported__. If you specify a replica set or multiple databases, will be used first database connection data.
*Notice:* __db__ is required. You should specify it directly or in __dbUri__.
*Metadata:* Logged as a native JSON object.
## Querying and streaming logs
Besides supporting the main options from winston, this transport supports the following extra options:
* __includeIds:__ Whether the returned logs should include the `_id` attribute settled by mongodb, defaults to `false`.
## Installation
### Installing npm (node package manager)

31
lib/helpers.js Normal file
Просмотреть файл

@ -0,0 +1,31 @@
/*
* mongodb.js: Transport for outputting to a MongoDB database
*
* (C) 2014 Yurij Mikhalevich
* MIT LICENCE
*
*/
exports.makeObjectNonCircular = function (node, parents) {
parents = parents || [];
var keys = Object.keys(node);
var i;
var value;
parents.push(node); // add self to current path
for (i = keys.length - 1; i >= 0; --i) {
value = node[keys[i]];
if (value && typeof value === 'object') {
if (parents.indexOf(value) === -1) {
// check child nodes
arguments.callee(value, parents);
} else {
// circularity detected!
node[keys[i]] = '[Circular]';
}
}
}
parents.pop();
};

Просмотреть файл

@ -8,18 +8,34 @@
var util = require('util');
var os = require('os');
var muri = require('muri');
var mongodb = require('mongodb');
var winston = require('winston');
var common = require('winston/lib/winston/common');
var Stream = require('stream').Stream;
var helpers = require('./helpers');
//
// ### function MongoDB (options)
// Constructor for the MongoDB transport object.
//
var MongoDB = exports.MongoDB = function (options) {
winston.Transport.call(this, options);
options = options || {};
if (options.dbUri) {
var uriOptions = muri(options.dbUri);
options.db = uriOptions.db;
if (uriOptions.hosts && uriOptions.hosts[0]) {
options.host = uriOptions.hosts[0].host;
options.port = uriOptions.hosts[0].port;
}
if (uriOptions.auth) {
options.username = uriOptions.auth.user;
options.password = uriOptions.auth.pass;
}
}
if (!options.db) {
throw new Error('Cannot log to MongoDB without database name.');
}
@ -110,8 +126,7 @@ MongoDB.prototype.log = function (level, msg, meta, callback) {
self.open(function (err) {
if (err) {
self.emit('error', err);
return callback(err, null);
return onError(err);
}
// Set a timeout to close the client connection unless `self.keepAlive`
@ -141,6 +156,41 @@ MongoDB.prototype.log = function (level, msg, meta, callback) {
if (typeof meta !== 'object' && meta != null) {
meta = { meta: meta };
} else {
helpers.makeObjectNonCircular(meta);
}
//
// Added to compatibility with express-winston
//
if (meta.req) {
function clearRequestData(object) {
for (var field in object) {
if (!object.hasOwnProperty(field)) {
continue;
}
var value = object[field];
if (field.indexOf('.') !== 0) {
delete object[field];
field = field.replace('.', '[dot]');
object[field] = value;
}
if (field.indexOf('$') === 0) {
delete object[field];
field = field.replace('$', '[$]');
object[field] = value;
}
if (typeof value === 'object') {
clearRequestData(value);
}
}
}
if (meta.req.query) {
clearRequestData(meta.req.query);
}
if (meta.req.body) {
clearRequestData(meta.req.body);
}
}
var entry = common.clone(meta) || {};
@ -210,9 +260,11 @@ MongoDB.prototype.query = function (options, callback) {
if (err) return callback(err);
col.find(query, opt).toArray(function (err, docs) {
if (err) return callback(err);
docs.forEach(function (log) {
delete log._id;
});
if (!options.includeIds) {
docs.forEach(function (log) {
delete log._id;
});
}
if (callback) callback(null, docs);
});
});
@ -246,17 +298,15 @@ MongoDB.prototype.stream = function (options, stream) {
start = null;
}
var opt = {
tailable: true
};
if (start != null) {
this._db.collection(this.collection, function (err, col) {
if (err) return stream.emit('error', err);
col.find({}, { skip: start }).toArray(function (err, docs) {
if (err) return stream.emit('error', err);
docs.forEach(function (doc) {
delete doc._id;
if (!options.includeIds) {
delete doc._id;
}
stream.emit('log', doc);
});
delete options.start;
@ -272,7 +322,7 @@ MongoDB.prototype.stream = function (options, stream) {
if (stream.destroyed) return;
var cursor = col.find({}, opt);
var cursor = col.find({}, { tailable: true });
// tail cursor
var tail = cursor.stream();
@ -283,7 +333,9 @@ MongoDB.prototype.stream = function (options, stream) {
};
tail.on('data', function (doc) {
delete doc._id;
if (!options.includeIds) {
delete doc._id;
}
stream.emit('log', doc);
});
@ -293,7 +345,9 @@ MongoDB.prototype.stream = function (options, stream) {
}
// hack because isCapped doesn't work
if (err.message === 'tailable cursor requested on non capped collection') {
var notCappedError = 'tailable cursor requested on non capped collection';
if (err.message.indexOf(notCappedError,
err.message.length - notCappedError.length) !== -1) {
tail.destroy();
self.streamPoll(options, stream);
return;
@ -359,12 +413,16 @@ MongoDB.prototype.streamPoll = function (options, stream) {
if (start == null) {
docs.forEach(function (doc) {
delete doc._id;
if (!options.includeIds) {
delete doc._id;
}
stream.emit('log', doc);
});
} else {
docs.forEach(function (doc) {
delete doc._id;
if (!options.includeIds) {
delete doc._id;
}
if (!start) {
stream.emit('log', doc);
} else {

Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "winston-mongodb",
"version": "0.4.3",
"version": "0.4.5",
"description": "A MongoDB transport for winston",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",
"contributors": [
@ -14,7 +14,8 @@
},
"keywords": [ "logging", "sysadmin", "tools", "winston", "mongodb", "log", "logger" ],
"dependencies": {
"mongodb": "1.3.x"
"mongodb": "1.4.x",
"muri": "0.3.x"
},
"devDependencies": {
"winston": "0.7.x",