/usr/share/grafana/public/app/features/explore/Logs
import { css } from '@emotion/css'; import { identity } from 'lodash'; import * as React from 'react'; import { AbsoluteTimeRange, DataQueryResponse, LoadingState, SplitOpen, EventBus, GrafanaTheme2, DataFrame, TimeRange, } from '@grafana/data'; import { t } from '@grafana/i18n'; import { TimeZone } from '@grafana/schema'; import { Icon, SeriesVisibilityChangeMode, Tooltip, TooltipDisplayMode, useStyles2, useTheme2 } from '@grafana/ui'; import { getLogsVolumeDataSourceInfo, isLogsVolumeLimited } from '../../logs/utils'; import { ExploreGraph } from '../Graph/ExploreGraph'; type Props = { logsVolumeData: DataQueryResponse; allLogsVolumeMaximum: number; timeRange: TimeRange; timeZone: TimeZone; splitOpen: SplitOpen; width: number; onUpdateTimeRange: (timeRange: AbsoluteTimeRange) => void; onLoadLogsVolume: () => void; onHiddenSeriesChanged: (hiddenSeries: string[]) => void; eventBus: EventBus; annotations: DataFrame[]; toggleLegendRef?: | React.MutableRefObject<(name: string | undefined, mode: SeriesVisibilityChangeMode) => void> | undefined; }; export function LogsVolumePanel(props: Props) { const { width, timeZone, splitOpen, onUpdateTimeRange, onHiddenSeriesChanged, allLogsVolumeMaximum, toggleLegendRef, } = props; const theme = useTheme2(); const styles = useStyles2(getStyles); const spacing = parseInt(theme.spacing(2).slice(0, -2), 10); const height = 150; const logsVolumeData = props.logsVolumeData; const logsVolumeInfo = getLogsVolumeDataSourceInfo(logsVolumeData?.data); let extraInfo = logsVolumeInfo ? `${logsVolumeInfo.name}` : ''; if (isLogsVolumeLimited(logsVolumeData.data)) { extraInfo = [ extraInfo, 'This datasource does not support full-range histograms. The graph below is based on the logs seen in the response.', ] .filter(identity) .join('. '); } let extraInfoComponent = <span>{extraInfo}</span>; if (logsVolumeData.state === LoadingState.Streaming) { extraInfoComponent = ( <> {extraInfoComponent} <Tooltip content={t('explore.logs-volume-panel.content-streaming', 'Streaming')}> <Icon name="circle-mono" size="md" className={styles.streaming} data-testid="logs-volume-streaming" /> </Tooltip> </> ); } return ( <div style={{ height }} className={styles.contentContainer}> <ExploreGraph toggleLegendRef={toggleLegendRef} vizLegendOverrides={{ calcs: ['sum'], }} graphStyle="lines" loadingState={logsVolumeData.state ?? LoadingState.Done} data={logsVolumeData.data} height={height} width={width - spacing * 2} timeRange={props.timeRange} onChangeTime={onUpdateTimeRange} timeZone={timeZone} splitOpenFn={splitOpen} tooltipDisplayMode={TooltipDisplayMode.Multi} onHiddenSeriesChanged={onHiddenSeriesChanged} anchorToZero yAxisMaximum={allLogsVolumeMaximum} eventBus={props.eventBus} annotations={props.annotations} /> {extraInfoComponent && <div className={styles.extraInfoContainer}>{extraInfoComponent}</div>} </div> ); } const getStyles = (theme: GrafanaTheme2) => { return { extraInfoContainer: css({ display: 'flex', justifyContent: 'end', position: 'absolute', right: '5px', top: '-10px', fontSize: theme.typography.bodySmall.fontSize, color: theme.colors.text.secondary, }), contentContainer: css({ display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', }), streaming: css({ color: theme.colors.success.text, }), }; };
.
Edit
..
Edit
LiveLogs.test.tsx
Edit
LiveLogs.tsx
Edit
Logs.test.tsx
Edit
Logs.tsx
Edit
LogsColumnSearch.tsx
Edit
LogsContainer.tsx
Edit
LogsFeedback.tsx
Edit
LogsMetaRow.test.tsx
Edit
LogsMetaRow.tsx
Edit
LogsNavigation.test.tsx
Edit
LogsNavigation.tsx
Edit
LogsNavigationPages.test.tsx
Edit
LogsNavigationPages.tsx
Edit
LogsSamplePanel.test.tsx
Edit
LogsSamplePanel.tsx
Edit
LogsTable.test.tsx
Edit
LogsTable.tsx
Edit
LogsTableWrap.test.tsx
Edit
LogsTableWrap.tsx
Edit
LogsVolumePanel.test.tsx
Edit
LogsVolumePanel.tsx
Edit
LogsVolumePanelList.test.tsx
Edit
LogsVolumePanelList.tsx
Edit
PopoverMenu.test.tsx
Edit
PopoverMenu.tsx
Edit
utils
Edit