UNPKG

2.25 kBJavaScriptView Raw
1const Transport = require('winston-transport')
2const Batcher = require('./src/batcher')
3const { MESSAGE } = require('triple-beam')
4
5/**
6 * A Winston transport for Grafana Loki.
7 *
8 * @class LokiTransport
9 * @extends {Transport}
10 */
11class LokiTransport extends Transport {
12 /**
13 * Creates an instance of LokiTransport.
14 * @param {*} options
15 * @memberof LokiTransport
16 */
17 constructor (options) {
18 super(options)
19
20 // Pass all the given options to batcher
21 this.batcher = new Batcher({
22 host: options.host,
23 interval: options.interval,
24 json: options.json,
25 batching: options.batching !== undefined ? options.batching : true,
26 clearOnError: options.clearOnError,
27 replaceOnError: options.replaceOnError,
28 replaceTimestamp: options.replaceTimestamp
29 })
30
31 this.useCustomFormat = options.format !== undefined
32 this.labels = options.labels
33 }
34
35 /**
36 * An overwrite of winston-transport's log(),
37 * which the Winston logging library uses
38 * when pushing logs to a transport.
39 *
40 * @param {*} info
41 * @param {*} callback
42 * @memberof LokiTransport
43 */
44 log (info, callback) {
45 // Immediately tell Winston that this transport has received the log.
46 setImmediate(() => {
47 this.emit('logged', info)
48 })
49
50 // Deconstruct the log
51 const { label, timestamp, level, message, ...rest } = info
52
53 // build custom labels if provided
54 let labels
55 if (this.labels) {
56 labels = `{level="${level}"`
57 for (let key in this.labels) {
58 labels += `,${key}="${this.labels[key]}"`
59 }
60 labels += '}'
61 } else {
62 labels = `{job="${label}", level="${level}"}`
63 }
64
65 // follow the format provided
66 const line = this.useCustomFormat ? info[MESSAGE] : `${message} ${
67 rest && Object.keys(rest).length > 0 ? JSON.stringify(rest) : ''
68 }`
69
70 // Construct the log to fit Grafana Loki's accepted format
71 const logEntry = {
72 labels: labels,
73 entries: [
74 {
75 ts: timestamp || Date.now(),
76 line
77 }
78 ]
79 }
80
81 // Pushes the log to the batcher
82 this.batcher.pushLogEntry(logEntry)
83
84 // Trigger the optional callback
85 callback()
86 }
87}
88
89module.exports = LokiTransport