Comparing version 0.7.2 to 0.7.3
@@ -293,2 +293,25 @@ # Winston Transports | ||
### Cassandra Transport | ||
[winston-cassandra][20] is a Cassandra transport: | ||
``` js | ||
var Cassandra = require('winston-cassandra').Cassandra; | ||
winston.add(Cassandra, options); | ||
``` | ||
The Cassandra transport connects to a cluster using the native protocol with the following options: | ||
* __level:__ Level of messages that this transport should log (default: `'info'`). | ||
* __table:__ The name of the Cassandra column family you want to store log messages in (default: `'logs'`). | ||
* __partitionBy:__ How you want the logs to be partitioned. Possible values `'hour'` and `'day'`(Default). | ||
* __consistency:__ The consistency of the insert query (default: `quorum`). | ||
In addition to the options accepted by the [Node.js Cassandra driver](https://github.com/jorgebay/node-cassandra-cql) Client. | ||
* __hosts:__ Cluster nodes that will handle the write requests: | ||
Array of strings containing the hosts, for example `['host1', 'host2']` (required). | ||
* __keyspace:__ The name of the keyspace that will contain the logs table (required). The keyspace should be already created in the cluster. | ||
## Find more Transports | ||
@@ -299,24 +322,25 @@ | ||
(...) | ||
winston-amon Winston transport for Amon logging =zoramite | ||
winston-amqp An AMQP transport for winston =kr1sp1n | ||
winston-couchdb a couchdb transport for winston =alz | ||
winston-express Express middleware to let you use winston from the browser. =regality | ||
winston-graylog2 A graylog2 transport for winston =smithclay | ||
winston-hbase A HBase transport for winston =ddude | ||
winston-loggly A Loggly transport for winston =indexzero | ||
winston-mail A mail transport for winston =wavded | ||
winston-mail2 A mail transport for winston =ivolo | ||
winston-mongodb A MongoDB transport for winston =indexzero | ||
winston-nodemail A mail transport for winston =reinpk | ||
winston-nssocket nssocket transport for winston =mmalecki | ||
winston-papertrail A Papertrail transport for winston =kenperkins | ||
winston-redis A fixed-length Redis transport for winston =indexzero | ||
winston-riak A Riak transport for winston =indexzero | ||
winston-scribe A scribe transport for winston =wnoronha | ||
winston-simpledb A Winston transport for Amazon SimpleDB =chilts | ||
winston-skywriter A Windows Azure table storage transport for winston =pofallon | ||
winston-amon Winston transport for Amon logging =zoramite | ||
winston-amqp An AMQP transport for winston =kr1sp1n | ||
winston-cassandra A Cassandra transport for winston =jorgebay | ||
winston-couchdb a couchdb transport for winston =alz | ||
winston-express Express middleware to let you use winston from the browser. =regality | ||
winston-graylog2 A graylog2 transport for winston =smithclay | ||
winston-hbase A HBase transport for winston =ddude | ||
winston-loggly A Loggly transport for winston =indexzero | ||
winston-mail A mail transport for winston =wavded | ||
winston-mail2 A mail transport for winston =ivolo | ||
winston-mongodb A MongoDB transport for winston =indexzero | ||
winston-nodemail A mail transport for winston =reinpk | ||
winston-nssocket nssocket transport for winston =mmalecki | ||
winston-papertrail A Papertrail transport for winston =kenperkins | ||
winston-redis A fixed-length Redis transport for winston =indexzero | ||
winston-riak A Riak transport for winston =indexzero | ||
winston-scribe A scribe transport for winston =wnoronha | ||
winston-simpledb A Winston transport for Amazon SimpleDB =chilts | ||
winston-skywriter A Windows Azure table storage transport for winston =pofallon | ||
winston-sns A Simple Notification System Transport for winston =jesseditson | ||
winston-syslog A syslog transport for winston =indexzero | ||
winston-syslog-ain2 An ain2 based syslog transport for winston =lamtha | ||
winston-winlog Windows Event Log logger for Winston =jfromaniello | ||
winston-syslog A syslog transport for winston =indexzero | ||
winston-syslog-ain2 An ain2 based syslog transport for winston =lamtha | ||
winston-winlog Windows Event Log logger for Winston =jfromaniello | ||
winston-zmq A 0MQ transport for winston =dhendo | ||
@@ -347,2 +371,2 @@ winston-growl A growl transport for winston =pgherveou | ||
[19]: https://github.com/flite/winston-graylog2 | ||
[20]: https://github.com/jorgebay/winston-cassandra |
@@ -12,2 +12,3 @@ /* | ||
cycle = require('cycle'), | ||
fs = require('fs'), | ||
config = require('./config'); | ||
@@ -290,1 +291,59 @@ | ||
}; | ||
// | ||
// ### function tailFile (options, callback) | ||
// #### @options {Object} Options for tail. | ||
// #### @callback {function} Callback to execute on every line. | ||
// `tail -f` a file. Options must include file. | ||
// | ||
exports.tailFile = function tail(options, callback) { | ||
var stream = fs.createReadStream(options.file, { encoding: 'utf8' }), | ||
buff = '', | ||
destroy, | ||
row = 0; | ||
destroy = stream.destroy.bind(stream); | ||
stream.destroy = function () {}; | ||
if (options.start === -1) { | ||
delete options.start; | ||
} | ||
stream.on('data', function (data) { | ||
var data = (buff + data).split(/\n+/), | ||
l = data.length - 1, | ||
i = 0; | ||
for (; i < l; i++) { | ||
if (options.start == null || row > options.start) { | ||
callback(null, data[i]); | ||
} | ||
row++; | ||
} | ||
buff = data[l]; | ||
}); | ||
stream.on('error', function (err) { | ||
callback(err); | ||
destroy(); | ||
}); | ||
stream.on('end', function () { | ||
if (buff) { | ||
stream.emit('line', buff); | ||
buff = ''; | ||
} | ||
resume(); | ||
}); | ||
function resume() { | ||
setTimeout(function () { | ||
stream.resume(); | ||
}, 1000); | ||
} | ||
return destroy; | ||
}; |
@@ -125,4 +125,9 @@ /* | ||
var self = this, | ||
args = Array.prototype.slice.call(arguments, 1), | ||
callback = typeof args[args.length - 1] === 'function' ? args.pop() : null, | ||
args = Array.prototype.slice.call(arguments, 1); | ||
while(args[args.length - 1] === null) { | ||
args.pop(); | ||
} | ||
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null, | ||
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {}, | ||
@@ -129,0 +134,0 @@ msg = util.format.apply(null, args); |
@@ -308,72 +308,2 @@ /* | ||
// | ||
// ### function _tail (options, callback) | ||
// #### @options {Object} Options for tail. | ||
// #### @callback {function} Callback to execute on every line. | ||
// `tail -f` a file. Options must include file. | ||
// | ||
DailyRotateFile.prototype._tail = function tail(options, callback) { | ||
var stream = fs.createReadStream(options.file, { encoding: 'utf8' }), | ||
buff = '', | ||
destroy, | ||
row = 0; | ||
destroy = stream.destroy.bind(stream); | ||
stream.destroy = function () {}; | ||
if (options.start === -1) { | ||
delete options.start; | ||
} | ||
if (options.start == null) { | ||
stream.once('end', bind); | ||
} else { | ||
bind(); | ||
} | ||
function bind() { | ||
stream.on('data', function (data) { | ||
var data = (buff + data).split(/\n+/), | ||
l = data.length - 1, | ||
i = 0; | ||
for (; i < l; i++) { | ||
if (options.start == null || row > options.start) { | ||
stream.emit('line', data[i]); | ||
} | ||
row++; | ||
} | ||
buff = data[l]; | ||
}); | ||
stream.on('line', function (data) { | ||
if (callback) callback(data); | ||
}); | ||
stream.on('error', function (err) { | ||
destroy(); | ||
}); | ||
stream.on('end', function () { | ||
if (buff) { | ||
stream.emit('line', buff); | ||
buff = ''; | ||
} | ||
resume(); | ||
}); | ||
resume(); | ||
} | ||
function resume() { | ||
setTimeout(function () { | ||
stream.resume(); | ||
}, 1000); | ||
} | ||
return destroy; | ||
}; | ||
// | ||
// ### function stream (options) | ||
@@ -393,3 +323,8 @@ // #### @options {Object} Stream options for this instance. | ||
stream.destroy = this._tail(tail, function (line) { | ||
stream.destroy = common.tailFile(tail, function (err, line) { | ||
if(err){ | ||
return stream.emit('error',err); | ||
} | ||
try { | ||
@@ -403,2 +338,6 @@ stream.emit('data', line); | ||
}); | ||
if(stream.resume){ | ||
stream.resume(); | ||
} | ||
@@ -405,0 +344,0 @@ return stream; |
@@ -279,72 +279,2 @@ /* | ||
// | ||
// ### function _tail (options, callback) | ||
// #### @options {Object} Options for tail. | ||
// #### @callback {function} Callback to execute on every line. | ||
// `tail -f` a file. Options must include file. | ||
// | ||
File.prototype._tail = function tail(options, callback) { | ||
var stream = fs.createReadStream(options.file, { encoding: 'utf8' }), | ||
buff = '', | ||
destroy, | ||
row = 0; | ||
destroy = stream.destroy.bind(stream); | ||
stream.destroy = function () {}; | ||
if (options.start === -1) { | ||
delete options.start; | ||
} | ||
if (options.start == null) { | ||
stream.once('end', bind); | ||
} else { | ||
bind(); | ||
} | ||
function bind() { | ||
stream.on('data', function (data) { | ||
var data = (buff + data).split(/\n+/), | ||
l = data.length - 1, | ||
i = 0; | ||
for (; i < l; i++) { | ||
if (options.start == null || row > options.start) { | ||
stream.emit('line', data[i]); | ||
} | ||
row++; | ||
} | ||
buff = data[l]; | ||
}); | ||
stream.on('line', function (data) { | ||
if (callback) callback(data); | ||
}); | ||
stream.on('error', function (err) { | ||
destroy(); | ||
}); | ||
stream.on('end', function () { | ||
if (buff) { | ||
stream.emit('line', buff); | ||
buff = ''; | ||
} | ||
resume(); | ||
}); | ||
resume(); | ||
} | ||
function resume() { | ||
setTimeout(function () { | ||
stream.resume(); | ||
}, 1000); | ||
} | ||
return destroy; | ||
}; | ||
// | ||
// ### function stream (options) | ||
@@ -364,3 +294,8 @@ // #### @options {Object} Stream options for this instance. | ||
stream.destroy = this._tail(tail, function (line) { | ||
stream.destroy = common.tailFile(tail, function (err, line) { | ||
if(err){ | ||
return stream.emit('error',err); | ||
} | ||
try { | ||
@@ -367,0 +302,0 @@ stream.emit('data', line); |
var util = require('util'), | ||
winston = require('../../winston'), | ||
request = require('request'), | ||
Stream = require('stream').Stream; | ||
Stream = require('stream').Stream, | ||
Transport = require('./transport').Transport; | ||
@@ -13,2 +14,3 @@ // | ||
var Http = exports.Http = function (options) { | ||
Transport.call(this, options); | ||
options = options || {}; | ||
@@ -15,0 +17,0 @@ |
@@ -22,3 +22,3 @@ /* | ||
options = options || {}; | ||
this.level = options.level || 'info'; | ||
this.level = options.level === undefined ? 'info' : options.level; | ||
this.silent = options.silent || false; | ||
@@ -25,0 +25,0 @@ this.raw = options.raw || false; |
@@ -91,2 +91,5 @@ /* | ||
options.cert = this.ssl.cert; | ||
// Required for the test fixture SSL certificate to be considered valid. | ||
options.rejectUnauthorized = false; | ||
} | ||
@@ -105,2 +108,7 @@ | ||
// keep track of pending logs. | ||
res.on('data', function(data) { | ||
// Do nothing. We need to read the response, or we run into maxSockets | ||
// after 5 requests. | ||
}); | ||
self.emit('logged'); | ||
@@ -107,0 +115,0 @@ if (callback) callback(null, true); |
{ | ||
"name": "winston", | ||
"description": "A multi-transport async logging library for Node.js", | ||
"version": "0.7.2", | ||
"version": "0.7.3", | ||
"author": "Nodejitsu Inc. <info@nodejitsu.com>", | ||
@@ -36,3 +36,9 @@ "maintainers": [ | ||
"node": ">= 0.6.0" | ||
} | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://raw.github.com/flatiron/winston/master/LICENSE" | ||
} | ||
] | ||
} |
@@ -10,2 +10,8 @@ # winston [![Build Status](https://secure.travis-ci.org/flatiron/winston.png?branch=master)](http://travis-ci.org/flatiron/winston) | ||
## Installation | ||
```bash | ||
npm install winston | ||
``` | ||
## Usage | ||
@@ -162,3 +168,3 @@ There are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose. | ||
## Querying Logs | ||
Winston supports querying of logs with Loggly-like options. | ||
Winston supports querying of logs with Loggly-like options. [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional). | ||
Specifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`. | ||
@@ -169,3 +175,7 @@ | ||
from: new Date - 24 * 60 * 60 * 1000, | ||
until: new Date | ||
until: new Date, | ||
limit: 10, | ||
start: 0 | ||
order: 'desc', | ||
fields: ['message'] | ||
}; | ||
@@ -287,2 +297,5 @@ | ||
// | ||
logger.log('silly', "127.0.0.1 - there's no place like home"); | ||
logger.log('debug', "127.0.0.1 - there's no place like home"); | ||
logger.log('verbose', "127.0.0.1 - there's no place like home"); | ||
logger.log('info', "127.0.0.1 - there's no place like home"); | ||
@@ -302,3 +315,3 @@ logger.log('warn', "127.0.0.1 - there's no place like home"); | ||
Winston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file: | ||
Winston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file (note that the default level of a transport is `info`): | ||
@@ -568,12 +581,9 @@ ``` js | ||
// | ||
myObject.info('127.0.0.1 - there's no place like home'); | ||
myObject.info("127.0.0.1 - there's no place like home"); | ||
``` | ||
## Working with Transports | ||
Right now there are four transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__ | ||
1. __Console:__ Output to the terminal | ||
2. __Files:__ Append to a file | ||
3. __Loggly:__ Log to Logging-as-a-Service platform Loggly | ||
There are many transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__ | ||
### Console Transport | ||
@@ -584,3 +594,3 @@ ``` js | ||
The Console transport takes two simple options: | ||
The Console transport takes a few simple options: | ||
@@ -619,3 +629,3 @@ * __level:__ Level of messages that this transport should log (default 'info'). | ||
The Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required: | ||
The Loggly transport is based on [Nodejitsu's][3] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required: | ||
@@ -784,2 +794,24 @@ * __level:__ Level of messages that this transport should log. | ||
### Cassandra Transport | ||
[winston-cassandra][24] is a Cassandra transport: | ||
``` js | ||
var Cassandra = require('winston-cassandra').Cassandra; | ||
winston.add(Cassandra, options); | ||
``` | ||
The Cassandra transport connects to a cluster using the native protocol with the following options: | ||
* __level:__ Level of messages that this transport should log (default: `'info'`). | ||
* __table:__ The name of the Cassandra column family you want to store log messages in (default: `'logs'`). | ||
* __partitionBy:__ How you want the logs to be partitioned. Possible values `'hour'` and `'day'`(Default). | ||
* __consistency:__ The consistency of the insert query (default: `quorum`). | ||
In addition to the options accepted by the [Node.js Cassandra driver](https://github.com/jorgebay/node-cassandra-cql) Client. | ||
* __hosts:__ Cluster nodes that will handle the write requests: | ||
Array of strings containing the hosts, for example `['host1', 'host2']` (required). | ||
* __keyspace:__ The name of the keyspace that will contain the logs table (required). The keyspace should be already created in the cluster. | ||
### Adding Custom Transports | ||
@@ -853,3 +885,3 @@ Adding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston. | ||
[0]: https://github.com/isaacs/npm/blob/master/lib/utils/log.js | ||
[0]: https://github.com/npm/npmlog/blob/master/log.js | ||
[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter | ||
@@ -864,2 +896,11 @@ [2]: http://github.com/nodejitsu/require-analyzer | ||
[9]: http://vowsjs.org | ||
[10]: http://nodejs.org/api/util.html#util_util_format_format | ||
[10]: http://nodejs.org/api/util.html#util_util_format_format | ||
[14]: http://nodejs.org/api/stream.html#stream_class_stream_writable | ||
[16]: https://github.com/indexzero/winston-mongodb | ||
[17]: https://github.com/indexzero/winston-riak | ||
[18]: https://github.com/appsattic/winston-simpledb | ||
[19]: https://github.com/wavded/winston-mail | ||
[21]: https://github.com/jesseditson/winston-sns | ||
[22]: https://github.com/flite/winston-graylog2 | ||
[23]: https://github.com/kenperkins/winston-papertrail | ||
[24]: https://github.com/jorgebay/winston-cassandra |
@@ -86,9 +86,9 @@ /* | ||
topic: function (logger) { | ||
var that = this; | ||
var cb = this.callback; | ||
logger.profile('test1'); | ||
setTimeout(function () { | ||
logger.profile('test1', function (err, level, msg, meta) { | ||
that.callback(err, level, msg, meta, logger); | ||
cb(err, level, msg, meta, logger); | ||
}); | ||
}, 1000); | ||
}, 50); | ||
}, | ||
@@ -100,17 +100,39 @@ "should respond with the appropriate profile message": function (err, level, msg, meta, logger) { | ||
assert.isTrue(typeof logger.profilers['test'] === 'undefined'); | ||
} | ||
}, | ||
"when not passed a callback": { | ||
topic: function (logger) { | ||
var that = this; | ||
logger.profile('test2'); | ||
logger.once('logging', that.callback.bind(null, null)); | ||
setTimeout(function () { | ||
logger.profile('test2'); | ||
}, 1000); | ||
}, | ||
"should respond with the appropriate profile message": function (err, transport, level, msg, meta) { | ||
assert.isNull(err); | ||
assert.equal(level, 'info'); | ||
assert.match(meta.duration, /(\d+)ms/); | ||
"when passed some metadata": { | ||
topic: function () { | ||
var logger = arguments[arguments.length - 1]; | ||
var cb = this.callback.bind(null, null); | ||
logger.profile('test3'); | ||
setTimeout(function () { | ||
logger.once('logging', cb); | ||
logger.profile('test3', { | ||
some: 'data' | ||
}); | ||
}, 50); | ||
}, | ||
"should respond with the right metadata": function (err, transport, level, msg, meta) { | ||
assert.equal(msg, 'test3'); | ||
assert.isNull(err); | ||
assert.equal(level, 'info'); | ||
assert.match(meta.duration, /(\d+)ms/); | ||
assert.equal(meta.some, 'data'); | ||
}, | ||
"when not passed a callback": { | ||
topic: function () { | ||
var logger = arguments[arguments.length - 1]; | ||
var cb = this.callback.bind(null, null); | ||
logger.profile('test2'); | ||
setTimeout(function () { | ||
logger.once('logging', cb); | ||
logger.profile('test2'); | ||
}, 50); | ||
}, | ||
"should respond with the appropriate profile message": function (err, transport, level, msg, meta) { | ||
assert.isNull(err); | ||
assert.equal(msg, 'test2'); | ||
assert.equal(level, 'info'); | ||
assert.match(meta.duration, /(\d+)ms/); | ||
} | ||
} | ||
} | ||
@@ -152,3 +174,3 @@ } | ||
assert.isNumber(duration); | ||
assert.isTrue(duration > 900 && duration < 1100); | ||
assert.isTrue(duration >= 50 && duration < 100); | ||
} | ||
@@ -278,3 +300,3 @@ } | ||
assert.strictEqual(msg, util.format('test message %%')); | ||
assert.deepEqual(meta, {number: 123}); | ||
assert.deepEqual(meta, {number: 123}); | ||
}, | ||
@@ -281,0 +303,0 @@ }, |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
201182
896
10
4718
15