From 2d10f2d15ec9f360efa11afceb9a65e193203ccd Mon Sep 17 00:00:00 2001 From: Jacob Rosborg Date: Sat, 17 Aug 2024 00:15:20 +0200 Subject: [PATCH] fix(trace): show status of span in trace pannel --- README.md | 3 ++- src/dashboards/opentelemetry-clickhouse.json | 4 ++++ src/data/sqlGenerator.test.ts | 8 ++++++-- src/data/sqlGenerator.ts | 5 +++++ src/otel.ts | 1 + src/types/queryBuilder.ts | 1 + 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eb1b3f96..55251b8d 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,8 @@ SELECT Duration / 1000000 AS duration, Timestamp AS startTime, arrayMap(key -> map('key', key, 'value', SpanAttributes[key]), mapKeys(SpanAttributes)) AS tags, - arrayMap(key -> map('key', key, 'value', ResourceAttributes[key]), mapKeys(ResourceAttributes)) AS serviceTags + arrayMap(key -> map('key', key, 'value', ResourceAttributes[key]), mapKeys(ResourceAttributes)) AS serviceTags, + if(StatusCode = 'STATUS_CODE_ERROR', 2, 0) AS statusCode FROM otel.otel_traces WHERE TraceId = '61d489320c01243966700e172ab37081' ORDER BY startTime ASC diff --git a/src/dashboards/opentelemetry-clickhouse.json b/src/dashboards/opentelemetry-clickhouse.json index 5bec4ba3..66dda463 100644 --- a/src/dashboards/opentelemetry-clickhouse.json +++ b/src/dashboards/opentelemetry-clickhouse.json @@ -728,6 +728,10 @@ { "hint": "trace_service_tags", "name": "ResourceAttributes" + }, + { + "hint": "trace_status_code", + "name": "StatusCode" } ], "database": "default", diff --git a/src/data/sqlGenerator.test.ts b/src/data/sqlGenerator.test.ts index 4e1a5651..6520dc3a 100644 --- a/src/data/sqlGenerator.test.ts +++ b/src/data/sqlGenerator.test.ts @@ -196,6 +196,7 @@ describe('SQL Generator', () => { { name: 'Duration', type: 'Int64', hint: ColumnHint.TraceDurationTime }, { name: 'SpanAttributes', type: 'Map(LowCardinality(String), String)', hint: ColumnHint.TraceTags }, { name: 'ResourceAttributes', type: 'Map(LowCardinality(String), String)', hint: ColumnHint.TraceServiceTags }, + { name: 'StatusCode', type: 'LowCardinality(String)', hint: ColumnHint.TraceStatusCode }, ], filters: [], meta: { @@ -215,7 +216,8 @@ describe('SQL Generator', () => { 'multiply("Duration", 0.000001) as duration,', `arrayMap(key -> map('key', key, 'value',"SpanAttributes"[key]),`, `mapKeys("SpanAttributes")) as tags,`, - `arrayMap(key -> map('key', key, 'value',"ResourceAttributes"[key]), mapKeys("ResourceAttributes")) as serviceTags`, + `arrayMap(key -> map('key', key, 'value',"ResourceAttributes"[key]), mapKeys("ResourceAttributes")) as serviceTags,`, + `if("StatusCode" = 'STATUS_CODE_ERROR', 2, 0) as statusCode`, `FROM "default"."otel_traces" WHERE traceID = 'abcdefg'`, 'LIMIT 1000' ]; @@ -239,6 +241,7 @@ describe('SQL Generator', () => { { name: 'Duration', type: 'Int64', hint: ColumnHint.TraceDurationTime }, { name: 'SpanAttributes', type: 'Map(LowCardinality(String), String)', hint: ColumnHint.TraceTags }, { name: 'ResourceAttributes', type: 'Map(LowCardinality(String), String)', hint: ColumnHint.TraceServiceTags }, + { name: 'StatusCode', type: 'LowCardinality(String)', hint: ColumnHint.TraceStatusCode }, ], filters: [], meta: { @@ -260,7 +263,8 @@ describe('SQL Generator', () => { 'multiply("Duration", 0.000001) as duration,', `arrayMap(key -> map('key', key, 'value',"SpanAttributes"[key]),`, `mapKeys("SpanAttributes")) as tags,`, - `arrayMap(key -> map('key', key, 'value',"ResourceAttributes"[key]), mapKeys("ResourceAttributes")) as serviceTags`, + `arrayMap(key -> map('key', key, 'value',"ResourceAttributes"[key]), mapKeys("ResourceAttributes")) as serviceTags,`, + `if("StatusCode" = 'STATUS_CODE_ERROR', 2, 0) as statusCode`, `FROM "default"."otel_traces" WHERE traceID = trace_id AND "Timestamp" >= trace_start AND "Timestamp" <= trace_end`, 'LIMIT 1000' ]; diff --git a/src/data/sqlGenerator.ts b/src/data/sqlGenerator.ts index 45abfdc0..e9145cf2 100644 --- a/src/data/sqlGenerator.ts +++ b/src/data/sqlGenerator.ts @@ -144,6 +144,11 @@ const generateTraceIdQuery = (options: QueryBuilderOptions): string => { if (traceServiceTags !== undefined) { selectParts.push(`arrayMap(key -> map('key', key, 'value',${escapeIdentifier(traceServiceTags.name)}[key]), mapKeys(${escapeIdentifier(traceServiceTags.name)})) as serviceTags`); } + + const traceServiceStatusCode = getColumnByHint(options, ColumnHint.TraceStatusCode); + if (traceServiceTags !== undefined) { + selectParts.push(`if(${escapeIdentifier(traceServiceStatusCode.name)} = 'STATUS_CODE_ERROR', 2, 0) as statusCode`); + } const selectPartsSql = selectParts.join(', '); // Optimize trace ID filtering for OTel enabled trace lookups diff --git a/src/otel.ts b/src/otel.ts index da756d11..54631b6e 100644 --- a/src/otel.ts +++ b/src/otel.ts @@ -47,6 +47,7 @@ const otel129: OtelVersion = { [ColumnHint.TraceDurationTime, 'Duration'], [ColumnHint.TraceTags, 'SpanAttributes'], [ColumnHint.TraceServiceTags, 'ResourceAttributes'], + [ColumnHint.TraceStatusCode, 'StatusCode'], ]), traceDurationUnit: TimeUnit.Nanoseconds, }; diff --git a/src/types/queryBuilder.ts b/src/types/queryBuilder.ts index dbc4d326..7a7755a1 100644 --- a/src/types/queryBuilder.ts +++ b/src/types/queryBuilder.ts @@ -131,6 +131,7 @@ export enum ColumnHint { TraceDurationTime = 'trace_duration_time', TraceTags = 'trace_tags', TraceServiceTags = 'trace_service_tags', + TraceStatusCode = 'trace_status_code', } /**