diff --git a/packages/grafana-data/src/types/logs.ts b/packages/grafana-data/src/types/logs.ts index b6b2531ea2e..c30d7e4dcf4 100644 --- a/packages/grafana-data/src/types/logs.ts +++ b/packages/grafana-data/src/types/logs.ts @@ -78,6 +78,7 @@ export interface LogRowModel { timeUtc: string; uid: string; uniqueLabels?: Labels; + datasourceType?: string; } export interface LogsModel { diff --git a/public/app/core/logsModel.ts b/public/app/core/logsModel.ts index bcf902b2779..a0b0c0c9e4c 100644 --- a/public/app/core/logsModel.ts +++ b/public/app/core/logsModel.ts @@ -207,7 +207,7 @@ export function dataFrameToLogsModel( queries?: DataQuery[] ): LogsModel { const { logSeries } = separateLogsAndMetrics(dataFrame); - const logsModel = logSeriesToLogsModel(logSeries); + const logsModel = logSeriesToLogsModel(logSeries, queries); if (logsModel) { // Create histogram metrics from logs using the interval as bucket size for the line count @@ -346,7 +346,7 @@ function getLabelsForFrameRow(fields: LogFields, index: number): Labels { * Converts dataFrames into LogsModel. This involves merging them into one list, sorting them and computing metadata * like common labels. */ -export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel | undefined { +export function logSeriesToLogsModel(logSeries: DataFrame[], queries: DataQuery[] = []): LogsModel | undefined { if (logSeries.length === 0) { return undefined; } @@ -432,6 +432,8 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel | undefi logLevel = getLogLevel(entry); } + const datasourceType = queries.find((query) => query.refId === series.refId)?.datasource?.type; + rows.push({ entryFieldIndex: stringField.index, rowIndex: j, @@ -450,6 +452,7 @@ export function logSeriesToLogsModel(logSeries: DataFrame[]): LogsModel | undefi raw: message, labels: labels || {}, uid: idField ? idField.values.get(j) : j.toString(), + datasourceType, }); } } diff --git a/public/app/features/logs/components/LogRow.tsx b/public/app/features/logs/components/LogRow.tsx index f7fd3a91479..c6fdaa94c5d 100644 --- a/public/app/features/logs/components/LogRow.tsx +++ b/public/app/features/logs/components/LogRow.tsx @@ -12,6 +12,7 @@ import { GrafanaTheme2, CoreApp, } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { styleMixins, withTheme2, Themeable2, Icon, Tooltip } from '@grafana/ui'; import { checkLogsError, escapeUnescapedString } from '../utils'; @@ -108,6 +109,14 @@ class UnThemedLogRow extends PureComponent { if (!this.props.enableLogDetails) { return; } + + reportInteraction('grafana_explore_logs_log_details_clicked', { + datasourceType: this.props.row.datasourceType, + type: this.state.showDetails ? 'close' : 'open', + logRowUid: this.props.row.uid, + app: this.props.app, + }); + this.setState((state) => { return { showDetails: !state.showDetails, diff --git a/public/app/plugins/panel/logs/LogsPanel.tsx b/public/app/plugins/panel/logs/LogsPanel.tsx index 0a970f00f26..60c8d7af9b2 100644 --- a/public/app/plugins/panel/logs/LogsPanel.tsx +++ b/public/app/plugins/panel/logs/LogsPanel.tsx @@ -66,9 +66,11 @@ export const LogsPanel: React.FunctionComponent = ({ // Important to memoize stuff here, as panel rerenders a lot for example when resizing. const [logRows, deduplicatedRows, commonLabels] = useMemo(() => { - const newResults = data ? dataFrameToLogsModel(data.series, data.request?.intervalMs) : null; - const logRows = newResults?.rows || []; - const commonLabels = newResults?.meta?.find((m) => m.label === COMMON_LABELS); + const logs = data + ? dataFrameToLogsModel(data.series, data.request?.intervalMs, undefined, data.request?.targets) + : null; + const logRows = logs?.rows || []; + const commonLabels = logs?.meta?.find((m) => m.label === COMMON_LABELS); const deduplicatedRows = dedupLogRows(logRows, dedupStrategy); return [logRows, deduplicatedRows, commonLabels]; }, [data, dedupStrategy]);