Skip to content

Commit 39523fd

Browse files
committed
chore(tracer): add option to configure sampler
1 parent 488da05 commit 39523fd

8 files changed

Lines changed: 89 additions & 17 deletions

File tree

lib/agent/tracer/collector.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var uuid = require('node-uuid')
77
var assign = require('lodash.assign')
88
var levels = require('./severity')
99
var some = require('lodash.some')
10-
var ReservoirSampler = require('./reservoirSampler')
10+
var reservoirSampler = require('./samplers/reservoir')
1111

1212
var EVENT_TYPE = {
1313
CLIENT_SEND: 'cs',
@@ -39,13 +39,13 @@ function Collector (options) {
3939
this.serviceKey = options.serviceKey
4040
this.mustCollectSeverity = levels.ERROR
4141
this.defaultSeverity = levels.INFO
42-
this.samplerLimit = options.samplerLimit || 100
42+
this.samplerLimit = options.samplerLimit
4343

4444
// init required variables
4545
this._noStack = options.noStack
4646
this._eventTtl = options.eventTtl || 1
4747
this._eventBuffers = { }
48-
this._sampler = new ReservoirSampler(this.samplerLimit)
48+
this._sampler = reservoirSampler.create(this.samplerLimit)
4949
}
5050

5151
Collector.prototype.LEVELS = levels

lib/agent/tracer/collector.spec.js

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,8 @@ describe('Collector', function () {
746746
})
747747
})
748748

749-
describe('Sampling', function () {
750-
it('happens when there is a big amount of data #1', function () {
749+
describe('Sampler', function () {
750+
it('samples big amount of data #1', function () {
751751
this.sandbox.stub(microtime, 'now', function () {
752752
return 2
753753
})
@@ -780,7 +780,7 @@ describe('Collector', function () {
780780
expect(length).to.be.above(0)
781781
})
782782

783-
it('happens when there is a big amount of data #2', function () {
783+
it('happens big amount of data #2', function () {
784784
this.sandbox.stub(microtime, 'now', function () {
785785
return 2
786786
})
@@ -802,5 +802,30 @@ describe('Collector', function () {
802802
expect(length).to.be.below(50)
803803
expect(length).to.be.above(0)
804804
})
805+
806+
it('is emptied', function () {
807+
this.sandbox.stub(microtime, 'now', function () {
808+
return 2
809+
})
810+
var tracer = new Collector(assign({ samplerLimit: 10 }, options))
811+
function report () {
812+
var cs = {
813+
payload: { severity: tracer.mustCollectSeverity },
814+
briefcase: { }
815+
}
816+
var csResult = tracer.clientSend(cs.payload, cs.briefcase)
817+
818+
var cr = {
819+
payload: { }
820+
}
821+
tracer.clientRecv(cr.payload, {}, csResult.briefcase)
822+
}
823+
for (var i = 0; i < 50; ++i) { report() }
824+
var length = tracer.collect().length
825+
expect(length).to.be.below(50)
826+
expect(length).to.be.above(0)
827+
828+
expect(tracer._sampler.size()).to.equal(0)
829+
})
805830
})
806831
})

lib/agent/tracer/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ function Tracer (options) {
1818
// init required variables
1919
this.collector = new Collector({
2020
eventTtl: 3,
21-
noStack: options.config.disableStackTrace
21+
noStack: options.config.disableStackTrace,
22+
samplerLimit: options.config.samplerLimit
2223
})
2324
this._api = options.collectorApi
2425

Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

2-
function Reservoir (limit) {
3-
this.MAX_ITEMS = limit || 10
2+
function ReservoirSampler (limit) {
3+
this.MAX_ITEMS = limit || Infinity
44

55
this._itemsSeen = 0
66
this._data = []
77
}
88

9-
Reservoir.prototype.add = function (item) {
9+
ReservoirSampler.prototype.add = function (item) {
1010
var inserted = true
1111
if (this._itemsSeen < this.MAX_ITEMS) {
1212
this._data.push(item)
@@ -18,14 +18,18 @@ Reservoir.prototype.add = function (item) {
1818
return inserted
1919
}
2020

21-
Reservoir.prototype.flush = function () {
21+
ReservoirSampler.prototype.flush = function () {
2222
var data = this._data
2323
this._data = []
2424
this._itemsSeen = 0
2525
return data
2626
}
2727

28-
Reservoir.prototype._replace = function (item) {
28+
ReservoirSampler.prototype.size = function () {
29+
return this._data.length
30+
}
31+
32+
ReservoirSampler.prototype._replace = function (item) {
2933
var toReplaceIndex = Math.floor(Math.random() * (this._itemsSeen + 2))
3034
if (toReplaceIndex < this.MAX_ITEMS) {
3135
this._data[toReplaceIndex] = item
@@ -34,4 +38,6 @@ Reservoir.prototype._replace = function (item) {
3438
return false
3539
}
3640

37-
module.exports = Reservoir
41+
module.exports.create = function (limit) {
42+
return new ReservoirSampler(limit)
43+
}

lib/agent/tracer/reservoirSampler.spec.js renamed to lib/agent/tracer/samplers/reservoir.spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
var expect = require('chai').expect
2-
var ReservoirSampler = require('./reservoirSampler')
2+
var reservoirSampler = require('./reservoir')
33

44
describe('The Reservoir Sampler', function () {
55
var itemToAdd = {
@@ -8,7 +8,7 @@ describe('The Reservoir Sampler', function () {
88

99
describe('when seen count is below the size limit', function () {
1010
it('adds the item', function () {
11-
var sampler = new ReservoirSampler(3)
11+
var sampler = reservoirSampler.create(3)
1212
var isAdded = sampler.add(itemToAdd)
1313

1414
expect(isAdded).to.eql(true)
@@ -21,7 +21,7 @@ describe('The Reservoir Sampler', function () {
2121
this.sandbox.stub(Math, 'random', function () {
2222
return 0
2323
})
24-
var sampler = new ReservoirSampler(1)
24+
var sampler = reservoirSampler.create(1)
2525
sampler._itemsSeen = 1
2626
var isAdded = sampler.add(itemToAdd)
2727
expect(isAdded).to.eql(true)
@@ -31,7 +31,7 @@ describe('The Reservoir Sampler', function () {
3131
this.sandbox.stub(Math, 'random', function () {
3232
return 1
3333
})
34-
var sampler = new ReservoirSampler(1)
34+
var sampler = reservoirSampler.create(1)
3535
sampler._itemsSeen = 1
3636
var isAdded = sampler.add(itemToAdd)
3737
expect(isAdded).to.eql(false)

lib/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ config.collectInterval = 2 * 60 * 1000
44
config.updateInterval = 15 * 1000
55
config.healthcheckInterval = 10 * 1000
66

7+
config.samplerLimit = 100
8+
79
config.collectorLanguage = 'nodejs'
810
config.collectorApiUrl = 'https://trace-collector-api.risingstack.com'
911
config.collectorApiSampleEndpoint = '/transaction-events'

lib/utils/configReader.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ ConfigReader.prototype._getEnvVarConfig = function () {
6767
keepQueryParams: process.env.TRACE_KEEP_QUERY_PARAMS
6868
}
6969

70+
if (process.env.TRACE_SAMPLER_LIMIT) {
71+
var samplerLimit = Number(process.env.TRACE_SAMPLER_LIMIT)
72+
!isNaN(samplerLimit) && defaults(envVarConfig, { samplerLimit: samplerLimit })
73+
}
74+
7075
var ignoreHeaders
7176
var ignoreOutgoingHosts
7277

lib/utils/configReader.spec.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,39 @@ describe('Config Reader module', function () {
345345
})
346346

347347
describe('config variable', function () {
348+
describe('samplerLimit', function () {
349+
it('should be configurable with by env var', function () {
350+
this.sandbox.stub(process, 'env', {
351+
TRACE_SAMPLER_LIMIT: 1000
352+
})
353+
354+
var configReader = ConfigReader.create({
355+
apiKey: testApiToken,
356+
reporter: 'dummy',
357+
serviceName: 'test'
358+
})
359+
360+
var config = configReader.getConfig()
361+
362+
expect(config.samplerLimit).to.equal(1000)
363+
})
364+
it('should be tolerant', function () {
365+
this.sandbox.stub(process, 'env', {
366+
TRACE_SAMPLER_LIMIT: 'asdf'
367+
})
368+
369+
var configReader = ConfigReader.create({
370+
apiKey: testApiToken,
371+
reporter: 'dummy',
372+
serviceName: 'test'
373+
})
374+
375+
var config = configReader.getConfig()
376+
377+
expect(config.samplerLimit).not.to.be.a('string')
378+
expect(config.samplerLimit).not.to.be.NaN
379+
})
380+
})
348381
describe('traceProxy', function () {
349382
it('should be configurable with the HTTP_PROXY env var', function () {
350383
this.sandbox.stub(process, 'env', {

0 commit comments

Comments
 (0)