Skip to content

Commit

Permalink
add async scope tracking as an official feature enabled by default (#664
Browse files Browse the repository at this point in the history
)
  • Loading branch information
rochdev authored Sep 10, 2019
1 parent ef64d0a commit 4fa0a75
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 22 deletions.
4 changes: 2 additions & 2 deletions docs/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ tracer.init({
analytics: true,
env: 'test',
runtimeMetrics: true,
trackAsyncScope: false,
experimental: {
b3: true,
thenables: true
b3: true
},
hostname: 'agent',
logger: {
Expand Down
8 changes: 6 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ export declare interface TracerOptions {
*/
runtimeMetrics?: boolean

/**
* Whether to track the scope of async functions. This is needed for async/await to work with non-native promises (thenables). Only disable this if you are sure only native promises are used with async/await.
* @default true
*/
trackAsyncScope?: boolean

/**
* Experimental features can be enabled all at once by using true or individually using key / value pairs.
* @default {}
Expand All @@ -241,8 +247,6 @@ export declare interface TracerOptions {
* @default false
*/
exporter?: 'log' | 'browser' | 'agent'

thenables?: boolean
};

/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"get-port": "^3.2.0",
"graphql": "0.13.2",
"mocha": "^5.2.0",
"nock": "^9.6.1",
"nock": "^11.3.3",
"node-abi": "^2.8.0",
"nyc": "^14.1.1",
"prebuildify": "^2.11.0",
Expand Down
1 change: 0 additions & 1 deletion packages/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"expect": true,
"sinon": true,
"proxyquire": true,
"nock": true,
"wrapIt": true,
"withVersions": true
},
Expand Down
4 changes: 2 additions & 2 deletions packages/dd-trace/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ class Config {
port: String(coalesce(dogstatsd.port, platform.env('DD_DOGSTATSD_PORT'), 8125))
}
this.runtimeMetrics = String(runtimeMetrics) === 'true'
this.trackAsyncScope = options.trackAsyncScope !== false
this.experimental = {
b3: !(!options.experimental || !options.experimental.b3),
exporter: options.experimental && options.experimental.exporter,
thenables: !(!options.experimental || !options.experimental.thenables)
exporter: options.experimental && options.experimental.exporter
}
this.reportHostname = String(reportHostname) === 'true'
this.scope = process.env.DD_CONTEXT_PROPAGATION === 'false' ? scopes.NOOP : scope
Expand Down
12 changes: 9 additions & 3 deletions packages/dd-trace/src/scope/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Scope extends Base {

singleton = this

this._thenables = config.experimental.thenables
this._trackAsyncScope = config.trackAsyncScope
this._current = null
this._spans = Object.create(null)
this._types = Object.create(null)
Expand Down Expand Up @@ -62,12 +62,17 @@ class Scope extends Base {
}

_exit (span) {
this._thenables && this._await(span)
this._trackAsyncScope && this._await(span)
this._current = span
this._stack[this._depth] = null
this._depth--
}

_exitNative () {
this._current = null
this._promises[0] = false
}

_await (span) {
if (!this._promises[this._depth]) return

Expand Down Expand Up @@ -106,12 +111,13 @@ class Scope extends Base {
platform.metrics().increment('async.resources')
platform.metrics().increment('async.resources.by.type', `resource_type:${type}`)

if (this._thenables && type === 'PROMISE') {
if (this._trackAsyncScope && type === 'PROMISE') {
this._initPromise()
}
}

_before (asyncId) {
this._depth === 0 && this._exitNative()
this._enter(this._spans[asyncId])
}

Expand Down
1 change: 0 additions & 1 deletion packages/dd-trace/test/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"expect": true,
"sinon": true,
"proxyquire": true,
"nock": true,
"wrapIt": true,
"withVersions": true
},
Expand Down
8 changes: 4 additions & 4 deletions packages/dd-trace/test/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('Config', () => {
expect(config).to.have.property('flushInterval', 2000)
expect(config).to.have.property('sampleRate', 1)
expect(config).to.have.property('runtimeMetrics', false)
expect(config).to.have.property('trackAsyncScope', true)
expect(config).to.have.deep.property('tags', {})
expect(config).to.have.property('plugins', true)
expect(config).to.have.property('env', undefined)
Expand All @@ -35,7 +36,6 @@ describe('Config', () => {
expect(config).to.have.property('apiKey', undefined)
expect(config).to.have.property('appKey', undefined)
expect(config).to.have.nested.property('experimental.b3', false)
expect(config).to.have.nested.property('experimental.thenables', false)
})

it('should initialize from the default service', () => {
Expand Down Expand Up @@ -116,14 +116,14 @@ describe('Config', () => {
tags,
flushInterval: 5000,
runtimeMetrics: true,
trackAsyncScope: false,
reportHostname: true,
plugins: false,
scope: 'noop',
apiKey: '123',
appKey: '456',
experimental: {
b3: true,
thenables: true
b3: true
}
})

Expand All @@ -141,6 +141,7 @@ describe('Config', () => {
expect(config.tags).to.have.property('foo', 'bar')
expect(config).to.have.property('flushInterval', 5000)
expect(config).to.have.property('runtimeMetrics', true)
expect(config).to.have.property('trackAsyncScope', false)
expect(config).to.have.property('reportHostname', true)
expect(config).to.have.property('plugins', false)
expect(config).to.have.property('scope', 'noop')
Expand All @@ -150,7 +151,6 @@ describe('Config', () => {
'foo': 'bar'
})
expect(config).to.have.nested.property('experimental.b3', true)
expect(config).to.have.nested.property('experimental.thenables', true)
})

it('should initialize from the options with url taking precedence', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/dd-trace/test/platform/node/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const nock = require('nock')
const semver = require('semver')

wrapIt()
Expand Down
19 changes: 18 additions & 1 deletion packages/dd-trace/test/scope/async_hooks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ describe('Scope (async_hooks)', () => {

beforeEach(() => {
thenable = {
then: () => {}
then: onFulfill => onFulfill()
}

test = async () => {
Expand Down Expand Up @@ -155,6 +155,23 @@ describe('Scope (async_hooks)', () => {
scope.activate(span, () => test())
})
})

it('should use the active span when using nested awaits', async () => {
return scope.activate(span, async () => {
await thenable

thenable.then = (onFulfill, onReject) => {
try {
expect()
onFulfill()
} catch (e) {
onReject(e)
}
}

await thenable
})
})
})

testScope(() => scope)
Expand Down
6 changes: 1 addition & 5 deletions packages/dd-trace/test/setup/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const sinon = require('sinon')
const chai = require('chai')
const sinonChai = require('sinon-chai')
const proxyquire = require('../proxyquire')
const nock = require('nock')
const semver = require('semver')
const platform = require('../../src/platform')
const node = require('../../src/platform/node')
Expand All @@ -13,17 +12,14 @@ const agent = require('../plugins/agent')
const externals = require('../plugins/externals.json')

const asyncHooksScope = new AsyncHooksScope({
experimental: {
thenables: true
}
trackAsyncScope: true
})

chai.use(sinonChai)

global.sinon = sinon
global.expect = chai.expect
global.proxyquire = proxyquire
global.nock = nock
global.wrapIt = wrapIt
global.withVersions = withVersions

Expand Down

0 comments on commit 4fa0a75

Please sign in to comment.