mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: Update log context UI (#66848)
* Loki: Update log context UI * Update copy
This commit is contained in:
parent
d1a918489e
commit
c96b704af3
@ -37,6 +37,10 @@ const setupProps = (): LokiContextUiProps => {
|
||||
},
|
||||
} as unknown as LogRowModel,
|
||||
onClose: jest.fn(),
|
||||
origQuery: {
|
||||
expr: '{label1="value1"} | logfmt',
|
||||
refId: 'A',
|
||||
},
|
||||
};
|
||||
|
||||
return defaults;
|
||||
@ -78,7 +82,14 @@ describe('LokiContextUi', () => {
|
||||
it('renders and shows executed query text', async () => {
|
||||
const props = setupProps();
|
||||
render(<LokiContextUi {...props} />);
|
||||
expect(await screen.findByText(/Executed log context query:/)).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
// We should see the query text (it is split into multiple spans)
|
||||
expect(screen.getByText('{')).toBeInTheDocument();
|
||||
expect(screen.getByText('label1')).toBeInTheDocument();
|
||||
expect(screen.getByText('=')).toBeInTheDocument();
|
||||
expect(screen.getByText('"value1"')).toBeInTheDocument();
|
||||
expect(screen.getByText('}')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('initialize context filters', async () => {
|
||||
@ -139,10 +150,8 @@ describe('LokiContextUi', () => {
|
||||
it('displays executed query even if context ui closed', async () => {
|
||||
const props = setupProps();
|
||||
render(<LokiContextUi {...props} />);
|
||||
// We start with the context ui open
|
||||
expect(await screen.findByText(/Executed log context query:/)).toBeInTheDocument();
|
||||
// We click on it to close
|
||||
await userEvent.click(screen.getByText(/Executed log context query:/));
|
||||
// We start with the context ui open and click on it to close
|
||||
await userEvent.click(screen.getAllByRole('button')[0]);
|
||||
await waitFor(() => {
|
||||
// We should see the query text (it is split into multiple spans)
|
||||
expect(screen.getByText('{')).toBeInTheDocument();
|
||||
@ -152,4 +161,49 @@ describe('LokiContextUi', () => {
|
||||
expect(screen.getByText('}')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not show parsed labels section if origQuery has 0 parsers', async () => {
|
||||
const props = setupProps();
|
||||
const newProps = {
|
||||
...props,
|
||||
origQuery: {
|
||||
expr: '{label1="value1"}',
|
||||
refId: 'A',
|
||||
},
|
||||
};
|
||||
render(<LokiContextUi {...newProps} />);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Refine the search')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows parsed labels section if origQuery has 1 parser', async () => {
|
||||
const props = setupProps();
|
||||
const newProps = {
|
||||
...props,
|
||||
origQuery: {
|
||||
expr: '{label1="value1"} | logfmt',
|
||||
refId: 'A',
|
||||
},
|
||||
};
|
||||
render(<LokiContextUi {...newProps} />);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Refine the search')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not show parsed labels section if origQuery has 2 parsers', async () => {
|
||||
const props = setupProps();
|
||||
const newProps = {
|
||||
...props,
|
||||
origQuery: {
|
||||
expr: '{label1="value1"} | logfmt | json',
|
||||
refId: 'A',
|
||||
},
|
||||
};
|
||||
render(<LokiContextUi {...newProps} />);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Refine the search')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -4,12 +4,13 @@ import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, LogRowModel, SelectableValue } from '@grafana/data';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { Collapse, Label, LoadingPlaceholder, MultiSelect, Tag, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { Collapse, Icon, Label, LoadingPlaceholder, MultiSelect, Tag, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import store from 'app/core/store';
|
||||
|
||||
import { RawQuery } from '../../prometheus/querybuilder/shared/RawQuery';
|
||||
import { LogContextProvider } from '../LogContextProvider';
|
||||
import { escapeLabelValueInSelector } from '../languageUtils';
|
||||
import { isQueryWithParser } from '../queryUtils';
|
||||
import { lokiGrammar } from '../syntax';
|
||||
import { ContextFilter, LokiQuery } from '../types';
|
||||
|
||||
@ -56,12 +57,18 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
query: css`
|
||||
text-align: start;
|
||||
line-break: anywhere;
|
||||
margin-top: ${theme.spacing(0.5)};
|
||||
margin-top: -${theme.spacing(0.25)};
|
||||
`,
|
||||
ui: css`
|
||||
background-color: ${theme.colors.background.secondary};
|
||||
padding: ${theme.spacing(2)};
|
||||
`,
|
||||
rawQuery: css`
|
||||
display: inline;
|
||||
`,
|
||||
queryDescription: css`
|
||||
margin-left: ${theme.spacing(0.5)};
|
||||
`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -155,6 +162,9 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Currently we support adding of parser and showing parsed labels only if there is 1 parser
|
||||
const showParsedLabels = origQuery && isQueryWithParser(origQuery.expr).parserCount === 1 && parsedLabels.length > 0;
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<LoadingPlaceholder text="" className={`${styles.loadingPlaceholder} ${loading ? '' : styles.hidden}`} />
|
||||
@ -167,7 +177,6 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
}}
|
||||
label={
|
||||
<div className={styles.query}>
|
||||
<Label>Executed log context query:</Label>
|
||||
<RawQuery
|
||||
lang={{ grammar: lokiGrammar, name: 'loki' }}
|
||||
query={logContextProvider.processContextFiltersToExpr(
|
||||
@ -175,14 +184,18 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
contextFilters.filter(({ enabled }) => enabled),
|
||||
origQuery
|
||||
)}
|
||||
className={styles.rawQuery}
|
||||
/>
|
||||
<Tooltip content="Initially executed log context query is created from all labels defining the stream for the selected log line. Use editor bellow to customize log context query.">
|
||||
<Icon name="info-circle" size="sm" className={styles.queryDescription} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className={styles.ui}>
|
||||
<Tooltip
|
||||
content={
|
||||
'This feature is experimental and only works on log queries containing no more than 1 parser (logfmt, json).'
|
||||
'This feature is experimental and may change in the future. Currently it supports using parser and extracted labels for queries with no more than 1 parser (e.g. logfmt, json). Please report any issues in the Grafana GitHub repository.'
|
||||
}
|
||||
placement="top"
|
||||
>
|
||||
@ -190,9 +203,9 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
</Tooltip>{' '}
|
||||
<Label
|
||||
className={styles.label}
|
||||
description="Context query is created from all labels defining the stream for the selected log line. Select labels to be included in log context query."
|
||||
description="By removing some of the selected label filters, you can broaden your search."
|
||||
>
|
||||
1. Select labels
|
||||
Widen the search
|
||||
</Label>
|
||||
<MultiSelect
|
||||
options={realLabels.map(contextFilterToSelectFilter)}
|
||||
@ -226,13 +239,13 @@ export function LokiContextUi(props: LokiContextUiProps) {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
{parsedLabels.length > 0 && (
|
||||
{showParsedLabels && (
|
||||
<>
|
||||
<Label
|
||||
className={styles.label}
|
||||
description={`By using parser, you are able to filter for extracted labels. Select extracted labels to be included in log context query.`}
|
||||
description={`By using parser in your original query, you are able to filter for extracted labels. Refine your search by applying extracted labels from selected log line.`}
|
||||
>
|
||||
2. Add extracted label filters
|
||||
Refine the search
|
||||
</Label>
|
||||
<MultiSelect
|
||||
options={parsedLabels.map(contextFilterToSelectFilter)}
|
||||
|
Loading…
Reference in New Issue
Block a user