From 90b572e4a3e21e6cc7bb34329f68ad0e6982c093 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Tue, 28 Apr 2026 17:17:26 +0200 Subject: [PATCH] Add alpha TracingService API Signed-off-by: Eric Peterson --- .changeset/backend-tracing-and-stuff.md | 5 + .../backend-plugin-api/report-alpha.api.md | 64 ++++++++++ .../src/alpha/TracingService.ts | 109 ++++++++++++++++++ .../backend-plugin-api/src/alpha/index.ts | 11 ++ packages/backend-plugin-api/src/alpha/refs.ts | 13 +++ 5 files changed, 202 insertions(+) create mode 100644 .changeset/backend-tracing-and-stuff.md create mode 100644 packages/backend-plugin-api/src/alpha/TracingService.ts diff --git a/.changeset/backend-tracing-and-stuff.md b/.changeset/backend-tracing-and-stuff.md new file mode 100644 index 0000000000..0909a5c250 --- /dev/null +++ b/.changeset/backend-tracing-and-stuff.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Adds an alpha `TracingService` to provide a unified interface for emitting trace spans across Backstage plugins. diff --git a/packages/backend-plugin-api/report-alpha.api.md b/packages/backend-plugin-api/report-alpha.api.md index d1db9c7eeb..0603f4310e 100644 --- a/packages/backend-plugin-api/report-alpha.api.md +++ b/packages/backend-plugin-api/report-alpha.api.md @@ -10,6 +10,7 @@ import { JsonObject } from '@backstage/types'; import { JSONSchema7 } from 'json-schema'; import { JsonValue } from '@backstage/types'; import { LoggerService } from '@backstage/backend-plugin-api'; +import type { Request as Request_2 } from 'express'; import { ServiceRef } from '@backstage/backend-plugin-api'; import { z } from 'zod/v3'; @@ -289,5 +290,68 @@ export const rootSystemMetadataServiceRef: ServiceRef< 'singleton' >; +// @alpha +export interface TracingService { + startActiveSpan( + name: string, + fn: (span: TracingServiceSpan) => T | Promise, + options?: TracingServiceSpanOptions, + ): Promise; +} + +// @alpha +export interface TracingServiceAttributes { + // (undocumented) + [key: string]: TracingServiceAttributeValue | undefined; +} + +// @alpha +export type TracingServiceAttributeValue = + | string + | number + | boolean + | Array + | Array + | Array; + +// @alpha +export const tracingServiceRef: ServiceRef< + TracingService, + 'plugin', + 'singleton' +>; + +// @alpha +export interface TracingServiceSpan { + // (undocumented) + setAttribute(key: string, value: TracingServiceAttributeValue): void; + // (undocumented) + setStatus(status: TracingServiceSpanStatus): void; +} + +// @alpha +export type TracingServiceSpanKind = + | 'internal' + | 'server' + | 'client' + | 'producer' + | 'consumer'; + +// @alpha +export interface TracingServiceSpanOptions { + attributes?: TracingServiceAttributes; + credentials?: BackstageCredentials; + kind?: TracingServiceSpanKind; + request?: Request_2; +} + +// @alpha +export interface TracingServiceSpanStatus { + // (undocumented) + code: 'unset' | 'ok' | 'error'; + // (undocumented) + message?: string; +} + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-plugin-api/src/alpha/TracingService.ts b/packages/backend-plugin-api/src/alpha/TracingService.ts new file mode 100644 index 0000000000..e0ccf26116 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/TracingService.ts @@ -0,0 +1,109 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Request } from 'express'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; + +/** + * Attribute values that can be attached to spans. + * + * @alpha + */ +export type TracingServiceAttributeValue = + | string + | number + | boolean + | Array + | Array + | Array; + +/** + * A set of key-value pairs that can be attached to spans. + * + * @alpha + */ +export interface TracingServiceAttributes { + [key: string]: TracingServiceAttributeValue | undefined; +} + +/** + * The kind of operation a span represents. + * + * @alpha + */ +export type TracingServiceSpanKind = + | 'internal' + | 'server' + | 'client' + | 'producer' + | 'consumer'; + +/** + * The status of a span. + * + * @alpha + */ +export interface TracingServiceSpanStatus { + code: 'unset' | 'ok' | 'error'; + message?: string; +} + +/** + * A trace span. Provided to `startActiveSpan` so + * additional attributes or status can be set from within the callback. + * + * @alpha + */ +export interface TracingServiceSpan { + setAttribute(key: string, value: TracingServiceAttributeValue): void; + setStatus(status: TracingServiceSpanStatus): void; +} + +/** + * Options for `startActiveSpan`. + * + * @alpha + */ +export interface TracingServiceSpanOptions { + /** Attributes to attach to the span. */ + attributes?: TracingServiceAttributes; + /** The kind of span. */ + kind?: TracingServiceSpanKind; + /** + * Authenticated principal source for span enrichment. Preferred when + * both `credentials` and `request` are supplied. + */ + credentials?: BackstageCredentials; + /** HTTP request to extract credentials from for span enrichment. */ + request?: Request; +} + +/** + * A service for emitting trace spans from a backend plugin. + * + * @alpha + */ +export interface TracingService { + /** + * Runs `fn` inside a new active span. The span is finished when `fn` + * resolves or throws. + */ + startActiveSpan( + name: string, + fn: (span: TracingServiceSpan) => T | Promise, + options?: TracingServiceSpanOptions, + ): Promise; +} diff --git a/packages/backend-plugin-api/src/alpha/index.ts b/packages/backend-plugin-api/src/alpha/index.ts index 9ec7ca5b09..4e1e73f23e 100644 --- a/packages/backend-plugin-api/src/alpha/index.ts +++ b/packages/backend-plugin-api/src/alpha/index.ts @@ -46,9 +46,20 @@ export type { MetricsServiceObservableUpDownCounter, } from './MetricsService'; +export type { + TracingService, + TracingServiceAttributeValue, + TracingServiceAttributes, + TracingServiceSpan, + TracingServiceSpanKind, + TracingServiceSpanOptions, + TracingServiceSpanStatus, +} from './TracingService'; + export { actionsRegistryServiceRef, actionsServiceRef, metricsServiceRef, rootSystemMetadataServiceRef, + tracingServiceRef, } from './refs'; diff --git a/packages/backend-plugin-api/src/alpha/refs.ts b/packages/backend-plugin-api/src/alpha/refs.ts index bd87ea8467..967fce6344 100644 --- a/packages/backend-plugin-api/src/alpha/refs.ts +++ b/packages/backend-plugin-api/src/alpha/refs.ts @@ -67,3 +67,16 @@ export const metricsServiceRef = createServiceRef< >({ id: 'alpha.core.metrics', }); + +/** + * Service for managing trace spans. + * + * See {@link TracingService} for the API surface. + * + * @alpha + */ +export const tracingServiceRef = createServiceRef< + import('./TracingService').TracingService +>({ + id: 'alpha.core.tracing', +});