@dash0/sdk-web
Version:
Dash0's Web SDK to collect telemetry from end-users' web browsers
73 lines (72 loc) • 2.55 kB
JavaScript
import { nowNanos } from "../time";
import { SPAN_KIND_CLIENT, SPAN_STATUS_UNSET, WEB_EVENT_ID } from "../../semantic-conventions";
import { sessionId } from "../../api/session";
import { generateTraceId } from "../trace-id";
import { generateSpanId } from "../span-id";
import { addAttribute } from "./attributes";
import { debug } from "../debug";
export function startSpan(name) {
const traceId = generateTraceId(sessionId);
const spanId = generateSpanId(traceId);
const attributes = [];
addAttribute(attributes, WEB_EVENT_ID, spanId);
return {
traceId,
spanId,
name,
// Always CLIENT for now https://github.com/open-telemetry/opentelemetry-proto/blob/ac3242b03157295e4ee9e616af53b81517b06559/opentelemetry/proto/trace/v1/trace.proto#L143-L169
// Note: we directly define otlp here, this differs from the values used by oteljs internally.
kind: SPAN_KIND_CLIENT,
startTimeUnixNano: nowNanos(),
attributes,
events: [],
links: [],
status: { code: SPAN_STATUS_UNSET },
};
}
/**
* Ends the span by setting status and endTimeUnixNano on it. If the spand was already previously ended, this returns undefined
* to prevent the span from being ended multiple times on accident.
*/
export function endSpan(span, status, durationNano) {
// We cast here to avoid having to instantiate a copy of the span
const s = span;
if (s.endTimeUnixNano) {
debug("Attempting to end already ended span. Dropping...", s);
return undefined;
}
if (status) {
s.status = status;
}
s.endTimeUnixNano =
durationNano != null ? String(Math.round(parseInt(s.startTimeUnixNano) + durationNano)) : nowNanos();
return s;
}
/**
* Adds an event to a span. Can optionally accept the events timestamp and attributes for the event.
* The timestamp needs to be specified as nanoseconds since unix epoch in string format.
*/
export function addSpanEvent(span, name, attributesOrTs, attributes) {
let ts = undefined;
let attr = undefined;
if (typeof attributesOrTs === "string") {
ts = attributesOrTs;
}
else if (Array.isArray(attributesOrTs)) {
attr = attributesOrTs;
}
if (attributes) {
attr = attributes;
}
span.events.push({
name,
timeUnixNano: ts != null ? ts : nowNanos(),
attributes: attr ?? [],
});
}
export function setSpanStatus(span, code, message) {
span.status = {
code,
message,
};
}