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

feature: winston 3.x compatibility #48

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -1,4 +1,7 @@
.idea/
.DS_Store

test/config.json

node_modules
npm-debug.log
.DS_Store
@@ -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();
```

174 lib/winston-loggly.js 100644 → 100755
@@ -6,11 +6,12 @@
*
*/

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

//
// Remark: This should be at a higher level.
@@ -35,15 +36,15 @@ 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');
}
else if (!options || !options.token) {
throw new Error('Loggly Customer token is required.');
}

this.name = 'loggly';
this.name = 'loggly';
var tags = options.tags || options.tag || options.id;
if (tags && !Array.isArray(tags)) {
tags = [tags];
@@ -57,11 +58,11 @@ var Loggly = exports.Loggly = function (options) {
token: options.token,
tags: tags,
isBulk: options.isBulk || false,
bufferOptions: options.bufferOptions || {size: 500, retriesInMilliSeconds: 30 * 1000},
bufferOptions: options.bufferOptions || { size: 500, retriesInMilliSeconds: 30 * 1000 },
networkErrorsOnConsole: options.networkErrorsOnConsole || false
});

this.timestamp = options.timestamp === false ? false : true;
this.timestamp = options.timestamp !== false;
this.stripColors = options.stripColors || false;
};

@@ -70,17 +71,17 @@ var Loggly = exports.Loggly = function (options) {
// 10 seconds.
//
var flushLogsAndExit = exports.flushLogsAndExit = function () {
if (timerFunctionForProcessExit === null) {
timerFunctionForProcessExit = setInterval(function () {
process.exit();
},10000);
}
}
if (timerFunctionForProcessExit === null) {
timerFunctionForProcessExit = setInterval(function () {
process.exit();
}, 10000);
}
};

//
// Inherit from `winston.Transport`.
//
util.inherits(Loggly, winston.Transport);
util.inherits(Loggly, Transport);

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

const validateMetadata = (meta) => {
if (meta == null) {
return {};
}

if (typeof meta !== 'object') {
return { metadata: meta };
}

const symbols = Object.getOwnPropertySymbols(meta);
const key = symbols.find(symbol => String(symbol) === 'Symbol(message)');
if (key !== undefined) {
return clone(meta[key]);
}

return clone(meta);
};

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// ### function log (metadata, callback)
// #### @metadata {Object} Information to attach.
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
// Core logging method exposed to Winston.
//
Loggly.prototype.log = function (level, msg, meta, callback) {
Loggly.prototype.log = function (metadata, callback) {

const data = validateMetadata(metadata);

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

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

if (this.stripColors) {
msg = ('' + msg).replace(code, '');
data.message = ('' + data.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.
@@ -130,23 +145,23 @@ Loggly.prototype.log = function (level, msg, meta, callback) {
callback(err, true);
}

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

//
// ### 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 || {},
stream = new Stream,
last,
start = options.start,
row = 0;
options = maybeOptions || {},
stream = new Stream,
last,
start = options.start,
row = 0;

if (start === -1) {
start = null;
@@ -156,7 +171,7 @@ Loggly.prototype.stream = function(options) {
last = new Date(0).toISOString();
}

stream.destroy = function() {
stream.destroy = function () {
this.destroyed = true;
};

@@ -166,26 +181,26 @@ Loggly.prototype.stream = function(options) {
self.query({
from: last || 'NOW-1DAY',
until: 'NOW'
}, function(err, results) {
}, function (err, results) {
if (stream.destroyed) return;

if (err) {
stream.emit('error', err);
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) {
results.forEach(function (log) {
if (start == null || row > start) {
stream.emit('log', log);
}
@@ -208,9 +223,9 @@ Loggly.prototype.stream = function(options) {

Loggly.prototype.query = function (options, callback) {
var self = this,
context = this.extractContext(options);
options = this.loglify(options);
options = this.extend(options, context);
context = this.extractContext(options);
options = this.loglify(options);
options = this.extend(options, context);

this.client
.search(options)
@@ -235,10 +250,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;
};

@@ -252,15 +267,14 @@ Loggly.prototype.formatResults = function (results, options) {
Loggly.prototype.extractContext = function (obj) {
var context = {};


['start',
'from',
'until',
'order',
'callback',
'size',
'format',
'fields'].forEach(function (key) {
['start',
'from',
'until',
'order',
'callback',
'size',
'format',
'fields'].forEach(function (key) {
if (obj[key]) {
context[key] = obj[key];
delete obj[key];
@@ -271,14 +285,13 @@ Loggly.prototype.extractContext = function (obj) {
context.from = context.from.toISOString();
context.until = context.until.toISOString();

context.from = context.from || '-1d';
context.from = context.from || '-1d';
context.until = context.until || 'now';
context.size = context.size || 50;
context.size = context.size || 50;

return context;
};


//
// ### function loglify (obj)
// #### @obj {Object} Search query to convert into an `AND` loggly query.
@@ -291,26 +304,25 @@ Loggly.prototype.loglify = function (obj) {

Object.keys(obj).forEach(function (key) {
if (key !== 'query' &&
key !== 'fields' &&
key !== 'start' &&
key !== 'rows' &&
key !== 'limit' &&
key !== 'from' &&
key !== 'until')
{
if (key == 'tag') {
opts.push(key + ':' + obj[key]);
}
else {
opts.push('json.' + key + ':' + obj[key]);
}
key !== 'fields' &&
key !== 'start' &&
key !== 'rows' &&
key !== 'limit' &&
key !== 'from' &&
key !== 'until') {
if (key == 'tag') {
opts.push(key + ':' + obj[key]);
}
else {
opts.push('json.' + key + ':' + obj[key]);
}
}
});

if (obj.query) {
opts.unshift(obj.query);
}
return {'query' : opts.join(' AND ')}
return { 'query': opts.join(' AND ') };
};

//
@@ -327,8 +339,8 @@ Loggly.prototype.sanitizeLogs = function (logs) {
return logs;
};

Loggly.prototype.extend = function(destination,source) {
for (var property in source)
destination[property] = source[property];
return destination;
}
Loggly.prototype.extend = function (destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
};
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.