Logs Volume: update timeout message (#95277)

* Logs Volume: update timeout message

* SupplementaryResultError: add list styles

* Address lint issues

* Update public/app/features/explore/Logs/LogsVolumePanelList.tsx

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>

---------

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
This commit is contained in:
Matias Chomicki
2024-10-24 13:15:52 +03:00
committed by GitHub
co-authored by Sven Grossmann
parent 5c9071a6c6
commit 142797032b
6 changed files with 87 additions and 28 deletions
@@ -52,7 +52,7 @@ describe('LogsVolumePanelList', () => {
expect(screen.getByText(message)).toBeInTheDocument();
});
it('a custom message for timeout errors', async () => {
it('has a custom message for timeout errors', async () => {
const onLoadCallback = jest.fn();
renderPanel(
{
@@ -62,7 +62,8 @@ describe('LogsVolumePanelList', () => {
},
onLoadCallback
);
expect(screen.getByText('The logs volume query has timed out')).toBeInTheDocument();
expect(screen.getByText('Unable to show log volume')).toBeInTheDocument();
expect(screen.getByText(/The query is trying to access too much data/)).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', { name: 'Retry' }));
expect(onLoadCallback).toHaveBeenCalled();
});
@@ -72,4 +73,9 @@ describe('LogsVolumePanelList', () => {
expect(screen.getByRole('status')).toBeInTheDocument();
expect(screen.getByText('No logs volume available')).toBeInTheDocument();
});
it('does not show an info message with empty responses when the current state is streaming', async () => {
renderPanel({ state: LoadingState.Streaming, data: [] });
expect(screen.queryByText('No logs volume available')).not.toBeInTheDocument();
});
});
@@ -17,6 +17,7 @@ import {
TimeZone,
} from '@grafana/data';
import { Button, InlineField, Alert, useStyles2, SeriesVisibilityChangeMode } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { mergeLogsVolumeDataFrames, isLogsVolumeLimited, getLogsVolumeMaximumRange } from '../../logs/utils';
import { SupplementaryResultError } from '../SupplementaryResultError';
@@ -97,8 +98,29 @@ export const LogsVolumePanelList = ({
} else if (timeoutError) {
return (
<SupplementaryResultError
title="The logs volume query has timed out"
title="Unable to show log volume"
// Using info to avoid users thinking that the actual query has failed.
message={
<>
<p>
<Trans i18nKey="explore.logs.logs-volume.much-data">
The query is trying to access too much data. Try one or more of the following:
</Trans>
</p>
<ul>
<li>
<Trans i18nKey="explore.logs.logs-volume.add-filters">
Add more labels to your query to narrow down your search.
</Trans>
</li>
<li>
<Trans i18nKey="explore.logs.logs-volume.decrease-timerange">
Decrease the time range of your query.
</Trans>
</li>
</ul>
</>
}
severity="info"
suggestedAction="Retry"
onSuggestedAction={onLoadLogsVolume}
@@ -27,4 +27,10 @@ describe('SupplementaryResultError', () => {
await userEvent.click(button);
expect(screen.getByText(message)).toBeInTheDocument();
});
it('allows arbitrary components in the message', async () => {
const error = { data: { message: 'error' } };
render(<SupplementaryResultError error={error} message={<div data-testid="custom-stuff" />} title={'Error'} />);
expect(screen.getByTestId('custom-stuff')).toBeInTheDocument();
});
});
@@ -1,53 +1,59 @@
import { css } from '@emotion/css';
import { useState } from 'react';
import { ReactNode, useState } from 'react';
import { DataQueryError, GrafanaTheme2 } from '@grafana/data';
import { Alert, AlertVariant, Button, useTheme2 } from '@grafana/ui';
type Props = {
error?: DataQueryError;
message?: ReactNode;
title: string;
severity?: AlertVariant;
suggestedAction?: string;
onSuggestedAction?(): void;
onRemove?(): void;
};
const SHORT_ERROR_MESSAGE_LIMIT = 100;
export function SupplementaryResultError(props: Props) {
const [isOpen, setIsOpen] = useState(false);
const SHORT_ERROR_MESSAGE_LIMIT = 100;
const { error, title, suggestedAction, onSuggestedAction, onRemove, severity = 'warning' } = props;
// generic get-error-message-logic, taken from
// /public/app/features/explore/ErrorContainer.tsx
const message = error?.message || error?.data?.message || '';
const showButton = !isOpen && message.length > SHORT_ERROR_MESSAGE_LIMIT;
const message = props.message ?? error?.message ?? error?.data?.message ?? '';
const showButton = typeof message === 'string' && message.length > SHORT_ERROR_MESSAGE_LIMIT;
const theme = useTheme2();
const styles = getStyles(theme);
return (
<div className={styles.supplementaryErrorContainer}>
<Alert title={title} severity={severity} onRemove={onRemove}>
<div className={styles.suggestedActionWrapper}>
{showButton ? (
<Button
variant="secondary"
size="xs"
onClick={() => {
setIsOpen(true);
}}
>
Show details
</Button>
) : (
message
)}
{suggestedAction && onSuggestedAction && (
<div className={styles.suggestedActionWrapper}>
{showButton ? (
<div className={styles.suggestedActionWrapper}>
{!isOpen ? (
<Button
variant="secondary"
size="xs"
onClick={() => {
setIsOpen(true);
}}
>
Show details
</Button>
) : (
message
)}
</div>
) : (
<div className={styles.suggestedActionWrapper}>
{message}
{suggestedAction && onSuggestedAction && (
<Button variant="primary" size="xs" onClick={onSuggestedAction}>
{suggestedAction}
</Button>
</div>
)}
</div>
)}
</div>
)}
</Alert>
</div>
);
@@ -59,13 +65,22 @@ const getStyles = (theme: GrafanaTheme2) => {
width: '50%',
minWidth: `${theme.breakpoints.values.sm}px`,
margin: '0 auto',
[theme.breakpoints.down('lg')]: {
width: '70%',
},
[theme.breakpoints.down('md')]: {
width: '100%',
},
}),
suggestedActionWrapper: css({
height: theme.spacing(6),
minHeight: theme.spacing(3),
['button']: {
position: 'absolute',
right: theme.spacing(2),
top: theme.spacing(7),
bottom: theme.spacing(2),
},
['ul']: {
paddingLeft: theme.spacing(2),
},
}),
};
+5
View File
@@ -856,6 +856,11 @@
"explore": {
"add-to-dashboard": "Add to dashboard",
"logs": {
"logs-volume": {
"add-filters": "Add more labels to your query to narrow down your search.",
"decrease-timerange": "Decrease the time range of your query.",
"much-data": "The query is trying to access too much data. Try one or more of the following:"
},
"maximum-pinned-logs": "Maximum of {{PINNED_LOGS_LIMIT}} pinned logs reached. Unpin a log to add another.",
"no-logs-found": "No logs found.",
"scan-for-older-logs": "Scan for older logs",
@@ -856,6 +856,11 @@
"explore": {
"add-to-dashboard": "Åđđ ŧő đäşĥþőäřđ",
"logs": {
"logs-volume": {
"add-filters": "Åđđ mőřę ľäþęľş ŧő yőūř qūęřy ŧő ʼnäřřőŵ đőŵʼn yőūř şęäřčĥ.",
"decrease-timerange": "Đęčřęäşę ŧĥę ŧįmę řäʼnģę őƒ yőūř qūęřy.",
"much-data": "Ŧĥę qūęřy įş ŧřyįʼnģ ŧő äččęşş ŧőő mūčĥ đäŧä. Ŧřy őʼnę őř mőřę őƒ ŧĥę ƒőľľőŵįʼnģ:"
},
"maximum-pinned-logs": "Mäχįmūm őƒ {{PINNED_LOGS_LIMIT}} pįʼnʼnęđ ľőģş řęäčĥęđ. Ůʼnpįʼn ä ľőģ ŧő äđđ äʼnőŧĥęř.",
"no-logs-found": "Ńő ľőģş ƒőūʼnđ.",
"scan-for-older-logs": "Ŝčäʼn ƒőř őľđęř ľőģş",