|
|
|
@ -41,7 +41,7 @@ import { |
|
|
|
|
InlineSwitch, |
|
|
|
|
withTheme2, |
|
|
|
|
Themeable2, |
|
|
|
|
Collapse, |
|
|
|
|
PanelChrome, |
|
|
|
|
} from '@grafana/ui'; |
|
|
|
|
import store from 'app/core/store'; |
|
|
|
|
import { createAndCopyShortLink } from 'app/core/utils/shortLinks'; |
|
|
|
@ -121,16 +121,6 @@ interface State { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const scrollableLogsContainer = config.featureToggles.exploreScrollableLogsContainer; |
|
|
|
|
// We need to override css overflow of divs in Collapse element to enable sticky Logs navigation
|
|
|
|
|
const styleOverridesForStickyNavigation = css` |
|
|
|
|
${scrollableLogsContainer && 'margin-bottom: 0px'}; |
|
|
|
|
& > div { |
|
|
|
|
overflow: visible; |
|
|
|
|
& > div { |
|
|
|
|
overflow: visible; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// we need to define the order of these explicitly
|
|
|
|
|
const DEDUP_OPTIONS = [ |
|
|
|
@ -292,11 +282,11 @@ class UnthemedLogs extends PureComponent<Props, State> { |
|
|
|
|
this.setState({ hiddenLogLevels }); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
onToggleLogsVolumeCollapse = (isOpen: boolean) => { |
|
|
|
|
this.props.onSetLogsVolumeEnabled(isOpen); |
|
|
|
|
onToggleLogsVolumeCollapse = (collapsed: boolean) => { |
|
|
|
|
this.props.onSetLogsVolumeEnabled(!collapsed); |
|
|
|
|
reportInteraction('grafana_explore_logs_histogram_toggle_clicked', { |
|
|
|
|
datasourceType: this.props.datasourceType, |
|
|
|
|
type: isOpen ? 'open' : 'close', |
|
|
|
|
type: !collapsed ? 'open' : 'close', |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -540,7 +530,12 @@ class UnthemedLogs extends PureComponent<Props, State> { |
|
|
|
|
timeZone={timeZone} |
|
|
|
|
/> |
|
|
|
|
)} |
|
|
|
|
<Collapse label="Logs volume" collapsible isOpen={logsVolumeEnabled} onToggle={this.onToggleLogsVolumeCollapse}> |
|
|
|
|
<PanelChrome |
|
|
|
|
title="Logs volume" |
|
|
|
|
collapsible |
|
|
|
|
collapsed={!logsVolumeEnabled} |
|
|
|
|
onToggleCollapse={this.onToggleLogsVolumeCollapse} |
|
|
|
|
> |
|
|
|
|
{logsVolumeEnabled && ( |
|
|
|
|
<LogsVolumePanelList |
|
|
|
|
absoluteRange={absoluteRange} |
|
|
|
@ -552,16 +547,22 @@ class UnthemedLogs extends PureComponent<Props, State> { |
|
|
|
|
onLoadLogsVolume={loadLogsVolumeData} |
|
|
|
|
onHiddenSeriesChanged={this.onToggleLogLevel} |
|
|
|
|
eventBus={this.logsVolumeEventBus} |
|
|
|
|
onClose={() => this.onToggleLogsVolumeCollapse(false)} |
|
|
|
|
onClose={() => this.onToggleLogsVolumeCollapse(true)} |
|
|
|
|
/> |
|
|
|
|
)} |
|
|
|
|
</Collapse> |
|
|
|
|
<Collapse |
|
|
|
|
label={ |
|
|
|
|
</PanelChrome> |
|
|
|
|
<PanelChrome |
|
|
|
|
title={ |
|
|
|
|
config.featureToggles.logsExploreTableVisualisation |
|
|
|
|
? this.state.visualisationType === 'logs' |
|
|
|
|
? 'Logs' |
|
|
|
|
: 'Table' |
|
|
|
|
: 'Logs' |
|
|
|
|
} |
|
|
|
|
actions={ |
|
|
|
|
<> |
|
|
|
|
{config.featureToggles.logsExploreTableVisualisation && ( |
|
|
|
|
<div className={styles.visualisationType}> |
|
|
|
|
{this.state.visualisationType === 'logs' ? 'Logs' : 'Table'} |
|
|
|
|
<RadioButtonGroup |
|
|
|
|
className={styles.visualisationTypeRadio} |
|
|
|
|
options={[ |
|
|
|
@ -582,102 +583,101 @@ class UnthemedLogs extends PureComponent<Props, State> { |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
)} |
|
|
|
|
{!config.featureToggles.logsExploreTableVisualisation && 'Logs'} |
|
|
|
|
</> |
|
|
|
|
} |
|
|
|
|
loading={loading} |
|
|
|
|
isOpen |
|
|
|
|
className={styleOverridesForStickyNavigation} |
|
|
|
|
loadingState={loading ? LoadingState.Loading : LoadingState.Done} |
|
|
|
|
> |
|
|
|
|
{this.state.visualisationType !== 'table' && ( |
|
|
|
|
<div className={styles.logOptions}> |
|
|
|
|
<InlineFieldRow> |
|
|
|
|
<InlineField label="Time" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={showTime} |
|
|
|
|
onChange={this.onChangeTime} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`show-time_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Unique labels" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={showLabels} |
|
|
|
|
onChange={this.onChangeLabels} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`unique-labels_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Wrap lines" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={wrapLogMessage} |
|
|
|
|
onChange={this.onChangeWrapLogMessage} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`wrap-lines_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Prettify JSON" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={prettifyLogMessage} |
|
|
|
|
onChange={this.onChangePrettifyLogMessage} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`prettify_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Deduplication" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<RadioButtonGroup |
|
|
|
|
options={DEDUP_OPTIONS.map((dedupType) => ({ |
|
|
|
|
label: capitalize(dedupType), |
|
|
|
|
value: dedupType, |
|
|
|
|
description: LogsDedupDescription[dedupType], |
|
|
|
|
}))} |
|
|
|
|
value={dedupStrategy} |
|
|
|
|
onChange={this.onChangeDedup} |
|
|
|
|
className={styles.radioButtons} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
</InlineFieldRow> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
<InlineField label="Display results" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<RadioButtonGroup |
|
|
|
|
disabled={isFlipping} |
|
|
|
|
options={[ |
|
|
|
|
{ |
|
|
|
|
label: 'Newest first', |
|
|
|
|
value: LogsSortOrder.Descending, |
|
|
|
|
description: 'Show results newest to oldest', |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
label: 'Oldest first', |
|
|
|
|
value: LogsSortOrder.Ascending, |
|
|
|
|
description: 'Show results oldest to newest', |
|
|
|
|
}, |
|
|
|
|
]} |
|
|
|
|
value={logsSortOrder} |
|
|
|
|
onChange={this.onChangeLogsSortOrder} |
|
|
|
|
className={styles.radioButtons} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<div className={styles.stickyNavigation}> |
|
|
|
|
{this.state.visualisationType !== 'table' && ( |
|
|
|
|
<div className={styles.logOptions}> |
|
|
|
|
<InlineFieldRow> |
|
|
|
|
<InlineField label="Time" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={showTime} |
|
|
|
|
onChange={this.onChangeTime} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`show-time_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Unique labels" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={showLabels} |
|
|
|
|
onChange={this.onChangeLabels} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`unique-labels_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Wrap lines" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={wrapLogMessage} |
|
|
|
|
onChange={this.onChangeWrapLogMessage} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`wrap-lines_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Prettify JSON" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<InlineSwitch |
|
|
|
|
value={prettifyLogMessage} |
|
|
|
|
onChange={this.onChangePrettifyLogMessage} |
|
|
|
|
className={styles.horizontalInlineSwitch} |
|
|
|
|
transparent |
|
|
|
|
id={`prettify_${exploreId}`} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
<InlineField label="Deduplication" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<RadioButtonGroup |
|
|
|
|
options={DEDUP_OPTIONS.map((dedupType) => ({ |
|
|
|
|
label: capitalize(dedupType), |
|
|
|
|
value: dedupType, |
|
|
|
|
description: LogsDedupDescription[dedupType], |
|
|
|
|
}))} |
|
|
|
|
value={dedupStrategy} |
|
|
|
|
onChange={this.onChangeDedup} |
|
|
|
|
className={styles.radioButtons} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
</InlineFieldRow> |
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
|
<InlineField label="Display results" className={styles.horizontalInlineLabel} transparent> |
|
|
|
|
<RadioButtonGroup |
|
|
|
|
disabled={isFlipping} |
|
|
|
|
options={[ |
|
|
|
|
{ |
|
|
|
|
label: 'Newest first', |
|
|
|
|
value: LogsSortOrder.Descending, |
|
|
|
|
description: 'Show results newest to oldest', |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
label: 'Oldest first', |
|
|
|
|
value: LogsSortOrder.Ascending, |
|
|
|
|
description: 'Show results oldest to newest', |
|
|
|
|
}, |
|
|
|
|
]} |
|
|
|
|
value={logsSortOrder} |
|
|
|
|
onChange={this.onChangeLogsSortOrder} |
|
|
|
|
className={styles.radioButtons} |
|
|
|
|
/> |
|
|
|
|
</InlineField> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
)} |
|
|
|
|
<div ref={this.topLogsRef} /> |
|
|
|
|
<LogsMetaRow |
|
|
|
|
logRows={logRows} |
|
|
|
|
meta={logsMeta || []} |
|
|
|
|
dedupStrategy={dedupStrategy} |
|
|
|
|
dedupCount={dedupCount} |
|
|
|
|
hasUnescapedContent={hasUnescapedContent} |
|
|
|
|
forceEscape={forceEscape} |
|
|
|
|
displayedFields={displayedFields} |
|
|
|
|
onEscapeNewlines={this.onEscapeNewlines} |
|
|
|
|
clearDetectedFields={this.clearDetectedFields} |
|
|
|
|
/> |
|
|
|
|
)} |
|
|
|
|
<div ref={this.topLogsRef} /> |
|
|
|
|
<LogsMetaRow |
|
|
|
|
logRows={logRows} |
|
|
|
|
meta={logsMeta || []} |
|
|
|
|
dedupStrategy={dedupStrategy} |
|
|
|
|
dedupCount={dedupCount} |
|
|
|
|
hasUnescapedContent={hasUnescapedContent} |
|
|
|
|
forceEscape={forceEscape} |
|
|
|
|
displayedFields={displayedFields} |
|
|
|
|
onEscapeNewlines={this.onEscapeNewlines} |
|
|
|
|
clearDetectedFields={this.clearDetectedFields} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
<div className={styles.logsSection}> |
|
|
|
|
{this.state.visualisationType === 'table' && hasData && ( |
|
|
|
|
<div className={styles.logRows} data-testid="logRowsTable"> |
|
|
|
@ -757,7 +757,7 @@ class UnthemedLogs extends PureComponent<Props, State> { |
|
|
|
|
clearCache={clearCache} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</Collapse> |
|
|
|
|
</PanelChrome> |
|
|
|
|
</> |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
@ -816,5 +816,9 @@ const getStyles = (theme: GrafanaTheme2, wrapLogMessage: boolean) => { |
|
|
|
|
visualisationTypeRadio: css` |
|
|
|
|
margin: 0 0 0 ${theme.spacing(1)}; |
|
|
|
|
`,
|
|
|
|
|
stickyNavigation: css` |
|
|
|
|
${scrollableLogsContainer && 'margin-bottom: 0px'} |
|
|
|
|
overflow: visible; |
|
|
|
|
`,
|
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|