diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts index 2ae104666f..bed1fe6f50 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.ts @@ -140,7 +140,7 @@ export class DefaultCatalogProcessingEngine implements CatalogProcessingEngine { processTask: async item => { await withActiveSpan(tracer, 'ProcessingRun', async span => { const track = this.tracker.processStart(item, this.logger); - addEntityAttributes(span, item.entityRef); + addEntityAttributes(span, item.unprocessedEntity); try { const { diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts index 98f9cd32a5..c5eaacbc68 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.ts @@ -200,7 +200,7 @@ export class DefaultCatalogProcessingOrchestrator context: Context, ): Promise { return await withActiveSpan(tracer, 'ProcessingStage', async stageSpan => { - addEntityAttributes(stageSpan, context.entityRef); + addEntityAttributes(stageSpan, entity); stageSpan.setAttribute('backstage.catalog.processor.stage', 'preProcess'); let res = entity; @@ -208,7 +208,7 @@ export class DefaultCatalogProcessingOrchestrator if (processor.preProcessEntity) { let innerRes = res; res = await withActiveSpan(tracer, 'ProcessingStep', async span => { - addEntityAttributes(span, context.entityRef); + addEntityAttributes(span, entity); addProcessorAttributes(span, 'preProcessEntity', processor); try { innerRes = await processor.preProcessEntity!( @@ -238,7 +238,7 @@ export class DefaultCatalogProcessingOrchestrator */ private async runPolicyStep(entity: Entity): Promise { return await withActiveSpan(tracer, 'ProcessingStage', async stageSpan => { - addEntityAttributes(stageSpan, stringifyEntityRef(entity)); + addEntityAttributes(stageSpan, entity); stageSpan.setAttribute( 'backstage.catalog.processor.stage', 'enforcePolicy', @@ -274,7 +274,7 @@ export class DefaultCatalogProcessingOrchestrator context: Context, ): Promise { return await withActiveSpan(tracer, 'ProcessingStage', async stageSpan => { - addEntityAttributes(stageSpan, context.entityRef); + addEntityAttributes(stageSpan, entity); stageSpan.setAttribute('backstage.catalog.processor.stage', 'validate'); // Double check that none of the previous steps tried to change something // related to the entity ref, which would break downstream @@ -303,7 +303,7 @@ export class DefaultCatalogProcessingOrchestrator tracer, 'ProcessingStep', async span => { - addEntityAttributes(span, context.entityRef); + addEntityAttributes(span, entity); addProcessorAttributes(span, 'validateEntityKind', processor); return await processor.validateEntityKind!(entity); }, @@ -339,7 +339,7 @@ export class DefaultCatalogProcessingOrchestrator context: Context, ): Promise { return await withActiveSpan(tracer, 'ProcessingStage', async stageSpan => { - addEntityAttributes(stageSpan, context.entityRef); + addEntityAttributes(stageSpan, entity); stageSpan.setAttribute( 'backstage.catalog.processor.stage', 'readLocation', @@ -379,7 +379,7 @@ export class DefaultCatalogProcessingOrchestrator tracer, 'ProcessingStep', async span => { - addEntityAttributes(span, context.entityRef); + addEntityAttributes(span, entity); addProcessorAttributes(span, 'readLocation', processor); return await processor.readLocation!( { @@ -423,7 +423,7 @@ export class DefaultCatalogProcessingOrchestrator context: Context, ): Promise { return await withActiveSpan(tracer, 'ProcessingStage', async stageSpan => { - addEntityAttributes(stageSpan, context.entityRef); + addEntityAttributes(stageSpan, entity); stageSpan.setAttribute( 'backstage.catalog.processor.stage', 'postProcessEntity', @@ -434,7 +434,7 @@ export class DefaultCatalogProcessingOrchestrator if (processor.postProcessEntity) { let innerRes = res; res = await withActiveSpan(tracer, 'ProcessingStep', async span => { - addEntityAttributes(span, context.entityRef); + addEntityAttributes(span, entity); addProcessorAttributes(span, 'postProcessEntity', processor); try { innerRes = await processor.postProcessEntity!( diff --git a/plugins/catalog-backend/src/util/opentelemetry.ts b/plugins/catalog-backend/src/util/opentelemetry.ts index 391869deb8..c2df008452 100644 --- a/plugins/catalog-backend/src/util/opentelemetry.ts +++ b/plugins/catalog-backend/src/util/opentelemetry.ts @@ -15,22 +15,31 @@ */ import { Span, SpanOptions, SpanStatusCode, Tracer } from '@opentelemetry/api'; -import { parseEntityRef } from '@backstage/catalog-model'; +import { Entity } from '@backstage/catalog-model'; export const TRACER_ID = 'backstage-plugin-catalog-backend'; -export function addEntityAttributes(span: Span, entityRef: string) { - try { - const fields = parseEntityRef(entityRef); - span.setAttribute('backstage.entity.kind', fields.kind); - span.setAttribute('backstage.entity.namespace', fields.namespace); - span.setAttribute('backstage.entity.name', fields.name); - } catch (err) { - span.recordException(err); - span.setStatus({ code: SpanStatusCode.ERROR }); +function setAttributeIfDefined(span: Span, attribute: string, value?: string) { + if (value !== null && value !== undefined) { + span.setAttribute(attribute, value); } } +export function addEntityAttributes(span: Span, entity: Entity) { + setAttributeIfDefined(span, 'backstage.entity.apiVersion', entity.apiVersion); + setAttributeIfDefined(span, 'backstage.entity.kind', entity.kind); + setAttributeIfDefined( + span, + 'backstage.entity.metadata.namespace', + entity.metadata?.namespace, + ); + setAttributeIfDefined( + span, + 'backstage.entity.metadata.name', + entity.metadata?.name, + ); +} + // Adapted from https://github.com/open-telemetry/opentelemetry-js/blob/359fbcc40a859057a02b14e84599eac399b8dba7/api/src/trace/SugaredTracer.ts // While waiting for something like https://github.com/open-telemetry/opentelemetry-js/pull/3317 to land upstream