Skip to content

Commit

Permalink
refactor Tracer instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
EddeCCC committed Oct 11, 2023
1 parent ad43a51 commit 9a51618
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
28 changes: 18 additions & 10 deletions src/impl/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import api, { context, trace, Span } from '@opentelemetry/api';
import api, { context, trace, Span, SpanOptions, Context } from '@opentelemetry/api';
import {
AlwaysOnSampler,
AlwaysOffSampler,
Expand Down Expand Up @@ -27,7 +27,10 @@ import { B3InjectEncoding, B3Propagator } from '@opentelemetry/propagator-b3';
import { PluginProperties, ContextFunction, PropagationHeader } from '../types';
import { patchExporter, patchExporterClass } from './patchCollectorPrototype';
import { MultiSpanProcessor, CustomSpanProcessor } from './spanProcessing';
import { CustomDocumentLoadInstrumentation, patchTracer } from './instrumentation/documentLoadInstrumentation';
import {
CustomDocumentLoadInstrumentation,
patchTracerForTransactions
} from './instrumentation/documentLoadInstrumentation';
import { CustomIdGenerator } from './transaction/transactionIdGeneration';
import { TransactionSpanManager } from './transaction/transactionSpanManager';
import { CustomXMLHttpRequestInstrumentation } from './instrumentation/xmlHttpRequestInstrumentation';
Expand Down Expand Up @@ -181,10 +184,8 @@ export default class OpenTelemetryTracingImpl {
// store the webtracer
this.traceProvider = providerWithZone;

// If recordTransaction is enabled, patch the Tracer to always use the transaction span as root span
// and initialize the transaction data storage
// If recordTransaction is enabled, initialize the transaction manager
if(this.isTransactionRecordingEnabled()) {
patchTracer();
const delay = this.props.plugins_config?.instrument_document_load?.exporterDelay;
TransactionSpanManager.initialize(true, this.customIdGenerator);

Expand Down Expand Up @@ -260,15 +261,22 @@ export default class OpenTelemetryTracingImpl {
*/
private instrumentTracerClass = () => {
const { commonAttributes, serviceName } = this.props;
// don't patch the function if no attributes are defined
if (Object.keys(commonAttributes).length <= 0) {

let startSpanFunction: (name: string, options?: SpanOptions, context?: Context) => (Span);

// If recordTransaction is enabled, patch the Tracer to always use the transaction span as root span
if(this.isTransactionRecordingEnabled)
startSpanFunction = patchTracerForTransactions();
else
startSpanFunction = Tracer.prototype.startSpan;

// don't patch the function if no attributes are defined AND no serviceName is defined
if (!serviceName && Object.keys(commonAttributes).length <= 0) {
return;
}

const originalStartSpanFunction = Tracer.prototype.startSpan;

Tracer.prototype.startSpan = function () {
const span: Span = originalStartSpanFunction.apply(this, arguments);
const span: Span = startSpanFunction.apply(this, arguments);

// add common attributes to each span
if (commonAttributes) {
Expand Down
13 changes: 11 additions & 2 deletions src/impl/instrumentation/documentLoadInstrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { sanitizeAttributes } from '@opentelemetry/core/build/src/common/attribu
import { TransactionSpanManager } from '../transaction/transactionSpanManager';
import { addUrlParams } from './urlParams';
import { GlobalInstrumentationConfig, RequestParameterConfig } from '../../types';
import { Context, SpanOptions } from '@opentelemetry/api';

export interface CustomDocumentLoadInstrumentationConfig extends InstrumentationConfig {
recordTransaction?: boolean;
Expand All @@ -18,12 +19,17 @@ export interface CustomDocumentLoadInstrumentationConfig extends Instrumentation

/**
* Patch the Tracer class to use the transaction span as root span
* For any additional instrumentation of the startSpan() function, you have to use the
* new returned function
*
* OpenTelemetry version: 0.25.0
*
* @return new startSpan() function
*/
export function patchTracer() {
export function patchTracerForTransactions(): (name: string, options?: SpanOptions, context?: Context) => (api.Span) {
// Overwrite startSpan() in Tracer class
// Copy of the original startSpan()-function with additional logic inside the function to determine the parentContext
Tracer.prototype.startSpan = function (
const overwrittenFunction = function (
name: string,
options: api.SpanOptions = {},
context = api.context.active()
Expand Down Expand Up @@ -115,6 +121,9 @@ export function patchTracer() {
span.setAttributes(Object.assign(attributes, samplingResult.attributes));
return span;
}

Tracer.prototype.startSpan = overwrittenFunction;
return overwrittenFunction;
}

type PerformanceEntriesWithServerTiming = PerformanceEntries & {serverTiming?: ReadonlyArray<({name: string, duration: number, description: string})>}
Expand Down

0 comments on commit 9a51618

Please sign in to comment.