Skip to content

Commit

Permalink
Merge pull request #53 from loggly/3.x
Browse files Browse the repository at this point in the history
Use winston 3.x by default
  • Loading branch information
elfilip committed Feb 12, 2019
2 parents 2256a5b + 4773a55 commit 4a613f9
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 41 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Please note that the documentation below is for `winston-loggly-bulk@2.x`. [Read
// Requiring `winston-loggly-bulk` will expose
// `winston.transports.Loggly`
//
require('winston-loggly-bulk');
var {Loggly} = require('winston-loggly-bulk');

winston.add(winston.transports.Loggly, options);
winston.add(new Loggly({options}));
```

The Loggly transport is based on [Nodejitsu's][2] [node-loggly][3] implementation of the [Loggly][0] API. If you haven't heard of Loggly before, you should probably read their [value proposition][4]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:
Expand All @@ -45,6 +45,22 @@ The Loggly transport is based on [Nodejitsu's][2] [node-loggly][3] implementatio

*Metadata:* Logged in suggested [Loggly format][5]

## Sample Working Code Snippet

``` js
var winston = require('winston');
var {Loggly} = require('winston-loggly-bulk');

winston.add(new Loggly({
token: "TOKEN",
subdomain: "SUBDOMAIN",
tags: ["Winston-NodeJS"],
json: true
}));

winston.log('info', "Hello World from Node.js!");
```

## Buffer Support

This library has buffer support during temporary network outage. User can configure size of buffer (no. of logs to be stored during network outage).
Expand All @@ -65,11 +81,11 @@ Our library uses ajax requests to send logs to Loggly, and as ajax requests take
Here is an example of how to use the method:

``` js
var winston = require('winston'),
winlog = require('winston-loggly-bulk');
var winston = require('winston');
var {flushLogsAndExit} = require('winston-loggly-bulk');

winston.log("info", "hello World");
winlog.flushLogsAndExit();
winston.log("info", "Hello World from Node.js!");
flushLogsAndExit();

```

Expand Down
55 changes: 33 additions & 22 deletions lib/winston-loggly.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
*
*/

var events = require('events'),
var clone = require('clone'),
loggly = require('node-loggly-bulk'),
util = require('util'),
winston = require('winston'),
Transport = require('winston-transport'),
Stream = require('stream').Stream;

//
Expand All @@ -35,7 +36,7 @@ var Loggly = exports.Loggly = function (options) {
options.token = options.inputToken;
}

winston.Transport.call(this, options);
Transport.call(this, options);
if (!options.subdomain) {
throw new Error('Loggly Subdomain is required');
}
Expand All @@ -52,7 +53,7 @@ var Loggly = exports.Loggly = function (options) {
this.client = loggly.createClient({
subdomain: options.subdomain,
auth: options.auth || null,
json: options.json || false,
json: options.json || false, //TODO: should be false
proxy: options.proxy || null,
token: options.token,
tags: tags,
Expand Down Expand Up @@ -80,7 +81,7 @@ var flushLogsAndExit = exports.flushLogsAndExit = function () {
//
// Inherit from `winston.Transport`.
//
util.inherits(Loggly, winston.Transport);
util.inherits(Loggly, Transport);

//
// Define a getter so that `winston.transports.Loggly`
Expand All @@ -94,6 +95,16 @@ winston.transports.flushLogsAndExit = flushLogsAndExit;
//
Loggly.prototype.name = 'loggly';

const validateMetadata = (meta) => {
if (meta == null) {
return {};
} else if (typeof meta !== 'object') {
return { metadata: meta };
} else {
return clone(meta);
}
}

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
Expand All @@ -102,47 +113,47 @@ Loggly.prototype.name = 'loggly';
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Loggly.prototype.log = function (level, msg, meta, callback) {
Loggly.prototype.log = function (meta, callback) {

const message = validateMetadata(meta);

if (this.silent) {
return callback(null, true);
}

if (this.timestamp && (!meta || !meta.timestamp)) {
meta = meta || {};
meta.timestamp = (new Date()).toISOString();
if (this.timestamp && !message.timestamp) {
message.timestamp = (new Date()).toISOString();
}

if (this.stripColors) {
msg = ('' + msg).replace(code, '');
message.message = ('' + message.message).replace(code, '');
}

var message = winston.clone(meta || {}),
self = this;

message.level = level;
message.message = msg || message.message;
const self = this;

//
// Helper function for responded to logging.
//
function logged(err) {
self.emit('logged');
callback(err, true);
}

return meta && meta.tags
result = (meta && meta.tags)
? this.client.log(message, meta.tags, logged)
: this.client.log(message, logged);

callback();
return result;
};

//
// ### function stream (options)
// #### @options {Object} Set stream options
// Returns a log stream.
//
Loggly.prototype.stream = function(options) {
Loggly.prototype.stream = function(maybeOptions) {
var self = this,
options = options || {},
options = maybeOptions || {},
stream = new Stream,
last,
start = options.start,
Expand Down Expand Up @@ -174,15 +185,15 @@ Loggly.prototype.stream = function(options) {
return setTimeout(check, 2000);
}

var result = res[res.length-1];
var result = results[results.length-1];
if (result && result.timestamp) {
if (last == null) {
last = result.timestamp;
return;
}
last = result.timestamp;
} else {
return func();
return;
}

results.forEach(function(log) {
Expand Down Expand Up @@ -235,10 +246,10 @@ Loggly.prototype.formatQuery = function (query) {
// ### function formatResults (results, options)
// #### @results {Object|Array} Results returned from `.query`.
// #### @options {Object} **Optional** Formatting options
// Formats the specified `results` with the given `options` accordinging
// Formats the specified `results` with the given `options` according
// to the implementation of this transport.
//
Loggly.prototype.formatResults = function (results, options) {
Loggly.prototype.formatResults = function (results, _options) {
return results;
};

Expand Down
22 changes: 17 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "winston-loggly-bulk",
"version": "2.0.3",
"version": "3.0.1",
"description": "A Loggly transport for winston",
"author": "Loggly <opensource@loggly.com>",
"contributors": [
Expand All @@ -19,15 +19,27 @@
"type": "git",
"url": "https://github.com/loggly/winston-loggly-bulk.git"
},
"keywords": ["loggly", "logging", "sysadmin", "tools", "winston"],
"keywords": [
"loggly",
"logging",
"sysadmin",
"tools",
"winston"
],
"dependencies": {
"node-loggly-bulk": "^2.0.1",
"winston": "^2.3.1"
"clone": "^2.1.1",
"winston": "^3.0",
"winston-transport": "^4.2.0"
},
"devDependencies": {
"vows": "0.8.0"
},
"main": "./lib/winston-loggly",
"scripts": { "test": "vows --spec" },
"engines": { "node": ">= 0.8.0" }
"scripts": {
"test": "vows --spec"
},
"engines": {
"node": ">= 6.4.0"
}
}
79 changes: 79 additions & 0 deletions test/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const winston = require('winston');
module.exports.testLevels = function (transport, assertMsg, assertFn) {
var tests = {};
const levels = winston.config.npm.levels;

Object.keys(levels).forEach(function (level) {
var test = {
topic: function () {
transport.log(level, 'test message', {}, this.callback.bind(this, null));
}
};

test[assertMsg] = assertFn;
tests['with the ' + level + ' level'] = test;
});

var metadatatest = {
topic: function () {
transport.log('info', 'test message', { metadata: true }, this.callback.bind(this, null));
}
};

metadatatest[assertMsg] = assertFn;
tests['when passed metadata'] = metadatatest;

var primmetadatatest = {
topic: function () {
transport.log('info', 'test message', 'metadata', this.callback.bind(this, null));
}
};

primmetadatatest[assertMsg] = assertFn;
tests['when passed primitive metadata'] = primmetadatatest;

var nummetadatatest = {
topic: function () {
transport.log('info', 'test message', 123456789, this.callback.bind(this, null));
}
};

nummetadatatest[assertMsg] = assertFn;
tests['when passed numeric metadata'] = nummetadatatest;

// circular references aren't supportded by regular JSON, and it's not supported
// by node-loggly-bulk. I'm omitting it for now. If it wants to be fixed, then
// node-loggly-bulk needs an update.
/*
var circmetadata = { };
circmetadata['metadata'] = circmetadata;
var circmetadatatest = {
topic: function () {
transport.log('info', 'circular message', circmetadata, this.callback.bind(this, null));
}
};
circmetadatatest[assertMsg] = assertFn;
tests['when passed circular metadata'] = circmetadatatest;
var circerror = new Error("message!");
var foo = {};
var circerrordatatest;
foo.bar = foo;
circerror.foo = foo;
circerror.stack = 'Some stacktrace';
circerrordatatest = {
topic: function () {
transport.log('info', 'circular error', circerror, this.callback.bind(this, null));
}
};
circerrordatatest[assertMsg] = assertFn;
tests['when passed circular error as metadata'] = circerrordatatest;
*/

return tests;
};
17 changes: 9 additions & 8 deletions test/winston-loggly-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
*
*/

var path = require('path'),
vows = require('vows'),
var vows = require('vows'),
assert = require('assert'),
winston = require('winston'),
helpers = require('winston/test/helpers'),
helpers = require('./helpers.js'),
Loggly = require('../lib/winston-loggly').Loggly;

var tokenTransport,
Expand All @@ -20,8 +18,8 @@ try {
config = require('./config');
}
catch (ex) {
console.log('Error reading test/config.json.')
console.log('Are you sure it exists?\n');
console.error('Error reading test/config.json.')
console.error('Are you sure it exists?\n');
console.dir(ex);
process.exit(1);
}
Expand All @@ -31,6 +29,9 @@ tokenTransport = new (Loggly)({
token: config.transports.loggly.token
});

tokenTransport.log('warning', 'test message', {}, (_err, _res) => {
})

function assertLoggly(transport) {
assert.instanceOf(transport, Loggly);
assert.isFunction(transport.log);
Expand All @@ -42,10 +43,10 @@ vows.describe('winston-loggly').addBatch({
"should have the proper methods defined": function () {
assertLoggly(tokenTransport);
},
"the log() method": helpers.testNpmLevels(tokenTransport, "should log messages to loggly", function (ign, err, logged) {
"the log() method": helpers.testLevels(tokenTransport, "should log messages to loggly", function (ign, err, logged) {
assert.isNull(err);
assert.isTrue(logged);
})
}
}
}).export(module);
}).export(module);

0 comments on commit 4a613f9

Please sign in to comment.