| 172 | // This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility. |
| 173 | // And `spanToJSON` needs the Span class from `span.ts` to check here. |
| 174 | export function spanToJSON(span: Span): SpanJSON { |
| 175 | if (spanIsSentrySpan(span)) { |
| 176 | return span.getSpanJSON(); |
| 177 | } |
| 178 | |
| 179 | const { spanId: span_id, traceId: trace_id } = span.spanContext(); |
| 180 | |
| 181 | // Handle a span from @opentelemetry/sdk-base-trace's `Span` class |
| 182 | if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) { |
| 183 | const { attributes, startTime, name, endTime, status, links } = span; |
| 184 | |
| 185 | return { |
| 186 | span_id, |
| 187 | trace_id, |
| 188 | data: attributes, |
| 189 | description: name, |
| 190 | parent_span_id: getOtelParentSpanId(span), |
| 191 | start_timestamp: spanTimeInputToSeconds(startTime), |
| 192 | // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time |
| 193 | timestamp: spanTimeInputToSeconds(endTime) || undefined, |
| 194 | status: getStatusMessage(status), |
| 195 | op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP], |
| 196 | origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined, |
| 197 | links: convertSpanLinksForEnvelope(links), |
| 198 | }; |
| 199 | } |
| 200 | |
| 201 | // Finally, at least we have `spanContext()`.... |
| 202 | // This should not actually happen in reality, but we need to handle it for type safety. |
| 203 | return { |
| 204 | span_id, |
| 205 | trace_id, |
| 206 | start_timestamp: 0, |
| 207 | data: {}, |
| 208 | }; |
| 209 | } |
| 210 | |
| 211 | /** |
| 212 | * Convert a span to the intermediate {@link StreamedSpanJSON} representation. |