Skip to content

Commit 13b5cc2

Browse files
committed
fix: decode scope version/attributes, handle missing status, and fix Effect error handling
- Read scopeVersion and scopeAttributes from scopeSpan.scope instead of hardcoding undefined/{} in decodeOtlpTraceRecords - Add null guard in decodeStatus to return undefined when span status is missing - Fix Effect.try catch handler to return a plain error value and use Effect.catch to actually execute the warning log - Make span array fields (attributes, events, links) tolerant of missing values - Convert OTLP intValue from string to number in decodeValue
1 parent 472dd26 commit 13b5cc2

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

apps/server/src/http.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,15 @@ export const otlpTracesProxyRouteLayer = HttpRouter.add(
3939

4040
yield* Effect.try({
4141
try: () => decodeOtlpTraceRecords(bodyJson),
42-
catch: (cause) =>
42+
catch: (cause) => ({ _tag: "DecodeError" as const, cause }),
43+
}).pipe(
44+
Effect.flatMap((records) => browserTraceCollector.record(records)),
45+
Effect.catch(() =>
4346
Effect.logWarning("Failed to decode browser OTLP traces", {
44-
cause,
4547
bodyJson,
4648
}),
47-
}).pipe(Effect.flatMap((records) => browserTraceCollector.record(records)));
49+
),
50+
);
4851

4952
if (otlpTracesUrl === undefined) {
5053
return HttpServerResponse.empty({ status: 204 });

apps/server/src/observability/TraceRecord.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,18 @@ export function decodeOtlpTraceRecords(
147147
const resourceAttributes = decodeAttributes(resourceSpan.resource?.attributes ?? []);
148148

149149
for (const scopeSpan of resourceSpan.scopeSpans) {
150+
const scope = scopeSpan.scope as {
151+
name?: string;
152+
version?: string;
153+
attributes?: ReadonlyArray<OtlpResource.KeyValue>;
154+
};
150155
for (const span of scopeSpan.spans) {
151156
records.push(
152157
otlpSpanToTraceRecord({
153158
resourceAttributes,
154-
scopeAttributes: {},
155-
scopeName: scopeSpan.scope.name,
156-
scopeVersion: undefined,
159+
scopeAttributes: decodeAttributes(scope?.attributes ?? []),
160+
scopeName: scope?.name,
161+
scopeVersion: scope?.version,
157162
span,
158163
}),
159164
);
@@ -184,20 +189,23 @@ function otlpSpanToTraceRecord(input: {
184189
durationMs:
185190
Number(parseBigInt(input.span.endTimeUnixNano) - parseBigInt(input.span.startTimeUnixNano)) /
186191
1_000_000,
187-
attributes: decodeAttributes(input.span.attributes),
192+
attributes: decodeAttributes(input.span.attributes ?? []),
188193
resourceAttributes: input.resourceAttributes,
189194
scope: {
190195
...(input.scopeName ? { name: input.scopeName } : {}),
191196
...(input.scopeVersion ? { version: input.scopeVersion } : {}),
192197
attributes: input.scopeAttributes,
193198
},
194-
events: decodeEvents(input.span.events),
195-
links: decodeLinks(input.span.links),
199+
events: decodeEvents(input.span.events ?? []),
200+
links: decodeLinks(input.span.links ?? []),
196201
status: decodeStatus(input.span.status),
197202
};
198203
}
199204

200-
function decodeStatus(input: OtlpSpanStatus): OtlpTraceRecord["status"] {
205+
function decodeStatus(input: OtlpSpanStatus | undefined): OtlpTraceRecord["status"] {
206+
if (input == null) {
207+
return undefined;
208+
}
201209
const code = String(input.code);
202210
const message = input.message;
203211

@@ -250,7 +258,7 @@ function decodeValue(input: OtlpResource.AnyValue | null | undefined): unknown {
250258
return input.boolValue;
251259
}
252260
if ("intValue" in input) {
253-
return input.intValue;
261+
return Number(input.intValue);
254262
}
255263
if ("doubleValue" in input) {
256264
return input.doubleValue;

0 commit comments

Comments
 (0)