Skip to content

Commit 0d60a9b

Browse files
committed
Pass timestamp on OpenTelemetry span close
When the SpanProcessor closes a span, before this commit, it would call `span.close()`, which would call the `appsignal_close_span` function in the extension, which would override the end time passed as an argument when calling `createOpenTelemetrySpan`. To fix this, pass the end time provided by OpenTelemetry _again_ to `span.close()` when closing the span, re-wiring it so that, if a timestamp is passed, it calls `appsignal_close_span_with_timestamp` instead. This function already existed in the extension, but a NAPI bridge for it needed to be created.
1 parent a549b2a commit 0d60a9b

File tree

4 files changed

+32
-3
lines changed

4 files changed

+32
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
bump: patch
3+
type: fix
4+
---
5+
6+
Fix an issue where a later span close time than accurate, and therefore a longer span duration, is reported to AppSignal under certain circumstances.

ext/appsignal_extension.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,23 @@ Napi::Value CloseSpan(const Napi::CallbackInfo &info) {
358358
return env.Null();
359359
}
360360

361+
Napi::Value CloseSpanWithTimestamp(const Napi::CallbackInfo &info) {
362+
Napi::Env env = info.Env();
363+
364+
Napi::External<appsignal_span_t> span =
365+
info[0].As<Napi::External<appsignal_span_t>>();
366+
367+
Napi::Number endTimeSec = info[1].As<Napi::Number>();
368+
Napi::Number endTimeNsec = info[2].As<Napi::Number>();
369+
370+
appsignal_close_span_with_timestamp(span.Data(),
371+
endTimeSec.Int64Value(),
372+
endTimeNsec.Int32Value()
373+
);
374+
375+
return env.Null();
376+
}
377+
361378
// Metrics
362379

363380
Napi::Value SetGauge(const Napi::CallbackInfo &info) {
@@ -494,6 +511,8 @@ Napi::Object CreateSpanObject(Napi::Env env, Napi::Object exports) {
494511

495512
span.Set(Napi::String::New(env, "closeSpan"),
496513
Napi::Function::New(env, CloseSpan));
514+
span.Set(Napi::String::New(env, "closeSpanWithTimestamp"),
515+
Napi::Function::New(env, CloseSpanWithTimestamp));
497516
span.Set(Napi::String::New(env, "addSpanError"),
498517
Napi::Function::New(env, AddSpanError));
499518
span.Set(Napi::String::New(env, "spanToJSON"),

src/span.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ export class Span {
2626
this.#ref = ref
2727
}
2828

29-
public close(): this {
30-
span.closeSpan(this.#ref)
29+
public close({ timestamp }: { timestamp?: [number, number] } = {}): this {
30+
if (timestamp !== undefined) {
31+
span.closeSpanWithTimestamp(this.#ref, timestamp[0], timestamp[1])
32+
} else {
33+
span.closeSpan(this.#ref)
34+
}
3135
return this
3236
}
3337

src/span_processor.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class SpanProcessor implements OpenTelemetrySpanProcessor {
6060
}
6161
})
6262

63-
opentelemetrySpan.close()
63+
opentelemetrySpan.close({ timestamp: [span.endTime[0], span.endTime[1]] })
6464
}
6565

6666
shutdown(): Promise<void> {

0 commit comments

Comments
 (0)