From 37fcfce07c88492d59f3224b6321973165530a76 Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Thu, 18 Jun 2026 08:45:11 +0200 Subject: [PATCH] feat(logs): show query and details in unified PG log dashboards DEBUG-138 (#47026) ## Problem The unified log dashboards' Postgres detail panel hid the `query` and `detail` fields. They were present in the raw log message but never surfaced in the structured view, making them harder to use when debugging. ## Fix - Select `pgl_parsed.query` and `pgl_parsed.detail` in the Postgres service flow query. - Add `Query` and `Details` field configs to the Postgres primary fields, both with `wrap: true` so long values display in full instead of truncating. The parsed Postgres field is `detail` (singular); it is labeled "Details" in the UI. ## How to test - Open Studio and navigate to the unified logs dashboard for a project. - Filter to Postgres logs and select a log row to open the detail panel. - Confirm the Postgres section now shows `Query` and `Details` rows below `User`. - Expected result: rows render the parsed query and detail text, wrapping for long values, and show an em dash when empty. ## Summary by CodeRabbit * **New Features** * PostgreSQL service flow logs now show additional always-visible **Query** and **Details** fields, bringing parsed database query content and expanded information directly into the log view. * **Tests** * Updated log inspection coverage to ensure the new parsed fields are correctly surfaced in the flattened inspection output. --------- Co-authored-by: Claude Opus 4.8 (1M context) --- .../Queries/ServiceFlowQueries/ServiceFlow.sql.ts | 2 ++ .../ServiceFlow/config/serviceFlowFields.ts | 14 ++++++++++++++ .../studio/data/logs/otel-inspection.utils.test.ts | 4 ++++ apps/studio/data/logs/otel-inspection.utils.ts | 2 ++ 4 files changed, 22 insertions(+) diff --git a/apps/studio/components/interfaces/UnifiedLogs/Queries/ServiceFlowQueries/ServiceFlow.sql.ts b/apps/studio/components/interfaces/UnifiedLogs/Queries/ServiceFlowQueries/ServiceFlow.sql.ts index c934107dbbc..24a9cf57c16 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/Queries/ServiceFlowQueries/ServiceFlow.sql.ts +++ b/apps/studio/components/interfaces/UnifiedLogs/Queries/ServiceFlowQueries/ServiceFlow.sql.ts @@ -376,6 +376,8 @@ export const getPostgresServiceFlowQuery = (logId: string): SafeLogSqlFragment = pgl_parsed.command_tag as command_tag, pgl_parsed.backend_type as backend_type, pgl_parsed.query_id as query_id, + pgl_parsed.query as query, + pgl_parsed.detail as detail, -- Session details pgl_parsed.session_id as session_id, diff --git a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/serviceFlowFields.ts b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/serviceFlowFields.ts index 1765a13e518..8ced27727be 100644 --- a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/serviceFlowFields.ts +++ b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/serviceFlowFields.ts @@ -673,6 +673,20 @@ export const postgresPrimaryFields: BlockFieldConfig[] = [ getValue: (data, enrichedData) => enrichedData?.database_user || data?.database_user, requiresEnrichedData: true, }, + { + id: 'query', + label: 'Query', + getValue: (data, enrichedData) => enrichedData?.query || data?.query, + requiresEnrichedData: true, + wrap: true, + }, + { + id: 'detail', + label: 'Details', + getValue: (data, enrichedData) => enrichedData?.detail || data?.detail, + requiresEnrichedData: true, + wrap: true, + }, ] // Postgres Details (Collapsible) diff --git a/apps/studio/data/logs/otel-inspection.utils.test.ts b/apps/studio/data/logs/otel-inspection.utils.test.ts index 458d6745c20..597c0d373b8 100644 --- a/apps/studio/data/logs/otel-inspection.utils.test.ts +++ b/apps/studio/data/logs/otel-inspection.utils.test.ts @@ -60,6 +60,8 @@ const pgRow: OtelLogRow = { 'parsed.transaction_id': '0', 'parsed.virtual_transaction_id': '3/0', 'parsed.sql_state_code': '00000', + 'parsed.query': 'select * from test_broken limit 10000;', + 'parsed.detail': 'Key (id)=(1) is not present in table "parent".', }, } @@ -101,6 +103,8 @@ describe('flattenOtelInspectionRow', () => { expect(e.transaction_id).toBe('0') expect(e.error_severity).toBe('LOG') expect(e.sql_state_code).toBe('00000') + expect(e.query).toBe('select * from test_broken limit 10000;') + expect(e.detail).toBe('Key (id)=(1) is not present in table "parent".') expect(e.level).toBe('success') }) diff --git a/apps/studio/data/logs/otel-inspection.utils.ts b/apps/studio/data/logs/otel-inspection.utils.ts index db0d6631432..125d9ebb512 100644 --- a/apps/studio/data/logs/otel-inspection.utils.ts +++ b/apps/studio/data/logs/otel-inspection.utils.ts @@ -124,6 +124,8 @@ export function flattenOtelInspectionRow( database_name: attrs['parsed.database_name'] ?? null, database_user: attrs['parsed.user_name'] ?? null, process_id: attrs['parsed.process_id'] ?? null, + query: attrs['parsed.query'] ?? null, + detail: attrs['parsed.detail'] ?? null, query_id: attrs['parsed.query_id'] ?? null, session_id: attrs['parsed.session_id'] ?? null, session_start_time: attrs['parsed.session_start_time'] ?? null,