[Monitor OpenTelemetry Exporter] Update Span Exception Emitting Logic (#31417)

### Packages impacted by this PR
@azure/monitor-opentelemetry-exporter

### Describe the problem that is addressed by this PR
Exceptions should only be emitted from top level spans or those with a
remote parent.

### What are the possible designs available to address the problem? If
there are more than one possible design, why was the one in this PR
chosen?


### Are there test cases added in this PR? _(If not, why?)_
Yes, tests are updated.

### Command used to generate this PR:**_(Applicable only to SDK release
request PRs)_

### Checklists
- [x] Added impacted package name to the issue description
- [ ] Does this PR needs any fixes in the SDK Generator?** _(If so,
create an Issue in the
[Autorest/typescript](https://github.com/Azure/autorest.typescript)
repository and link it here)_
- [x] Added a changelog (if necessary)
This commit is contained in:
Jackson Weber 2024-10-22 13:06:45 -07:00 коммит произвёл GitHub
Родитель e605b318e5
Коммит 21ee8ad656
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 46 добавлений и 5 удалений

Просмотреть файл

@ -8,6 +8,7 @@
- Updated OTel dependencies.
- Update Statsbeat shutdown logic to include more status codes for shutdown.
- Add non-essential statsbeat metrics.
- Update logic for when to emit exceptions.
## 1.0.0-beta.25 (2024-08-14)

Просмотреть файл

@ -3,7 +3,16 @@
import { ReadableSpan, TimedEvent } from "@opentelemetry/sdk-trace-base";
import { hrTimeToMilliseconds } from "@opentelemetry/core";
import { diag, SpanKind, SpanStatusCode, Link, Attributes } from "@opentelemetry/api";
import {
diag,
SpanKind,
SpanStatusCode,
Link,
Attributes,
SpanContext,
isValidTraceId,
isValidSpanId,
} from "@opentelemetry/api";
import {
DBSYSTEMVALUES_MONGODB,
DBSYSTEMVALUES_MYSQL,
@ -414,7 +423,19 @@ export function spanEventsToEnvelopes(span: ReadableSpan, ikey: string): Envelop
// Only generate exception telemetry for incoming requests
if (event.name === "exception") {
if (span.kind === SpanKind.SERVER) {
let isValidParent = false;
const parentSpanContext: SpanContext | undefined = span.parentSpanId
? span.spanContext()
: undefined;
if (parentSpanContext) {
isValidParent =
isValidTraceId(parentSpanContext.traceId) && isValidSpanId(parentSpanContext.spanId);
}
/*
* Only generate exception telemetry for children of a remote span,
* internal spans, and top level spans. This is to avoid unresolvable exceptions from outgoing calls.
*/
if (!isValidParent || parentSpanContext?.isRemote || span.kind === SpanKind.INTERNAL) {
name = "Microsoft.ApplicationInsights.Exception";
baseType = "ExceptionData";
let typeName = "";

Просмотреть файл

@ -1218,13 +1218,13 @@ describe("spanUtils.ts", () => {
});
});
describe("#spanEventsToEnvelopes", () => {
it("should create exception envelope for server exception events", () => {
it("should create exception envelope for remote exception events", () => {
const testError = new Error("test error");
const span = new Span(
tracer,
ROOT_CONTEXT,
"parent span",
{ traceId: "traceid", spanId: "spanId", traceFlags: 0 },
{ traceId: "traceid", spanId: "spanId", traceFlags: 0, isRemote: true },
SpanKind.SERVER,
"parentSpanId",
);
@ -1267,7 +1267,7 @@ describe("spanUtils.ts", () => {
tracer,
ROOT_CONTEXT,
"parent span",
{ traceId: "traceid", spanId: "spanId", traceFlags: 0 },
{ traceId: "4bf92f3577b34da6a3ce929d0e0e4736", spanId: "00f067aa0ba902b7", traceFlags: 0 },
SpanKind.CLIENT,
"parentSpanId",
);
@ -1281,6 +1281,25 @@ describe("spanUtils.ts", () => {
assert.ok(envelopes.length === 0);
});
});
it("should create an envelope for internal exception span events", () => {
const testError = new Error("test error");
const span = new Span(
tracer,
ROOT_CONTEXT,
"parent span",
{ traceId: "4bf92f3577b34da6a3ce929d0e0e4736", spanId: "00f067aa0ba902b7", traceFlags: 0 },
SpanKind.INTERNAL,
"parentSpanId",
);
span.recordException(testError);
span.end();
const envelopes = spanEventsToEnvelopes(span, "ikey");
const expectedTags: Tags = {};
expectedTags[KnownContextTagKeys.AiOperationId] = span.spanContext().traceId;
expectedTags[KnownContextTagKeys.AiOperationParentId] = "spanId";
assert.ok(envelopes.length === 1);
});
it("should create message envelope for span events", () => {
const span = new Span(
tracer,