Add info tooltips to logs that have been sampled by adaptive logs (#89320)

* Add info tooltips to logs that have been sampled by adaptive logs

* review commends and linter changes

* make warnings match info

* fix betterer results
This commit is contained in:
Travis Patterson 2024-06-18 10:54:14 -06:00 committed by GitHub
parent 966cee864a
commit 59f255bb7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 39 additions and 7 deletions

View File

@ -4702,8 +4702,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Styles should be written using objects.", "31"], [0, 0, 0, "Styles should be written using objects.", "31"],
[0, 0, 0, "Styles should be written using objects.", "32"], [0, 0, 0, "Styles should be written using objects.", "32"],
[0, 0, 0, "Styles should be written using objects.", "33"], [0, 0, 0, "Styles should be written using objects.", "33"],
[0, 0, 0, "Styles should be written using objects.", "34"], [0, 0, 0, "Styles should be written using objects.", "34"]
[0, 0, 0, "Styles should be written using objects.", "35"]
], ],
"public/app/features/logs/components/log-context/LogContextButtons.tsx:5381": [ "public/app/features/logs/components/log-context/LogContextButtons.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"] [0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]

View File

@ -17,7 +17,7 @@ import { reportInteraction } from '@grafana/runtime';
import { DataQuery, TimeZone } from '@grafana/schema'; import { DataQuery, TimeZone } from '@grafana/schema';
import { withTheme2, Themeable2, Icon, Tooltip, PopoverContent } from '@grafana/ui'; import { withTheme2, Themeable2, Icon, Tooltip, PopoverContent } from '@grafana/ui';
import { checkLogsError, escapeUnescapedString } from '../utils'; import { checkLogsError, escapeUnescapedString, checkLogsSampled } from '../utils';
import { LogDetails } from './LogDetails'; import { LogDetails } from './LogDetails';
import { LogLabels } from './LogLabels'; import { LogLabels } from './LogLabels';
@ -222,6 +222,7 @@ class UnThemedLogRow extends PureComponent<Props, State> {
const { showDetails, showingContext, permalinked } = this.state; const { showDetails, showingContext, permalinked } = this.state;
const levelStyles = getLogLevelStyles(theme, row.logLevel); const levelStyles = getLogLevelStyles(theme, row.logLevel);
const { errorMessage, hasError } = checkLogsError(row); const { errorMessage, hasError } = checkLogsError(row);
const { sampleMessage, isSampled } = checkLogsSampled(row);
const logRowBackground = cx(styles.logsRow, { const logRowBackground = cx(styles.logsRow, {
[styles.errorLogRow]: hasError, [styles.errorLogRow]: hasError,
[styles.highlightBackground]: showingContext || permalinked, [styles.highlightBackground]: showingContext || permalinked,
@ -255,13 +256,22 @@ class UnThemedLogRow extends PureComponent<Props, State> {
</td> </td>
)} )}
<td <td
className={hasError ? styles.logsRowWithError : `${levelStyles.logsRowLevelColor} ${styles.logsRowLevel}`} className={
hasError || isSampled
? styles.logsRowWithError
: `${levelStyles.logsRowLevelColor} ${styles.logsRowLevel}`
}
> >
{hasError && ( {hasError && (
<Tooltip content={`Error: ${errorMessage}`} placement="right" theme="error"> <Tooltip content={`Error: ${errorMessage}`} placement="right" theme="error">
<Icon className={styles.logIconError} name="exclamation-triangle" size="xs" /> <Icon className={styles.logIconError} name="exclamation-triangle" size="xs" />
</Tooltip> </Tooltip>
)} )}
{isSampled && (
<Tooltip content={`${sampleMessage}`} placement="right" theme="info">
<Icon className={styles.logIconInfo} name="info-circle" size="xs" />
</Tooltip>
)}
</td> </td>
<td <td
title={enableLogDetails ? (showDetails ? 'Hide log details' : 'See log details') : ''} title={enableLogDetails ? (showDetails ? 'Hide log details' : 'See log details') : ''}

View File

@ -117,9 +117,16 @@ export const getLogRowStyles = memoizeOne((theme: GrafanaTheme2) => {
width: 4em; width: 4em;
cursor: default; cursor: default;
`, `,
logIconError: css` logIconError: css({
color: ${theme.colors.warning.main}; color: theme.colors.warning.main,
`, position: 'relative',
top: '-2px',
}),
logIconInfo: css({
color: theme.colors.info.main,
position: 'relative',
top: '-2px',
}),
logsRowToggleDetails: css` logsRowToggleDetails: css`
label: logs-row-toggle-details__level; label: logs-row-toggle-details__level;
font-size: 9px; font-size: 9px;

View File

@ -154,6 +154,22 @@ export const checkLogsError = (logRow: LogRowModel): { hasError: boolean; errorM
}; };
}; };
export const checkLogsSampled = (logRow: LogRowModel): { isSampled: boolean; sampleMessage?: string } => {
if (logRow.labels.__adaptive_logs_sampled__) {
let msg =
logRow.labels.__adaptive_logs_sampled__ === 'true'
? 'Logs like this one have been dropped by Adaptive Logs'
: `${logRow.labels.__adaptive_logs_sampled__}% of logs like this one have been dropped by Adaptive Logs`;
return {
isSampled: true,
sampleMessage: msg,
};
}
return {
isSampled: false,
};
};
export const escapeUnescapedString = (string: string) => export const escapeUnescapedString = (string: string) =>
string.replace(/\\r\\n|\\n|\\t|\\r/g, (match: string) => (match.slice(1) === 't' ? '\t' : '\n')); string.replace(/\\r\\n|\\n|\\t|\\r/g, (match: string) => (match.slice(1) === 't' ? '\t' : '\n'));