Skip to content

Commit 36a06e2

Browse files
committed
feat: logs processing speed increased
1 parent 215a6bb commit 36a06e2

File tree

13 files changed

+5221
-3509
lines changed

13 files changed

+5221
-3509
lines changed

bench/bench.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
time node producer.js 1000000 | node --trace-uncaught ../index.js log -c ../__mocks__/custom-schema.json -v

bench/producer.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'strict'
2+
3+
for (let i = 0; i < process.argv.slice(2)[0]; i++) {
4+
process.stdout.write('{"level":30,"time":1531171074631,"msg":"hello world","nested":{"mock":666},"test2":"red","pid":657,"hostname":"box","name":"app","v":1}' + '\n')
5+
}

lib/gelf-transformer.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
const fastJsonParse = require('fast-json-parse')
2-
const pipeline = require('./pipeline')
3-
const pump = require('pump')
2+
const processLogs = require('./process-logs')
3+
const streamLogs = require('./stream-logs')
44
const split = require('split2')
5+
const { pipeline } = require('readable-stream')
56

67
module.exports = function (opts) {
7-
const pipe = pipeline(opts)
8-
pump(process.stdin, split(fastJsonParse), pipe)
8+
pipeline(
9+
process.stdin,
10+
split(fastJsonParse),
11+
processLogs(opts),
12+
...streamLogs(opts)
13+
)
914
process.on('SIGINT', function () { process.exit(0) })
1015
}

lib/pipeline.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

lib/process-logs.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const transformer = require('./transformer')
2+
const { stringify } = require('./utils')
3+
const { Transform } = require('readable-stream')
4+
5+
module.exports = function processLogs (opts) {
6+
const transform = transformer(opts)
7+
const stringified = stringify(opts)
8+
9+
return new Transform({
10+
writableObjectMode: true,
11+
decodeStrings: false,
12+
transform: function (data, enc, cb) {
13+
if (data.value !== null) {
14+
this.push(stringified(transform(data.value)))
15+
}
16+
cb()
17+
},
18+
construct (callback) {
19+
this.data = ''
20+
callback()
21+
},
22+
flush (callback) {
23+
try {
24+
this.push('')
25+
} catch (err) {
26+
callback(err)
27+
}
28+
}
29+
})
30+
}

lib/stream-logs.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const Transport = require('./transport')
2+
const { Transform } = require('readable-stream')
3+
4+
module.exports = function processLogs (opts) {
5+
const streams = []
6+
if (opts.verbose) {
7+
streams.push(getVerbose())
8+
}
9+
if (opts.transportToGraylog) {
10+
streams.push(getTransport(opts))
11+
}
12+
return streams
13+
}
14+
15+
function getVerbose () {
16+
return new Transform({
17+
writableObjectMode: true,
18+
decodeStrings: false,
19+
transform: function (data, enc, cb) {
20+
setImmediate(function () { process.stdout.write(data + '\n') })
21+
cb()
22+
}
23+
})
24+
}
25+
26+
function getTransport (opts) {
27+
console.log('transport is prepared')
28+
const transport = new Transport(opts)
29+
return new Transform({
30+
writableObjectMode: true,
31+
decodeStrings: false,
32+
transform: function (data, enc, cb) {
33+
setImmediate(function () {
34+
transport.emit('log', data)
35+
})
36+
cb()
37+
}
38+
})
39+
}

lib/transformer/custom-gelf.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
const get = require('lodash.get')
22

3-
module.exports = function (data, customSchema) {
4-
return Object.entries(customSchema.properties)
5-
.reduce((acc, entry) => {
6-
const sourcePath = entry[1].source ? entry[1].source : entry[0]
7-
acc[entry[0]] = get(data, sourcePath, undefined)
8-
return acc
9-
}, {})
3+
module.exports = function customGelf (properties) {
4+
return function (data) {
5+
const _data = {}
6+
for (const property in properties) {
7+
_data[property] = get(data, properties[property].source, data[property])
8+
}
9+
return _data
10+
}
1011
}

lib/transformer/index.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ const buildCustomGelf = require('./custom-gelf')
33

44
module.exports = function (opts) {
55
const sanitizeData = setMessageField(opts)
6-
7-
return function (data) {
8-
return {
9-
...buildStandardGelf(sanitizeData(data)),
10-
...opts.customSchema ? buildCustomGelf(data, opts.customSchema) : {}
11-
}
6+
const customProperties = opts.customSchema ? opts.customSchema.properties : {}
7+
const build = buildCustomGelf(customProperties)
8+
return function (value) {
9+
return Object.assign(buildStandardGelf(sanitizeData(value)), build(value))
1210
}
1311
}
1412

1513
function setMessageField (opts) {
14+
const _field = opts.messageField
1615
return function (data) {
17-
data.msg = data[opts.messageField] ? data[opts.messageField] : 'No msg property found or msg is empty'
16+
data.msg = data[_field] !== undefined ? data[_field] : 'No msg property found or msg is empty'
1817
return data
1918
}
2019
}

lib/transport.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@ const EventEmitter = require('events').EventEmitter
77
const pick = require('lodash.pick')
88
const utils = require('./utils')
99

10-
var Transport = function (opts) {
10+
const Transport = function (opts) {
1111
const self = this
1212

1313
self.config = pick(opts, ['host', 'port', 'maxChunkSize'])
1414
self.stringify = utils.stringify(opts)
1515

16-
self.on('log', function (gelf) {
17-
const msg = self.stringify(gelf)
18-
16+
self.on('log', function (msg) {
1917
self.compress(msg, function (buffer) {
2018
self.processMessage(buffer)
2119
})
@@ -39,7 +37,7 @@ Transport.prototype.prepareDatagrams = function (chunks, cb) {
3937
const length = chunks.length
4038

4139
const createDatagramArray = function (msgId) {
42-
for (var i = 0; i < chunks.length; i++) {
40+
for (let i = 0; i < chunks.length; i++) {
4341
datagrams[i] = Buffer.from(gelfBytes.concat(msgId, i, length, chunks[i]))
4442
}
4543

@@ -98,7 +96,7 @@ Transport.prototype.processMessage = function (msg) {
9896
Transport.prototype.sendMultipleMessages = function (datagrams) {
9997
const self = this
10098

101-
for (var i = 0; i < datagrams.length; i++) {
99+
for (let i = 0; i < datagrams.length; i++) {
102100
self.sendMessage(datagrams[i])
103101
}
104102
}

lib/utils/index.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,15 @@ const mapPinoToSyslogLevel = {
1111
50: syslogLevel.error,
1212
60: syslogLevel.critical
1313
}
14-
function pinoLevelToSyslogLevel (level) {
14+
15+
exports.pinoLevelToSyslogLevel = function pinoLevelToSyslogLevel (level) {
1516
return mapPinoToSyslogLevel[level] || syslogLevel.critical
1617
}
1718

18-
const stringify = function (opts) {
19-
const schema = standardSchema
19+
exports.stringify = function stringify (opts) {
2020
if (opts.customSchema) {
21-
schema.properties = Object.assign(schema.properties, opts.customSchema.properties)
21+
Object.assign(standardSchema.properties, opts.customSchema.properties)
2222
}
2323

24-
return fastJsonStringify(schema)
25-
}
26-
27-
module.exports = {
28-
pinoLevelToSyslogLevel,
29-
stringify
24+
return fastJsonStringify(standardSchema)
3025
}

0 commit comments

Comments
 (0)