Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use winston 3.x by default #53

Merged
merged 17 commits into from Feb 12, 2019
@@ -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:
@@ -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).
@@ -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();
```

55 lib/winston-loggly.js 100644 → 100755
@@ -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;

//
@@ -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');
}
@@ -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,
@@ -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`
@@ -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.
@@ -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,
@@ -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) {
@@ -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;
};

@@ -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": [
@@ -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"
}
}
@@ -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;
};
@@ -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,
@@ -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);
}
@@ -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);
@@ -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);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.