Skip to content

Commit

Permalink
wip: wired up context manager, and segment synthesis
Browse files Browse the repository at this point in the history
  • Loading branch information
bizob2828 committed Jan 10, 2025
1 parent 449a9f2 commit 806e8c8
Show file tree
Hide file tree
Showing 21 changed files with 443 additions and 500 deletions.
436 changes: 218 additions & 218 deletions THIRD_PARTY_NOTICES.md

Large diffs are not rendered by default.

24 changes: 22 additions & 2 deletions lib/context-manager/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
*/

'use strict'
const { otelSynthesis } = require('../symbols')

module.exports = class Context {
constructor(transaction, segment) {
constructor(transaction, segment, parentContext) {
this._transaction = transaction
this._segment = segment
this._otelCtx = parentContext ? new Map(parentContext) : new Map()
}

get segment() {
Expand All @@ -19,11 +21,29 @@ module.exports = class Context {
return this._transaction
}

enterSegment({ segment, transaction = this.transaction }) {
enterSegment({ segment, transaction = this._transaction }) {
return new this.constructor(transaction, segment)
}

enterTransaction(transaction) {
return new this.constructor(transaction, transaction.trace.root)
}

getValue(key) {
return this._otelCtx.get(key)
}

setValue(key, value) {
const { segment, transaction } = value[otelSynthesis]
segment.start()
const ctx = new this.constructor(transaction, segment, this._otelCtx)
ctx._otelCtx.set(key, value)
return ctx
}

deleteValue(key) {
const ctx = new this.constructor(this._transaction, this._segment, this._otelCtx)
ctx._otelCtx.delete(key)
return ctx
}
}
2 changes: 1 addition & 1 deletion lib/feature_flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ exports.prerelease = {
// internal_test_only is used for testing our feature flag implementation.
// It is not used to gate any features.
internal_test_only: false,
otel_instrumentation: true,
otel_bridge: false,
promise_segments: false,
reverse_naming_rules: false,
undici_async_tracking: true,
Expand Down
44 changes: 0 additions & 44 deletions lib/instrumentation/otel/Readme.md

This file was deleted.

17 changes: 0 additions & 17 deletions lib/instrumentation/otel/nr-hooks.js

This file was deleted.

27 changes: 0 additions & 27 deletions lib/instrumentation/otel/otel.js

This file was deleted.

95 changes: 0 additions & 95 deletions lib/instrumentation/otel/tracer-provider.js

This file was deleted.

37 changes: 0 additions & 37 deletions lib/instrumentation/otel/tracer.js

This file was deleted.

1 change: 0 additions & 1 deletion lib/instrumentations.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ module.exports = function instrumentations() {
'mongodb': { type: InstrumentationDescriptor.TYPE_DATASTORE },
'mysql': { module: './instrumentation/mysql' },
'next': { module: './instrumentation/nextjs' },
'otel': { module: './instrumentation/otel' },
'openai': { type: InstrumentationDescriptor.TYPE_GENERIC },
'pg': { type: InstrumentationDescriptor.TYPE_DATASTORE },
'pino': { module: './instrumentation/pino' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,18 @@

'use strict'

const { ROOT_CONTEXT } = require('@opentelemetry/api')

/**
* @see https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api.ContextManager.html
*/
class ContextManager {
#agent

#ctxMgr

constructor(agent) {
this.#agent = agent
this.#ctxMgr = agent._contextManager
this.#ctxMgr = agent.tracer._contextManager
}

active() {
// TODO: get current span(segment?) from agent and prefer it
const storedContext = this.#ctxMgr.getContext()
return storedContext || ROOT_CONTEXT
return this.#ctxMgr.getContext()
}

bind(context, target) {
Expand All @@ -44,7 +37,7 @@ class ContextManager {
* @param args
*/
with(context, callback, thisRef, ...args) {
return this.#agent._contextManager.runInContext(context, callback, thisRef, args)
return this.#ctxMgr.runInContext(context, callback, thisRef, args)
}

enable() {
Expand Down
2 changes: 2 additions & 0 deletions lib/otel/segments/http-external.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
'use strict'
const NAMES = require('../../metrics/names')
const { SEMATTRS_HTTP_HOST } = require('@opentelemetry/semantic-conventions')
const recordExternal = require('../../metrics/recorders/http_external')

module.exports = function createHttpExternalSegment(agent, otelSpan) {
const context = agent.tracer.getContext()
const host = otelSpan.attributes[SEMATTRS_HTTP_HOST] || 'Unknown'
const name = NAMES.EXTERNAL.PREFIX + host
const segment = agent.tracer.createSegment({
name,
recorder: recordExternal(host, 'http'),
parent: context.segment,
transaction: context.transaction
})
Expand Down
4 changes: 3 additions & 1 deletion lib/otel/segments/internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
*/

'use strict'
const customRecorder = require('../../metrics/recorders/custom')

module.exports = function createInternalSegment(agent, otelSpan) {
const context = agent.tracer.getContext()
const name = `Custom/${otelSpan.name}`
const name = otelSpan.name
const segment = agent.tracer.createSegment({
name,
parent: context.segment,
recorder: customRecorder,
transaction: context.transaction
})
return { segment, transaction: context.transaction }
Expand Down
26 changes: 26 additions & 0 deletions lib/otel/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2025 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

'use strict'
const { BasicTracerProvider } = require('@opentelemetry/sdk-trace-base')
const NrSpanProcessor = require('./span-processor')
const ContextManager = require('./context-manager')

module.exports = function setupOtel(agent) {
if (agent.config.feature_flag.otel_bridge !== true) {
agent.logger.warn(
'`feature_flag.otel_bridge` is not enabled, not setting up opentelemetry_bridge.'
)
return
}

const provider = new BasicTracerProvider({
spanProcessors: [new NrSpanProcessor(agent)]
})
provider.register({
contextManager: new ContextManager(agent)
// propagator: // w3c trace propagator
})
}
Loading

0 comments on commit 806e8c8

Please sign in to comment.