forked from GUI/bunyan-rollbar
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
99 lines (85 loc) · 3.31 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
'use strict'
var _ = require('lodash')
// Rollbar uses slightly different error levels than Bunyan.
// https://rollbar.com/docs/custom-log-messages/
var levelMapping = {
10: 'debug',
20: 'debug',
30: 'info',
40: 'warning',
50: 'error',
60: 'critical'
}
var BunyanRollbar = function () {
this.initialize.apply(this, arguments)
}
_.extend(BunyanRollbar.prototype, {
initialize: function (rollbar) {
this.rollbar = rollbar
},
write: function (record) {
if (!_.isObject(record)) {
throw new Error('bunyan-rollbar requires a raw stream. Please define the type as raw when setting up the bunyan-rollbar stream.')
}
// If Bunyan has serialized the Error object, try to retrieve the real
// error object to send to Rollbar, so it can process the error object
// itself. This requires use of the customized
// bunyanRollbar.stdSerializers.
var error
if (record.err && record.err._bunyanRollbarOriginalObject && (record.err._bunyanRollbarOriginalObject instanceof Error)) {
error = record.err._bunyanRollbarOriginalObject
} else if (record.err && (record.err instanceof Error)) {
error = record.err
}
// Similar to above, but for the request object. Try to retrieve the real
// request object to send to Rollbar.
var request
if (record.req && record.req._bunyanRollbarOriginalObject && record.req._bunyanRollbarOriginalObject.connection) {
request = record.req._bunyanRollbarOriginalObject
} else if (record.req && record.req.connection) {
request = record.req
}
var payload = {
level: levelMapping[record.level] || 'error',
custom: record
}
// If we're sending Rollbar the real error or request objects, remove those
// references from the custom playload so there's not duplicate data.
if (error) {
payload.custom = _.omit(payload.custom, 'err')
}
if (request) {
payload.custom = _.omit(payload.custom, 'req')
}
// Rollbar expects errors and general messages to be passed differently.
if (error) {
this.rollbar.handleErrorWithPayloadData(error, payload, request)
} else {
payload.custom = _.omit(payload.custom, 'msg')
this.rollbar.reportMessageWithPayloadData(record.msg, payload, request)
}
}
})
// Define our own copy of the bunyan.stdSerializers but patch the 'err' and
// 'req' serializers so we can maintain access to the original error or request
// objects for sending to Rollbar (since Rollbar's API has it's own custom
// handling of those two types of objects).
var patchSerializer = function (originalSerializer) {
return function (object) {
// Call the original serializer.
var serialized = originalSerializer(object)
// If the original serializer did serialize this object, store the original
// object on a special '_bunyanRollbarOriginalObject' property of the
// serialized object. Using defineProperty should ensure that this object
// is available for us to access, but won't show up in the JSON
// serialization of the serialized data.
if (serialized !== object && _.isPlainObject(serialized)) {
Object.defineProperty(serialized, '_bunyanRollbarOriginalObject', {
value: object
})
}
return serialized
}
}
module.exports.patchSerializer = patchSerializer
module.exports.Stream = BunyanRollbar