devdocs/adding-apis.md
dd-trace-apiThis guide explains how to expose dd-trace methods through the dd-trace-api package.
Datadog’s tracing system includes two related packages:
dd-trace: The core tracing library.dd-trace-api: A stable facade layer used in specialized deployments.All APIs exposed via dd-trace-api exist in dd-trace. The facade adds flexibility for deployment and versioning.
You’ll typically update dd-trace-api when:
dd-trace.dd-trace needs to be exposed via dd-trace-api.In either case, you’ll also update the datadog-plugin-dd-trace-api to bridge the method.
Locate or add the desired method in dd-trace (e.g., tracer.js, appsec, etc.).
Existing method example:
class DatadogTracer extends Tracer {
getVersion() {
return this._version
}
}
New method example:
class DatadogTracer extends Tracer {
getEnvironmentInfo() {
return {
nodeVersion: process.version,
platform: process.platform,
tracerVersion: this._version
}
}
}
dd-trace-apiExpose the method by updating the dd-trace-api package.
Refer to the contribution guide for details.
Bridge the method in datadog-plugin-dd-trace-api by adding a handleEvent() call:
handleEvent('getVersion') // For tracer methods
handleEvent('appsec:checkPermission') // For subsystem methods
File location:
packages/datadog-plugin-dd-trace-api/src/index.js
Add a test in:
packages/datadog-plugin-dd-trace-api/test/index.spec.js
Example:
describe('getVersion', () => {
it('should call underlying API', () => {
testChannel({
name: 'getVersion',
fn: tracer.getVersion,
ret: '1.2.3'
})
})
})
Use the subsystem:method format in handleEvent():
handleEvent('appsec:checkPermission')
And test with describeSubsystem():
describeSubsystem('appsec', 'checkPermission', true)
For non-trivial logic, define a custom handler:
this.addSub('datadog-api:v1:complexMethod', ({ self, args, ret, proxy }) => {
try {
ret.value = self.complexMethod(...args)
} catch (e) {
ret.error = e
}
})
dd-trace-api uses the diagnostics_channel system to communicate with dd-trace:
datadog-api:v1:methodName.dd-trace.handleEvent().proxy parameter.dd-trace:class DatadogTracer extends Tracer {
getServiceName() {
return this._service
}
}
dd-trace-api:getServiceName() {
return this._publicApi.channel.publish('getServiceName', {})
}
handleEvent('getServiceName')
describe('getServiceName', () => {
it('should call underlying API', () => {
testChannel({
name: 'getServiceName',
fn: tracer.getServiceName,
ret: 'test-service'
})
})
})
With these changes, users of dd-trace-api can call tracer.getServiceName() just like they would with dd-trace directly.