From 73b246c7d3640b87ee92765197676f4c73e144ce Mon Sep 17 00:00:00 2001 From: kavix Date: Fri, 19 Jun 2026 02:22:13 +0530 Subject: [PATCH 1/5] feat(observability): add clickable link to component name in logs Signed-off-by: kavix --- .../src/components/RuntimeLogs/LogEntry.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx index aa0edcf2c..8c5512ecf 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx @@ -9,6 +9,8 @@ import { } from '@material-ui/core'; import FileCopyOutlined from '@material-ui/icons/FileCopyOutlined'; import { LogEntry as LogEntryType, LogEntryField } from './types'; +import { Link } from '@backstage/core-components'; +import { useLocation } from 'react-router-dom'; import { useLogEntryStyles } from './styles'; import { getColumnStyle } from './columns'; @@ -59,6 +61,7 @@ export const LogEntry: FC = ({ renderRowAction, }) => { const classes = useLogEntryStyles(); + const location = useLocation(); const [copySuccess, setCopySuccess] = useState(false); const handleCopyLog = async (event: MouseEvent) => { @@ -140,13 +143,23 @@ export const LogEntry: FC = ({ } if (field === LogEntryField.ComponentName) { + const compName = log.metadata?.componentName ?? componentName ?? ''; return ( - {log.metadata?.componentName ?? componentName ?? ''} + {compName ? ( + e.stopPropagation()} + > + {compName} + + ) : ( + '' + )} ); } From 49502d1dd157e564a4cb861191213e0d8e7c31f0 Mon Sep 17 00:00:00 2001 From: kavix Date: Fri, 19 Jun 2026 02:22:13 +0530 Subject: [PATCH 2/5] test(observability): update LogEntry tests with MemoryRouter Signed-off-by: kavix --- .../src/components/RuntimeLogs/LogEntry.test.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx index c71371266..9a17728fb 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import { MemoryRouter } from 'react-router-dom'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { LogEntry } from './LogEntry'; @@ -48,7 +49,11 @@ function renderLogEntry( expanded, onToggleExpand: () => setExpanded(prev => !prev), }; - return ; + return ( + + + + ); }; return render(); } From f1d26ab951b227cc105dc5b8c44497982e3454ea Mon Sep 17 00:00:00 2001 From: kavix Date: Fri, 19 Jun 2026 02:22:13 +0530 Subject: [PATCH 3/5] chore(observability): add changeset for clickable log components Signed-off-by: kavix --- .changeset/clickable-log-components.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/clickable-log-components.md diff --git a/.changeset/clickable-log-components.md b/.changeset/clickable-log-components.md new file mode 100644 index 000000000..85acd64a9 --- /dev/null +++ b/.changeset/clickable-log-components.md @@ -0,0 +1,5 @@ +--- +'@openchoreo/backstage-plugin-openchoreo-observability': minor +--- + +Made component names in the project-level logging view clickable, allowing users to navigate directly to the component-scoped logging view while preserving the current time range and any relevant filters. From 913888c05253a8481ee09d826fdba48511ef3443 Mon Sep 17 00:00:00 2001 From: kavix Date: Fri, 19 Jun 2026 02:33:10 +0530 Subject: [PATCH 4/5] fix(observability): use dynamic namespace and kind in log component links Signed-off-by: kavix --- .../src/components/RuntimeLogs/LogEntry.tsx | 6 +++++- .../src/components/RuntimeLogs/LogsTable.tsx | 6 ++++++ .../RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx | 2 ++ .../components/RuntimeLogs/ObservabilityRuntimeLogsPage.tsx | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx index 8c5512ecf..cfb7e5d35 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx @@ -31,6 +31,8 @@ interface LogEntryProps { environmentName?: string; projectName?: string; componentName?: string; + entityNamespace?: string; + entityKind?: string; /** * Whether this row is currently expanded. Controlled by the parent so that * expansion survives the virtualizer unmounting the row off-screen. @@ -55,6 +57,8 @@ export const LogEntry: FC = ({ environmentName, projectName, componentName, + entityNamespace, + entityKind, expanded, onToggleExpand, getLogsSnapshot, @@ -152,7 +156,7 @@ export const LogEntry: FC = ({ > {compName ? ( e.stopPropagation()} > {compName} diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogsTable.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogsTable.tsx index f332a8fbf..506f4b298 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogsTable.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogsTable.tsx @@ -21,6 +21,8 @@ interface LogsTableProps { environmentName?: string; projectName?: string; componentName?: string; + entityNamespace?: string; + entityKind?: string; renderRowAction?: RenderLogRowAction; } @@ -37,6 +39,8 @@ export const LogsTable: FC = ({ environmentName, projectName, componentName, + entityNamespace, + entityKind, renderRowAction, }) => { const classes = useLogsTableStyles(); @@ -164,6 +168,8 @@ export const LogsTable: FC = ({ environmentName={environmentName} projectName={projectName} componentName={componentName} + entityNamespace={entityNamespace} + entityKind={entityKind} expanded={expanded.has(key)} onToggleExpand={() => toggle(key)} getLogsSnapshot={getLogsSnapshot} diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx index a02a108a9..c59856328 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityProjectRuntimeLogsPage.tsx @@ -241,6 +241,8 @@ const ObservabilityProjectRuntimeLogsContent = ({ selectedEnvironment?.displayName || selectedEnvironment?.name } projectName={projectName} + entityNamespace={entity.metadata.namespace} + entityKind="component" renderRowAction={renderRowAction} /> diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityRuntimeLogsPage.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityRuntimeLogsPage.tsx index 44df01637..903a64eb6 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityRuntimeLogsPage.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/ObservabilityRuntimeLogsPage.tsx @@ -257,6 +257,8 @@ const ObservabilityRuntimeLogsContent = ({ } projectName={project} componentName={componentName} + entityNamespace={entity.metadata.namespace} + entityKind={entity.kind} renderRowAction={renderRowAction} /> From 6c65bd16d6d7b54697fd7970e17a7da6ccc1182e Mon Sep 17 00:00:00 2001 From: kavix Date: Fri, 19 Jun 2026 15:26:43 +0530 Subject: [PATCH 5/5] refactor(observability): reuse buildRuntimeLogsBasePath to derive log link and add tests Signed-off-by: kavix --- .../src/components/RuntimeLogs/LogEntry.test.tsx | 15 +++++++++++++++ .../src/components/RuntimeLogs/LogEntry.tsx | 13 ++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx index 9a17728fb..5efce186d 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.test.tsx @@ -102,6 +102,21 @@ describe('LogEntry', () => { expect(screen.getByText('api-service')).toBeInTheDocument(); }); + it('renders component name link with correct path', () => { + renderLogEntry({ + selectedFields: [...allFields, LogEntryField.ComponentName], + entityNamespace: 'my-namespace', + entityKind: 'Component', + }); + + const link = screen.getByRole('link', { name: 'api-service' }); + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute( + 'href', + '/catalog/my-namespace/component/api-service/runtime-logs', + ); + }); + it('expands to show metadata on row click', async () => { const user = userEvent.setup(); renderLogEntry(); diff --git a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx index cfb7e5d35..907a62fe3 100644 --- a/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx +++ b/plugins/openchoreo-observability/src/components/RuntimeLogs/LogEntry.tsx @@ -13,6 +13,8 @@ import { Link } from '@backstage/core-components'; import { useLocation } from 'react-router-dom'; import { useLogEntryStyles } from './styles'; import { getColumnStyle } from './columns'; +import { Entity } from '@backstage/catalog-model'; +import { buildRuntimeLogsBasePath } from '@openchoreo/backstage-plugin-react'; /** * Render-prop slot for a per-row action button (assistant integration, @@ -148,6 +150,15 @@ export const LogEntry: FC = ({ if (field === LogEntryField.ComponentName) { const compName = log.metadata?.componentName ?? componentName ?? ''; + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: entityKind || 'Component', + metadata: { + name: compName, + namespace: entityNamespace, + }, + }; + const basePath = buildRuntimeLogsBasePath(entity); return ( = ({ > {compName ? ( e.stopPropagation()} > {compName}