Logs Panel: Emphasize log line, rename field (#114579)

* Logs: Rename attributes field

* LogLine: emphasize log line body

* LogLine: improve light mode

* Lint

* Update tests

* Only override colors if displayed fields are used

* Fix small font size ignored with displayed fields

* Fix types
This commit is contained in:
Matias Chomicki
2025-12-10 11:19:31 +01:00
committed by GitHub
parent 633332c750
commit a7bbca3451
6 changed files with 43 additions and 14 deletions
@@ -72,7 +72,7 @@ export const InfiniteScroll = ({
const lastEvent = useRef<Event | WheelEvent | null>(null);
const countRef = useRef(0);
const lastLogOfPage = useRef<string[]>([]);
const styles = useStyles2(getStyles, virtualization);
const styles = useStyles2(getStyles, virtualization, displayedFields);
const resetStateTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
const scrollToLogLineRef = useRef<LogListModel | undefined>(undefined);
const noScrollRef = useRef<undefined | boolean>(undefined);
@@ -202,7 +202,7 @@ const LogLineComponent = memo(
{/* A button element could be used but in Safari it prevents text selection. Fallback available for a11y in LogLineMenu */}
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */}
<div
className={`${styles.logLine} ${variant ?? ''} ${pinned ? styles.pinnedLogLine : ''} ${permalinked ? styles.permalinkedLogLine : ''} ${detailsShown ? styles.detailsDisplayed : ''} ${isLogDetailsFocused ? styles.currentLog : ''} ${fontSize === 'small' ? styles.fontSizeSmall : ''} ${enableLogDetails ? styles.clickable : ''}`}
className={`${styles.logLine} ${variant ?? ''} ${pinned ? styles.pinnedLogLine : ''} ${permalinked ? styles.permalinkedLogLine : ''} ${detailsShown ? styles.detailsDisplayed : ''} ${isLogDetailsFocused ? styles.currentLog : ''} ${fontSize === 'small' ? styles.fontSizeSmall : styles.fontSizeDefault} ${enableLogDetails ? styles.clickable : ''}`}
ref={onOverflow ? logLineRef : undefined}
onMouseEnter={handleMouseOver}
onFocus={handleMouseOver}
@@ -433,7 +433,7 @@ const LogLineBody = ({ log, styles }: { log: LogListModel; styles: LogLineStyles
if (log.hasAnsi) {
return (
<span className="field no-highlighting">
<span className="field no-highlighting log-line-body">
<LogMessageAnsi value={log.body} highlight={highlight} />{' '}
</span>
);
@@ -448,12 +448,12 @@ const LogLineBody = ({ log, styles }: { log: LogListModel; styles: LogLineStyles
highlightClassName={styles.matchHighLight}
/>
) : (
<span className="field no-highlighting">{log.body} </span>
<span className="field no-highlighting log-line-body">{log.body} </span>
);
}
return (
<span className="field log-syntax-highlight">
<span className="field log-syntax-highlight log-line-body">
<HighlightedLogRenderer tokens={log.highlightedBodyTokens} />{' '}
</span>
);
@@ -468,7 +468,30 @@ export function getGridTemplateColumns(dimensions: LogFieldDimension[], displaye
}
export type LogLineStyles = ReturnType<typeof getStyles>;
export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtualization) => {
export const getStyles = (
theme: GrafanaTheme2,
virtualization: LogLineVirtualization | undefined = undefined,
displayedFields: string[] = []
) => {
const base = tinycolor(theme.colors.background.primary);
let maxContrast = theme.isDark
? tinycolor(theme.colors.text.maxContrast).darken(10).toRgbString()
: tinycolor(theme.colors.text.maxContrast).lighten(10).toRgbString();
let colorDefault = theme.isDark
? theme.colors.text.primary
: tinycolor(theme.colors.text.maxContrast).lighten(30).toRgbString();
const contrast1 = tinycolor.readability(base, maxContrast);
const contrast2 = tinycolor.readability(base, colorDefault);
if (!displayedFields.length || (displayedFields.length === 1 && displayedFields.includes(LOG_LINE_BODY_FIELD_NAME))) {
colorDefault = theme.colors.text.primary;
maxContrast = theme.colors.text.primary;
} else if (contrast1 < contrast2) {
colorDefault = maxContrast;
maxContrast = theme.colors.text.primary;
}
const colors = {
critical: '#B877D9',
error: theme.colors.error.text,
@@ -477,8 +500,9 @@ export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtuali
trace: '#6ed0e0',
info: '#6CCF8E',
metadata: theme.colors.text.secondary,
default: theme.colors.text.primary,
default: colorDefault,
parsedField: theme.colors.text.secondary,
logLineBody: maxContrast,
};
const hoverColor = tinycolor(theme.colors.background.canvas).darken(11).toRgbString();
@@ -490,8 +514,6 @@ export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtuali
gap: theme.spacing(0.5),
flexDirection: 'row',
fontFamily: theme.typography.fontFamilyMonospace,
fontSize: theme.typography.fontSize,
lineHeight: theme.typography.body.lineHeight,
wordBreak: 'break-all',
'&:hover': {
background: hoverColor,
@@ -509,7 +531,7 @@ export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtuali
},
'& .log-syntax-highlight': {
'.log-token-string': {
color: colors.default,
color: colors.logLineBody,
},
'.log-token-duration': {
color: theme.colors.success.text,
@@ -540,6 +562,9 @@ export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtuali
color: theme.components.textHighlight.text,
backgroundColor: theme.components.textHighlight.background,
},
'&.log-line-body': {
color: colors.logLineBody,
},
},
'& .no-highlighting': {
color: theme.colors.text.primary,
@@ -553,6 +578,10 @@ export const getStyles = (theme: GrafanaTheme2, virtualization?: LogLineVirtuali
fontSize: theme.typography.bodySmall.fontSize,
lineHeight: theme.typography.bodySmall.lineHeight,
}),
fontSizeDefault: css({
fontSize: theme.typography.fontSize,
lineHeight: theme.typography.body.lineHeight,
}),
detailsDisplayed: css({
background: tinycolor(theme.colors.background.canvas)
.darken(theme.isDark ? 2 : 5)
@@ -457,7 +457,7 @@ describe('LogList', () => {
// Default displayed fields
expect(screen.getByText('Log line')).toBeInTheDocument();
expect(screen.getByText('OTel attributes')).toBeInTheDocument();
expect(screen.getByText('Log attributes')).toBeInTheDocument();
// Suggested field
expect(screen.getByText('scope_name')).toBeInTheDocument();
@@ -550,7 +550,7 @@ const LogListComponent = ({
function getStyles(
theme: GrafanaTheme2,
dimensions: LogFieldDimension[],
displayedFields: string[],
displayedFields: string[] = [],
{ showTime }: { showTime: boolean }
) {
const columns = showTime ? dimensions : dimensions.filter((_, index) => index > 0);
@@ -364,7 +364,7 @@ export function getNormalizedFieldName(field: string) {
if (field === LOG_LINE_BODY_FIELD_NAME) {
return t('logs.log-line-details.log-line-field', 'Log line');
} else if (field === OTEL_LOG_LINE_ATTRIBUTES_FIELD_NAME) {
return t('logs.log-line-details.log-attributes-field', 'OTel attributes');
return t('logs.log-line-details.log-attributes-field', 'Log attributes');
}
return field;
}
+1 -1
View File
@@ -9937,7 +9937,7 @@
"inline-mode": "Display inline",
"link-value-tooltip": "Link value",
"links-section": "Links",
"log-attributes-field": "OTel attributes",
"log-attributes-field": "Log attributes",
"log-line-field": "Log line",
"log-line-section": "Log line",
"move-displayed-field-down": "Move down",