diff --git a/App/FeatureSet/Dashboard/src/Components/Logs/LogsViewer.tsx b/App/FeatureSet/Dashboard/src/Components/Logs/LogsViewer.tsx index d2416185cc..b80efcf3be 100644 --- a/App/FeatureSet/Dashboard/src/Components/Logs/LogsViewer.tsx +++ b/App/FeatureSet/Dashboard/src/Components/Logs/LogsViewer.tsx @@ -289,6 +289,20 @@ const DashboardLogsViewer: FunctionComponent = ( (requestData as any)["serviceIds"] = Array.from(serviceFilterValues); } + const traceFilterValues: Set | undefined = + appliedFacetFilters.get("traceId"); + + if (traceFilterValues && traceFilterValues.size > 0) { + (requestData as any)["traceIds"] = Array.from(traceFilterValues); + } + + const spanFilterValues: Set | undefined = + appliedFacetFilters.get("spanId"); + + if (spanFilterValues && spanFilterValues.size > 0) { + (requestData as any)["spanIds"] = Array.from(spanFilterValues); + } + const response: HTTPResponse = await postApi( "/telemetry/logs/histogram", requestData, @@ -716,6 +730,8 @@ const DashboardLogsViewer: FunctionComponent = ( severity: "severityText", level: "severityText", service: "serviceId", + trace: "traceId", + span: "spanId", }; const resolvedKey: string = fieldAliases[fieldKey] || fieldKey; diff --git a/Common/Server/API/TelemetryAPI.ts b/Common/Server/API/TelemetryAPI.ts index c337650765..e4f70b54f6 100644 --- a/Common/Server/API/TelemetryAPI.ts +++ b/Common/Server/API/TelemetryAPI.ts @@ -144,6 +144,14 @@ router.post( ? (body["bodySearchText"] as string) : undefined; + const traceIds: Array | undefined = body["traceIds"] + ? (body["traceIds"] as Array) + : undefined; + + const spanIds: Array | undefined = body["spanIds"] + ? (body["spanIds"] as Array) + : undefined; + const request: HistogramRequest = { projectId: databaseProps.tenantId, startTime, @@ -152,6 +160,8 @@ router.post( serviceIds, severityTexts, bodySearchText, + traceIds, + spanIds, }; const buckets: Array = @@ -218,6 +228,14 @@ router.post( ? (body["bodySearchText"] as string) : undefined; + const traceIds: Array | undefined = body["traceIds"] + ? (body["traceIds"] as Array) + : undefined; + + const spanIds: Array | undefined = body["spanIds"] + ? (body["spanIds"] as Array) + : undefined; + const facets: Record> = {}; for (const facetKey of facetKeys) { @@ -230,6 +248,8 @@ router.post( serviceIds, severityTexts, bodySearchText, + traceIds, + spanIds, }; facets[facetKey] = await LogAggregationService.getFacetValues(request); diff --git a/Common/Server/Services/LogAggregationService.ts b/Common/Server/Services/LogAggregationService.ts index 32f1149c7c..420ef26d85 100644 --- a/Common/Server/Services/LogAggregationService.ts +++ b/Common/Server/Services/LogAggregationService.ts @@ -20,6 +20,8 @@ export interface HistogramRequest { serviceIds?: Array | undefined; severityTexts?: Array | undefined; bodySearchText?: string | undefined; + traceIds?: Array | undefined; + spanIds?: Array | undefined; } export interface FacetValue { @@ -36,6 +38,8 @@ export interface FacetRequest { serviceIds?: Array | undefined; severityTexts?: Array | undefined; bodySearchText?: string | undefined; + traceIds?: Array | undefined; + spanIds?: Array | undefined; } export class LogAggregationService { @@ -179,7 +183,7 @@ export class LogAggregationService { statement: Statement, request: Pick< HistogramRequest, - "serviceIds" | "severityTexts" | "bodySearchText" + "serviceIds" | "severityTexts" | "bodySearchText" | "traceIds" | "spanIds" >, ): void { if (request.serviceIds && request.serviceIds.length > 0) { @@ -197,6 +201,22 @@ export class LogAggregationService { statement.append(` AND severityText IN (${sevStrings.join(",")})`); } + if (request.traceIds && request.traceIds.length > 0) { + const traceStrings: Array = request.traceIds.map( + (s: string): string => + `'${LogAggregationService.escapeSingleQuotes(s)}'`, + ); + statement.append(` AND traceId IN (${traceStrings.join(",")})`); + } + + if (request.spanIds && request.spanIds.length > 0) { + const spanStrings: Array = request.spanIds.map( + (s: string): string => + `'${LogAggregationService.escapeSingleQuotes(s)}'`, + ); + statement.append(` AND spanId IN (${spanStrings.join(",")})`); + } + if (request.bodySearchText && request.bodySearchText.trim().length > 0) { statement.append(` AND body ILIKE ${{ type: TableColumnType.Text, diff --git a/Common/UI/Components/LogsViewer/components/LogSearchBar.tsx b/Common/UI/Components/LogsViewer/components/LogSearchBar.tsx index 495ab52de8..bbdf473fb9 100644 --- a/Common/UI/Components/LogsViewer/components/LogSearchBar.tsx +++ b/Common/UI/Components/LogsViewer/components/LogSearchBar.tsx @@ -328,6 +328,8 @@ const FIELD_ALIAS_MAP: Record = { severity: "severityText", level: "severityText", service: "serviceId", + trace: "traceId", + span: "spanId", }; function getValueSuggestions( diff --git a/Common/UI/Components/LogsViewer/components/LogSearchHelp.tsx b/Common/UI/Components/LogsViewer/components/LogSearchHelp.tsx index ab955cd90d..b6ee576b4b 100644 --- a/Common/UI/Components/LogsViewer/components/LogSearchHelp.tsx +++ b/Common/UI/Components/LogsViewer/components/LogSearchHelp.tsx @@ -31,6 +31,16 @@ const HELP_ROWS: Array = [ description: "Filter by service", example: "service:api", }, + { + syntax: "trace:", + description: "Filter by trace ID", + example: "trace:abc123def456", + }, + { + syntax: "span:", + description: "Filter by span ID", + example: "span:e1f7f671fe78", + }, { syntax: "@:", description: "Filter by attribute",