Skip to content

trace level PoC #4994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions packages/datadog-plugin-router/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ class RouterPlugin extends WebPlugin {
context.middleware.push(span)
}

const store = storage.getStore()
this._storeStack.push(store)
this.enter(span, store)
if (span.constructor.name !== 'NoopSpan') {
const store = storage.getStore()
this._storeStack.push(store)
this.enter(span, store)
}

web.patch(req)
web.setRoute(req, context.route)
Expand Down Expand Up @@ -90,6 +92,9 @@ class RouterPlugin extends WebPlugin {
if (!context) return
if (context.middleware.length === 0) return context.span

// if the span is no-op then use the OG request span
if (context.middleware[context.middleware.length - 1].constructor.name === 'NoopSpan') return context.span

return context.middleware[context.middleware.length - 1]
}

Expand Down
8 changes: 8 additions & 0 deletions packages/dd-trace/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,8 @@ class Config {
this._setValue(defaults, 'logInjection', false)
this._setValue(defaults, 'lookup', undefined)
this._setValue(defaults, 'inferredProxyServicesEnabled', false)
this._setValue(defaults, 'traceLevel', 'debug')
this._setValue(defaults, 'spanFilters', '')
this._setValue(defaults, 'memcachedCommandEnabled', false)
this._setValue(defaults, 'openAiLogsEnabled', false)
this._setValue(defaults, 'openaiSpanCharLimit', 128)
Expand Down Expand Up @@ -688,6 +690,8 @@ class Config {
DD_TRACING_ENABLED,
DD_VERSION,
DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED,
DD_TRACE_LEVEL,
DD_SPAN_FILTERS,
OTEL_METRICS_EXPORTER,
OTEL_PROPAGATORS,
OTEL_RESOURCE_ATTRIBUTES,
Expand Down Expand Up @@ -881,6 +885,8 @@ class Config {
this._setBoolean(env, 'tracing', DD_TRACING_ENABLED)
this._setString(env, 'version', DD_VERSION || tags.version)
this._setBoolean(env, 'inferredProxyServicesEnabled', DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED)
this._setString(env, 'traceLevel', DD_TRACE_LEVEL)
this._setString(env, 'spanFilters', DD_SPAN_FILTERS)
this._setString(env, 'aws.dynamoDb.tablePrimaryKeys', DD_AWS_SDK_DYNAMODB_TABLE_PRIMARY_KEYS)
}

Expand Down Expand Up @@ -996,6 +1002,8 @@ class Config {
this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
this._setString(opts, 'version', options.version || tags.version)
this._setBoolean(opts, 'inferredProxyServicesEnabled', options.inferredProxyServicesEnabled)
this._setString(opts, 'traceLevel', options.traceLevel)
this._setString(opts, 'spanFilters', options.spanFilters)

// For LLMObs, we want the environment variable to take precedence over the options.
// This is reliant on environment config being set before options.
Expand Down
24 changes: 21 additions & 3 deletions packages/dd-trace/src/noop/span.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
'use strict'

const NoopSpanContext = require('./span_context')
const DatadogSpanContext = require('../opentracing/span_context')
const id = require('../id')
const { performance } = require('perf_hooks')
const now = performance.now.bind(performance)
const dateNow = Date.now
const { storage } = require('../../../datadog-core') // TODO: noop storage?

class NoopSpan {
constructor (tracer, parent) {
constructor (tracer, parent, options) {
this._store = storage.getStore()
this._noopTracer = tracer
this._noopContext = this._createContext(parent)
this._noopContext = this._createContext(parent, options)
this._options = options
this._startTime = this._getTime()
}

_getTime () {
const startTime = dateNow() + now()

return startTime
}

context () { return this._noopContext }
Expand All @@ -27,10 +39,16 @@ class NoopSpan {
logEvent () {}
finish (finishTime) {}

_createContext (parent) {
_createContext (parent, options) {
const spanId = id()

if (parent) {
// necessary for trace level configuration. This pattern returns the first valid span context that is not a
// NoopSpanContext, aka the next parent span in the trace that will be kept.
if (options.keepParent && parent) {
return parent instanceof DatadogSpanContext ? parent : parent.context()
}

return new NoopSpanContext({
noop: this,
traceId: parent._traceId,
Expand Down
37 changes: 35 additions & 2 deletions packages/dd-trace/src/opentracing/tracer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const os = require('os')
const Span = require('./span')
const NoopSpan = require('../noop/span')
const SpanProcessor = require('../span_processor')
const PrioritySampler = require('../priority_sampler')
const TextMapPropagator = require('./propagation/text_map')
Expand All @@ -15,6 +16,7 @@ const log = require('../log')
const runtimeMetrics = require('../runtime_metrics')
const getExporter = require('../exporter')
const SpanContext = require('./span_context')
const { SpanFilter } = require('../span_filter')

const REFERENCE_CHILD_OF = 'child_of'
const REFERENCE_FOLLOWS_FROM = 'follows_from'
Expand Down Expand Up @@ -45,6 +47,7 @@ class DatadogTracer {
if (config.reportHostname) {
this._hostname = os.hostname()
}
this._spanFilter = new SpanFilter(this)
}

startSpan (name, options = {}) {
Expand All @@ -54,7 +57,21 @@ class DatadogTracer {

// as per spec, allow the setting of service name through options
const tags = {
'service.name': options?.tags?.service ? String(options.tags.service) : this._service
'service.name': options?.tags?.service ? String(options.tags.service) : this._service,
...options?.tags
}

if (options?.kind) {
tags['span.kind'] = options.kind
}

options.tags = tags

if (this._config.traceLevel !== 'debug' || this._config.spanFilters !== '') {
const traceLevelSpan = this._useTraceLevel(parent, options)
if (traceLevelSpan) {
return traceLevelSpan
}
}

// As per unified service tagging spec if a span is created with a service name different from the global
Expand All @@ -81,7 +98,7 @@ class DatadogTracer {
}

inject (context, format, carrier) {
if (context instanceof Span) {
if (context instanceof Span || context instanceof NoopSpan) {
context = context.context()
}

Expand All @@ -105,13 +122,29 @@ class DatadogTracer {
return null
}
}

_useTraceLevel (parent, options) {
// service trace level indicates service exit / entry spans only
// if (this._config.traceLevel === 'service') {
if (!this._spanFilter.shouldKeepSpan(options.tags)) {
return new NoopSpan(this, parent, { keepParent: true })
}
// } else {
// log.warn(`Received invalid Datadog Trace Level Configuration: ${this._config.traceLevel}`)
// return null
// }
}
}

function getContext (spanContext) {
if (spanContext instanceof Span) {
spanContext = spanContext.context()
}

if (spanContext instanceof NoopSpan) {
spanContext = spanContext.context()
}

if (!(spanContext instanceof SpanContext)) {
spanContext = null
}
Expand Down
2 changes: 1 addition & 1 deletion packages/dd-trace/src/plugins/tracing.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class TracingPlugin extends Plugin {
}

addError (error, span = this.activeSpan) {
if (span && !span._spanContext._tags.error) {
if (!span.context()._tags.error) {
// Errors may be wrapped in a context.
error = (error && error.error) || error
span.setTag('error', error || 1)
Expand Down
2 changes: 1 addition & 1 deletion packages/dd-trace/src/plugins/util/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ const web = {
}
}

const span = tracer.startSpan(name, { childOf, links: childOf?._links })
const span = tracer.startSpan(name, { childOf, links: childOf?._links, kind: SERVER })

return span
},
Expand Down
Loading
Loading