From c0a866d7c7aeec3eddaf16eeb9db9a445d7c5d68 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:02:32 +0100 Subject: [PATCH] Logs: For LogLines frames, don't show additional fields in log details (#78109) * Logs: Don't use other fields in log details for log details * Reorder variables * Update comment * Update comment --- .../logs/components/LogDetails.test.tsx | 73 ++++++++++++++++++- .../features/logs/components/LogDetails.tsx | 14 ++-- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/public/app/features/logs/components/LogDetails.test.tsx b/public/app/features/logs/components/LogDetails.test.tsx index 00e6aef9683..c10c35277e0 100644 --- a/public/app/features/logs/components/LogDetails.test.tsx +++ b/public/app/features/logs/components/LogDetails.test.tsx @@ -2,7 +2,16 @@ import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; -import { Field, LogLevel, LogRowModel, MutableDataFrame, createTheme, FieldType } from '@grafana/data'; +import { + Field, + LogLevel, + LogRowModel, + MutableDataFrame, + createTheme, + FieldType, + createDataFrame, + DataFrameType, +} from '@grafana/data'; import { LogDetails, Props } from './LogDetails'; import { createLogRow } from './__mocks__/logRow'; @@ -173,4 +182,66 @@ describe('LogDetails', () => { expect(link).toBeInTheDocument(); expect(link).toHaveAttribute('href', 'localhost:3210/1234'); }); + + it('should show correct log details fields, links and labels for DataFrameType.LogLines frames', () => { + const entry = 'test'; + const dataFrame = createDataFrame({ + fields: [ + { name: 'timestamp', config: {}, type: FieldType.time, values: [1] }, + { name: 'body', type: FieldType.string, values: [entry] }, + { + name: 'labels', + type: FieldType.other, + values: [ + { + label1: 'value1', + }, + ], + }, + { + name: 'shouldNotShowFieldName', + type: FieldType.string, + values: ['shouldNotShowFieldValue'], + }, + { + name: 'shouldShowLinkName', + type: FieldType.string, + values: ['shouldShowLinkValue'], + config: { links: [{ title: 'link', url: 'localhost:3210/${__value.text}' }] }, + }, + ], + meta: { + type: DataFrameType.LogLines, + }, + }); + + setup( + { + getFieldLinks: (field: Field, rowIndex: number) => { + if (field.config && field.config.links) { + return field.config.links.map((link) => { + return { + href: link.url.replace('${__value.text}', field.values[rowIndex]), + title: link.title, + target: '_blank', + origin: field, + }; + }); + } + return []; + }, + }, + { entry, dataFrame, entryFieldIndex: 0, rowIndex: 0, labels: { label1: 'value1' } } + ); + + // Don't show additional fields for DataFrameType.LogLines + expect(screen.queryByText('shouldNotShowFieldName')).not.toBeInTheDocument(); + expect(screen.queryByText('shouldNotShowFieldValue')).not.toBeInTheDocument(); + + // Show labels and links + expect(screen.getByText('label1')).toBeInTheDocument(); + expect(screen.getByText('value1')).toBeInTheDocument(); + expect(screen.getByText('shouldShowLinkName')).toBeInTheDocument(); + expect(screen.getByText('shouldShowLinkValue')).toBeInTheDocument(); + }); }); diff --git a/public/app/features/logs/components/LogDetails.tsx b/public/app/features/logs/components/LogDetails.tsx index ecd529407a3..3233d03d0e7 100644 --- a/public/app/features/logs/components/LogDetails.tsx +++ b/public/app/features/logs/components/LogDetails.tsx @@ -1,7 +1,7 @@ import { cx } from '@emotion/css'; import React, { PureComponent } from 'react'; -import { CoreApp, DataFrame, Field, LinkModel, LogRowModel } from '@grafana/data'; +import { CoreApp, DataFrame, DataFrameType, Field, LinkModel, LogRowModel } from '@grafana/data'; import { Themeable2, withTheme2 } from '@grafana/ui'; import { calculateLogsLabelStats, calculateStats } from '../utils'; @@ -56,14 +56,18 @@ class UnThemedLogDetails extends PureComponent { const displayedFieldsWithLinks = fieldsWithLinks.filter((f) => f.fieldIndex !== row.entryFieldIndex).sort(); const hiddenFieldsWithLinks = fieldsWithLinks.filter((f) => f.fieldIndex === row.entryFieldIndex).sort(); const fieldsWithLinksFromVariableMap = createLogLineLinks(hiddenFieldsWithLinks); - - // do not show the log message unless there is a link attached - const fields = fieldsAndLinks.filter((f) => f.links?.length === 0 && f.fieldIndex !== row.entryFieldIndex).sort(); - const fieldsAvailable = fields && fields.length > 0; const fieldsWithLinksAvailable = (displayedFieldsWithLinks && displayedFieldsWithLinks.length > 0) || (fieldsWithLinksFromVariableMap && fieldsWithLinksFromVariableMap.length > 0); + const fields = + row.dataFrame.meta?.type === DataFrameType.LogLines + ? // for LogLines frames (dataplane) we don't want to show any additional fields besides already extracted labels and links + [] + : // for other frames, do not show the log message unless there is a link attached + fieldsAndLinks.filter((f) => f.links?.length === 0 && f.fieldIndex !== row.entryFieldIndex).sort(); + const fieldsAvailable = fields && fields.length > 0; + // If logs with error, we are not showing the level color const levelClassName = hasError ? ''