-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathindex.js
102 lines (82 loc) · 2.92 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// index.js - Main bunyan-raven stream export
module.exports = (function(undefined) {
var util = require('util')
, assert = require('assert')
, Writable = require('stream').Writable;
var nameFromLevel = [];
nameFromLevel[10] = 'trace';
nameFromLevel[20] = 'debug';
nameFromLevel[30] = 'info';
nameFromLevel[40] = 'warning';
nameFromLevel[50] = 'error';
nameFromLevel[60] = 'fatal';
function RavenStream(client) {
assert(client != null, "Please provide a raven client.");
Writable.call(this, { objectMode: true });
this.client = client;
}
util.inherits(RavenStream, Writable);
RavenStream.prototype.client = null;
RavenStream.prototype._write = function(record, encoding, callback) {
// mangle the error message a bit to make sure we have the log record's message
// showing up on sentry as well or at least also logs the message itself if no error
// object are provided.
var err = record.err;
// Get level value string, since bunyan uses numbers for levels
if (record.level && typeof record.level === 'number') {
record.level = nameFromLevel[record.level];
}
var options = this._gatherRavenMetaData(record);
if (!err) {
this.client.captureMessage(record.msg, options);
return callback(null);
}
if (record.msg) {
err.message = record.msg + " (" + err.message + ")";
}
if (err instanceof Error) {
this.client.captureException(err, options);
return callback(null);
}
// Bunyan's serializer kicks in in some cases which requires reconverting the object to an error
var convertedError = new Error(err.message);
convertedError.name = err.name;
convertedError.code = err.code;
convertedError.signal = err.signal;
convertedError.stack = err.stack;
this.client.captureException(convertedError, options);
return callback(null);
};
RavenStream.prototype._gatherRavenMetaData = function(record) {
var options = {tags: {}, extra: {}};
// Level doesn't go in tags or extra
options.level = record.level;
// Add tags
var tags = ['name', 'hostname', 'pid'];
tags.forEach(function(tag) { options.tags[tag] = record[tag]; });
// Add 'extra' meta-data from record
var skip = ['msg', 'time', 'v', 'err', 'level'];
for (var key in record) {
if (tags.indexOf(key) != -1) continue;
if (skip.indexOf(key) != -1) continue;
options.extra[key] = JSON.stringify(record[key], safeCycles());
}
return options;
};
// A JSON stringifier that handles cycles safely.
// Usage: JSON.stringify(obj, safeCycles())
function safeCycles() {
var seen = [];
return function (key, val) {
if (!val || typeof (val) !== 'object') {
return val;
}
if (seen.indexOf(val) !== -1) {
return '[Circular]';
}
seen.push(val);
return val;
};
}
return RavenStream;
})();