-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[Service Bus] Tracing for send API #11651
Changes from 24 commits
a8c1d5d
a73fd31
e46e805
4af1738
c7d3a14
b5f77a8
cd71e42
d631ee5
8375ed8
8038315
6fa23f7
a8b34fc
d04a38e
9742d97
f262e45
ba4fef7
e46deb4
fea2177
5c5795f
6b2409a
7de9b6f
d1af28e
060842e
3197fbc
84e48aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
import { extractSpanContextFromTraceParentHeader, getTraceParentHeader } from "@azure/core-tracing"; | ||
import { Span, SpanContext } from "@opentelemetry/api"; | ||
import { ServiceBusMessage } from "../serviceBusMessage"; | ||
|
||
/** | ||
* @ignore | ||
*/ | ||
export const TRACEPARENT_PROPERTY = "Diagnostic-Id"; | ||
|
||
/** | ||
* Populates the `ServiceBusMessage` with `SpanContext` info to support trace propagation. | ||
* Creates and returns a copy of the passed in `ServiceBusMessage` unless the `ServiceBusMessage` | ||
* has already been instrumented. | ||
* @param message The `ServiceBusMessage` to instrument. | ||
* @param span The `Span` containing the context to propagate tracing information. | ||
* @ignore | ||
* @internal | ||
*/ | ||
export function instrumentServiceBusMessage( | ||
message: ServiceBusMessage, | ||
span: Span | ||
): ServiceBusMessage { | ||
if (message.properties && message.properties[TRACEPARENT_PROPERTY]) { | ||
return message; | ||
} | ||
|
||
// create a copy so the original isn't modified | ||
message = { ...message, properties: { ...message.properties } }; | ||
|
||
const traceParent = getTraceParentHeader(span.context()); | ||
if (traceParent) { | ||
message.properties![TRACEPARENT_PROPERTY] = traceParent; | ||
} | ||
|
||
return message; | ||
} | ||
|
||
/** | ||
* Extracts the `SpanContext` from an `ServiceBusMessage` if the context exists. | ||
* @param message An individual `ServiceBusMessage` object. | ||
* @internal | ||
* @ignore | ||
*/ | ||
export function extractSpanContextFromServiceBusMessage( | ||
message: ServiceBusMessage | ||
): SpanContext | undefined { | ||
if (!message.properties || !message.properties[TRACEPARENT_PROPERTY]) { | ||
return; | ||
} | ||
|
||
const diagnosticId = message.properties[TRACEPARENT_PROPERTY] as string; | ||
return extractSpanContextFromTraceParentHeader(diagnosticId); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
import { ConnectionConfig } from "@azure/core-amqp"; | ||
import { getTracer } from "@azure/core-tracing"; | ||
import { Span, SpanContext, SpanKind } from "@opentelemetry/api"; | ||
|
||
/** | ||
* @internal | ||
* @ignore | ||
*/ | ||
export function createMessageSpan( | ||
parentSpan?: Span | SpanContext | null, | ||
config?: Pick<ConnectionConfig, "entityPath" | "host"> | ||
): Span { | ||
const tracer = getTracer(); | ||
const span = tracer.startSpan("Azure.ServiceBus.message", { | ||
kind: SpanKind.PRODUCER, | ||
parent: parentSpan | ||
}); | ||
span.setAttribute("az.namespace", "Microsoft.ServiceBus"); | ||
if (config) { | ||
span.setAttribute("message_bus.destination", config.entityPath); | ||
span.setAttribute("peer.address", config.host); | ||
} | ||
return span; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,9 @@ | |
|
||
// TODO: this code is a straight-copy from EventHubs. Need to merge. | ||
|
||
import { Span, SpanContext } from "@opentelemetry/api"; | ||
import { Link, Span, SpanContext, SpanKind } from "@opentelemetry/api"; | ||
import { OperationOptions } from "@azure/core-http"; | ||
import { getTracer, OperationTracingOptions } from "@azure/core-tracing"; | ||
|
||
/** | ||
* NOTE: This type is intended to mirror the relevant fields and structure from @azure/core-http OperationOptions | ||
|
@@ -18,7 +19,41 @@ export type OperationOptionsBase = Pick<OperationOptions, "abortSignal" | "traci | |
* @ignore | ||
*/ | ||
export function getParentSpan( | ||
options: Pick<OperationOptionsBase, "tracingOptions"> | ||
options?: OperationTracingOptions | ||
): Span | SpanContext | null | undefined { | ||
return options.tracingOptions?.spanOptions?.parent; | ||
return options?.spanOptions?.parent; | ||
} | ||
|
||
export function createSendSpan( | ||
parentSpan?: Span | SpanContext | null, | ||
spanContextsToLink: SpanContext[] = [], | ||
entityPath?: string, | ||
host?: string | ||
): Span { | ||
const links: Link[] = spanContextsToLink.map((context) => { | ||
return { | ||
context | ||
}; | ||
}); | ||
const tracer = getTracer(); | ||
const span = tracer.startSpan("Azure.ServiceBus.send", { | ||
kind: SpanKind.CLIENT, | ||
parent: parentSpan, | ||
links | ||
}); | ||
|
||
span.setAttribute("az.namespace", "Microsoft.ServiceBus"); | ||
span.setAttribute("message_bus.destination", entityPath); | ||
span.setAttribute("peer.address", host); | ||
|
||
return span; | ||
} | ||
/** | ||
* The set of options to manually propagate `Span` context for distributed tracing. | ||
*/ | ||
export interface TryAddOptions { | ||
/** | ||
* The `Span` or `SpanContext` to use as the `parent` of any spans created while calling operations that make a request to the service. | ||
*/ | ||
parentSpan?: Span | SpanContext | null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed in Event Hubs that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are other places where we allow the span to be "null" which is a valid value and it signifies the rootSpan. Moreover, I needed to allow this "null" since I'm calling getParentSpan() for the tryAdd over array of messages which may return a null value. In event-hubs, this tracing for "array of messages" case is duplicated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll log an issue for fixing it in event-hubs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Logged #11687 |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feedback not for this PR, but a note for both Event Hubs & Service Bus for which we can log a generic issue on improvements and make changes for both packages at once in the future:
createMessageSpan()
is slightly misleading as it may indicate that I can use it at any time when a message is involved. In reality, this method is tied to the "producer" kind, so is usable only when sending message.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes to the first two!
parentSpan is not a required parameter but feels primary, I believe that was the reason Chris made the config optional in event-hubs. I can make it the first param in both service-bus and event-hubs and make it required in a later PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logged #11687