mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
logs: merge log-lines-based and full-range histogram (#50507)
* logs: merge old-histogram and new-histogram * better variable names * better names * refactor * refactor * refactor * logs: remove log-volume-loading indicator
This commit is contained in:
parent
033654f93f
commit
a22e9a0e0a
@ -24,7 +24,6 @@ import {
|
||||
DataQueryResponse,
|
||||
} from '@grafana/data';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { TooltipDisplayMode } from '@grafana/schema';
|
||||
import {
|
||||
RadioButtonGroup,
|
||||
LogRows,
|
||||
@ -40,7 +39,6 @@ import { dedupLogRows, filterLogLevels } from 'app/core/logs_model';
|
||||
import store from 'app/core/store';
|
||||
import { ExploreId } from 'app/types/explore';
|
||||
|
||||
import { ExploreGraph } from './ExploreGraph';
|
||||
import { LogsMetaRow } from './LogsMetaRow';
|
||||
import LogsNavigation from './LogsNavigation';
|
||||
import { LogsVolumePanel } from './LogsVolumePanel';
|
||||
@ -330,30 +328,19 @@ class UnthemedLogs extends PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<>
|
||||
{logsSeries && logsSeries.length ? (
|
||||
<>
|
||||
<div className={styles.infoText}>
|
||||
This datasource does not support full-range histograms. The graph is based on the logs seen in the
|
||||
response.
|
||||
</div>
|
||||
<ExploreGraph
|
||||
graphStyle="lines"
|
||||
data={logsSeries}
|
||||
height={150}
|
||||
width={width}
|
||||
tooltipDisplayMode={TooltipDisplayMode.Multi}
|
||||
absoluteRange={visibleRange || absoluteRange}
|
||||
timeZone={timeZone}
|
||||
loadingState={loadingState}
|
||||
onChangeTime={onChangeTime}
|
||||
onHiddenSeriesChanged={this.onToggleLogLevel}
|
||||
/>
|
||||
</>
|
||||
) : undefined}
|
||||
<LogsVolumePanel
|
||||
absoluteRange={absoluteRange}
|
||||
width={width}
|
||||
logsVolumeData={logsVolumeData}
|
||||
logLinesBasedData={
|
||||
logsSeries
|
||||
? {
|
||||
data: logsSeries,
|
||||
state: loadingState,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
logLinesBasedDataVisibleRange={visibleRange}
|
||||
onUpdateTimeRange={onChangeTime}
|
||||
timeZone={timeZone}
|
||||
splitOpen={splitOpen}
|
||||
@ -547,9 +534,5 @@ const getStyles = (theme: GrafanaTheme2, wrapLogMessage: boolean) => {
|
||||
overflow-y: visible;
|
||||
width: 100%;
|
||||
`,
|
||||
infoText: css`
|
||||
font-size: ${theme.typography.size.sm};
|
||||
color: ${theme.colors.text.secondary};
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
@ -21,6 +21,8 @@ function renderPanel(logsVolumeData?: DataQueryResponse) {
|
||||
width={100}
|
||||
onUpdateTimeRange={() => {}}
|
||||
logsVolumeData={logsVolumeData}
|
||||
logLinesBasedData={undefined}
|
||||
logLinesBasedDataVisibleRange={undefined}
|
||||
onLoadLogsVolume={() => {}}
|
||||
onHiddenSeriesChanged={() => null}
|
||||
/>
|
||||
|
@ -1,14 +1,24 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { AbsoluteTimeRange, DataQueryError, DataQueryResponse, LoadingState, SplitOpen, TimeZone } from '@grafana/data';
|
||||
import {
|
||||
AbsoluteTimeRange,
|
||||
DataQueryError,
|
||||
DataQueryResponse,
|
||||
GrafanaTheme2,
|
||||
LoadingState,
|
||||
SplitOpen,
|
||||
TimeZone,
|
||||
} from '@grafana/data';
|
||||
import { Alert, Button, Collapse, InlineField, TooltipDisplayMode, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
|
||||
import { ExploreGraph } from './ExploreGraph';
|
||||
|
||||
type Props = {
|
||||
logsVolumeData?: DataQueryResponse;
|
||||
logsVolumeData: DataQueryResponse | undefined;
|
||||
absoluteRange: AbsoluteTimeRange;
|
||||
logLinesBasedData: DataQueryResponse | undefined;
|
||||
logLinesBasedDataVisibleRange: AbsoluteTimeRange | undefined;
|
||||
timeZone: TimeZone;
|
||||
splitOpen: SplitOpen;
|
||||
width: number;
|
||||
@ -46,29 +56,64 @@ function ErrorAlert(props: { error: DataQueryError }) {
|
||||
);
|
||||
}
|
||||
|
||||
function createVisualisationData(
|
||||
logLinesBased: DataQueryResponse | undefined,
|
||||
logLinesBasedVisibleRange: AbsoluteTimeRange | undefined,
|
||||
fullRangeData: DataQueryResponse | undefined,
|
||||
absoluteRange: AbsoluteTimeRange
|
||||
):
|
||||
| {
|
||||
logsVolumeData: DataQueryResponse;
|
||||
fullRangeData: boolean;
|
||||
range: AbsoluteTimeRange;
|
||||
}
|
||||
| undefined {
|
||||
if (fullRangeData !== undefined) {
|
||||
return {
|
||||
logsVolumeData: fullRangeData,
|
||||
fullRangeData: true,
|
||||
range: absoluteRange,
|
||||
};
|
||||
}
|
||||
|
||||
if (logLinesBased !== undefined) {
|
||||
return {
|
||||
logsVolumeData: logLinesBased,
|
||||
fullRangeData: false,
|
||||
range: logLinesBasedVisibleRange || absoluteRange,
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function LogsVolumePanel(props: Props) {
|
||||
const {
|
||||
width,
|
||||
logsVolumeData,
|
||||
absoluteRange,
|
||||
timeZone,
|
||||
splitOpen,
|
||||
onUpdateTimeRange,
|
||||
onLoadLogsVolume,
|
||||
onHiddenSeriesChanged,
|
||||
} = props;
|
||||
const { width, timeZone, splitOpen, onUpdateTimeRange, onLoadLogsVolume, onHiddenSeriesChanged } = props;
|
||||
const theme = useTheme2();
|
||||
const styles = useStyles2(getStyles);
|
||||
const spacing = parseInt(theme.spacing(2).slice(0, -2), 10);
|
||||
const height = 150;
|
||||
|
||||
const data = createVisualisationData(
|
||||
props.logLinesBasedData,
|
||||
props.logLinesBasedDataVisibleRange,
|
||||
props.logsVolumeData,
|
||||
props.absoluteRange
|
||||
);
|
||||
|
||||
if (data === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { logsVolumeData, fullRangeData, range } = data;
|
||||
|
||||
if (logsVolumeData.error !== undefined) {
|
||||
return <ErrorAlert error={logsVolumeData.error} />;
|
||||
}
|
||||
|
||||
let LogsVolumePanelContent;
|
||||
|
||||
if (!logsVolumeData) {
|
||||
return null;
|
||||
} else if (logsVolumeData?.error) {
|
||||
return <ErrorAlert error={logsVolumeData?.error} />;
|
||||
} else if (logsVolumeData?.state === LoadingState.Loading) {
|
||||
if (logsVolumeData?.state === LoadingState.Loading) {
|
||||
LogsVolumePanelContent = <span>Log volume is loading...</span>;
|
||||
} else if (logsVolumeData?.data) {
|
||||
if (logsVolumeData.data.length > 0) {
|
||||
@ -79,7 +124,7 @@ export function LogsVolumePanel(props: Props) {
|
||||
data={logsVolumeData.data}
|
||||
height={height}
|
||||
width={width - spacing}
|
||||
absoluteRange={absoluteRange}
|
||||
absoluteRange={range}
|
||||
onChangeTime={onUpdateTimeRange}
|
||||
timeZone={timeZone}
|
||||
splitOpenFn={splitOpen}
|
||||
@ -92,30 +137,37 @@ export function LogsVolumePanel(props: Props) {
|
||||
}
|
||||
}
|
||||
|
||||
const zoomRatio = logsLevelZoomRatio(logsVolumeData, absoluteRange);
|
||||
let zoomLevelInfo;
|
||||
let extraInfo;
|
||||
if (fullRangeData) {
|
||||
const zoomRatio = logsLevelZoomRatio(logsVolumeData, range);
|
||||
|
||||
if (zoomRatio !== undefined && zoomRatio < 1) {
|
||||
zoomLevelInfo = (
|
||||
<InlineField label="Reload log volume" transparent>
|
||||
<Button size="xs" icon="sync" variant="secondary" onClick={onLoadLogsVolume} id="reload-volume" />
|
||||
</InlineField>
|
||||
if (zoomRatio !== undefined && zoomRatio < 1) {
|
||||
extraInfo = (
|
||||
<InlineField label="Reload log volume" transparent>
|
||||
<Button size="xs" icon="sync" variant="secondary" onClick={onLoadLogsVolume} id="reload-volume" />
|
||||
</InlineField>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
extraInfo = (
|
||||
<div className={styles.oldInfoText}>
|
||||
This datasource does not support full-range histograms. The graph is based on the logs seen in the response.
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Collapse label="" isOpen={true} loading={logsVolumeData?.state === LoadingState.Loading}>
|
||||
<Collapse label="" isOpen={true}>
|
||||
<div style={{ height }} className={styles.contentContainer}>
|
||||
{LogsVolumePanelContent}
|
||||
</div>
|
||||
<div className={styles.zoomInfoContainer}>{zoomLevelInfo}</div>
|
||||
<div className={styles.extraInfoContainer}>{extraInfo}</div>
|
||||
</Collapse>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = () => {
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
zoomInfoContainer: css`
|
||||
extraInfoContainer: css`
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
position: absolute;
|
||||
@ -127,6 +179,10 @@ const getStyles = () => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`,
|
||||
oldInfoText: css`
|
||||
font-size: ${theme.typography.size.sm};
|
||||
color: ${theme.colors.text.secondary};
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user