mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* [Infra UI] Add Docker section to node detail page * Add chart with terms aggregation for top 5 CPU and Memory - Add label to series returned from metrics endpoint - Honor seriesOverride name or use label - Fix chart tooltip for long names - Add name to seriesOverrides for current layouts * Fixing types * removing point changes, handled in seperate pr * Changing infMetricsExplorerChart className to infrastructureChart * updating comment with new functionality * updating id to human readable string
This commit is contained in:
parent
a86b6b3d51
commit
6d5824ed31
22 changed files with 837 additions and 246 deletions
|
@ -309,6 +309,8 @@ export interface InfraMetricData {
|
|||
export interface InfraDataSeries {
|
||||
id: string;
|
||||
|
||||
label: string;
|
||||
|
||||
data: InfraDataPoint[];
|
||||
}
|
||||
|
||||
|
@ -574,6 +576,10 @@ export enum InfraMetric {
|
|||
hostLoad = 'hostLoad',
|
||||
hostMemoryUsage = 'hostMemoryUsage',
|
||||
hostNetworkTraffic = 'hostNetworkTraffic',
|
||||
hostDockerOverview = 'hostDockerOverview',
|
||||
hostDockerInfo = 'hostDockerInfo',
|
||||
hostDockerTop5ByCpu = 'hostDockerTop5ByCpu',
|
||||
hostDockerTop5ByMemory = 'hostDockerTop5ByMemory',
|
||||
podOverview = 'podOverview',
|
||||
podCpuUsage = 'podCpuUsage',
|
||||
podMemoryUsage = 'podMemoryUsage',
|
||||
|
@ -839,6 +845,8 @@ export namespace MetricsQuery {
|
|||
|
||||
id: string;
|
||||
|
||||
label: string;
|
||||
|
||||
data: Data[];
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
import React, { useCallback } from 'react';
|
||||
import moment from 'moment';
|
||||
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { get } from 'lodash';
|
||||
import {
|
||||
Axis,
|
||||
|
@ -40,109 +40,107 @@ interface Props {
|
|||
onChangeRangeTime?: (time: MetricsTimeInput) => void;
|
||||
isLiveStreaming?: boolean;
|
||||
stopLiveStreaming?: () => void;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
export const ChartSection = injectI18n(
|
||||
({ onChangeRangeTime, section, metric, intl, stopLiveStreaming, isLiveStreaming }: Props) => {
|
||||
const { visConfig } = section;
|
||||
const [dateFormat] = useKibanaUiSetting('dateFormat');
|
||||
const formatter = get(visConfig, 'formatter', InfraFormatterType.number);
|
||||
const formatterTemplate = get(visConfig, 'formatterTemplate', '{{value}}');
|
||||
const valueFormatter = useCallback(getFormatter(formatter, formatterTemplate), [
|
||||
formatter,
|
||||
formatterTemplate,
|
||||
]);
|
||||
const dateFormatter = useCallback(niceTimeFormatter(getMaxMinTimestamp(metric)), [metric]);
|
||||
const handleTimeChange = useCallback(
|
||||
(from: number, to: number) => {
|
||||
if (onChangeRangeTime) {
|
||||
if (isLiveStreaming && stopLiveStreaming) {
|
||||
stopLiveStreaming();
|
||||
}
|
||||
onChangeRangeTime({
|
||||
from: moment(from).toISOString(),
|
||||
to: moment(to).toISOString(),
|
||||
interval: '>=1m',
|
||||
});
|
||||
export const ChartSection = ({
|
||||
onChangeRangeTime,
|
||||
section,
|
||||
metric,
|
||||
stopLiveStreaming,
|
||||
isLiveStreaming,
|
||||
}: Props) => {
|
||||
const { visConfig } = section;
|
||||
const [dateFormat] = useKibanaUiSetting('dateFormat');
|
||||
const formatter = get(visConfig, 'formatter', InfraFormatterType.number);
|
||||
const formatterTemplate = get(visConfig, 'formatterTemplate', '{{value}}');
|
||||
const valueFormatter = useCallback(getFormatter(formatter, formatterTemplate), [
|
||||
formatter,
|
||||
formatterTemplate,
|
||||
]);
|
||||
const dateFormatter = useCallback(niceTimeFormatter(getMaxMinTimestamp(metric)), [metric]);
|
||||
const handleTimeChange = useCallback(
|
||||
(from: number, to: number) => {
|
||||
if (onChangeRangeTime) {
|
||||
if (isLiveStreaming && stopLiveStreaming) {
|
||||
stopLiveStreaming();
|
||||
}
|
||||
},
|
||||
[onChangeRangeTime, isLiveStreaming, stopLiveStreaming]
|
||||
);
|
||||
const tooltipProps = {
|
||||
headerFormatter: useCallback(
|
||||
(data: TooltipValue) => moment(data.value).format(dateFormat || 'Y-MM-DD HH:mm:ss.SSS'),
|
||||
[dateFormat]
|
||||
),
|
||||
};
|
||||
|
||||
if (!metric) {
|
||||
return (
|
||||
<ErrorMessage
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.chartSection.missingMetricDataText',
|
||||
defaultMessage: 'Missing Data',
|
||||
})}
|
||||
body={intl.formatMessage({
|
||||
id: 'xpack.infra.chartSection.missingMetricDataBody',
|
||||
defaultMessage: 'The data for this chart is missing.',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (metric.series.some(seriesHasLessThen2DataPoints)) {
|
||||
return (
|
||||
<ErrorMessage
|
||||
title={intl.formatMessage({
|
||||
id: 'xpack.infra.chartSection.notEnoughDataPointsToRenderTitle',
|
||||
defaultMessage: 'Not Enough Data',
|
||||
})}
|
||||
body={intl.formatMessage({
|
||||
id: 'xpack.infra.chartSection.notEnoughDataPointsToRenderText',
|
||||
defaultMessage:
|
||||
'Not enough data points to render chart, try increasing the time range.',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
onChangeRangeTime({
|
||||
from: moment(from).toISOString(),
|
||||
to: moment(to).toISOString(),
|
||||
interval: '>=1m',
|
||||
});
|
||||
}
|
||||
},
|
||||
[onChangeRangeTime, isLiveStreaming, stopLiveStreaming]
|
||||
);
|
||||
const tooltipProps = {
|
||||
headerFormatter: useCallback(
|
||||
(data: TooltipValue) => moment(data.value).format(dateFormat || 'Y-MM-DD HH:mm:ss.SSS'),
|
||||
[dateFormat]
|
||||
),
|
||||
};
|
||||
|
||||
if (!metric) {
|
||||
return (
|
||||
<EuiPageContentBody>
|
||||
<EuiTitle size="xs">
|
||||
<h3 id={section.id}>{section.label}</h3>
|
||||
</EuiTitle>
|
||||
<div style={{ height: 250, marginBottom: 16 }}>
|
||||
<Chart>
|
||||
<Axis
|
||||
id={getAxisId('timestamp')}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={dateFormatter}
|
||||
/>
|
||||
<Axis id={getAxisId('values')} position={Position.Left} tickFormat={valueFormatter} />
|
||||
{metric &&
|
||||
metric.series.map(series => (
|
||||
<SeriesChart
|
||||
key={`series-${section.id}-${series.id}`}
|
||||
id={`series-${section.id}-${series.id}`}
|
||||
series={series}
|
||||
name={getChartName(section, series.id)}
|
||||
type={getChartType(section, series.id)}
|
||||
color={getChartColor(section, series.id)}
|
||||
stack={visConfig.stacked}
|
||||
/>
|
||||
))}
|
||||
<Settings
|
||||
tooltip={tooltipProps}
|
||||
onBrushEnd={handleTimeChange}
|
||||
theme={getChartTheme()}
|
||||
showLegend={true}
|
||||
legendPosition="right"
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
</EuiPageContentBody>
|
||||
<ErrorMessage
|
||||
title={i18n.translate('xpack.infra.chartSection.missingMetricDataText', {
|
||||
defaultMessage: 'Missing Data',
|
||||
})}
|
||||
body={i18n.translate('xpack.infra.chartSection.missingMetricDataBody', {
|
||||
defaultMessage: 'The data for this chart is missing.',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
if (metric.series.some(seriesHasLessThen2DataPoints)) {
|
||||
return (
|
||||
<ErrorMessage
|
||||
title={i18n.translate('xpack.infra.chartSection.notEnoughDataPointsToRenderTitle', {
|
||||
defaultMessage: 'Not Enough Data',
|
||||
})}
|
||||
body={i18n.translate('xpack.infra.chartSection.notEnoughDataPointsToRenderText', {
|
||||
defaultMessage: 'Not enough data points to render chart, try increasing the time range.',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiPageContentBody>
|
||||
<EuiTitle size="xs">
|
||||
<h3 id={section.id}>{section.label}</h3>
|
||||
</EuiTitle>
|
||||
<div className="infrastructureChart" style={{ height: 250, marginBottom: 16 }}>
|
||||
<Chart>
|
||||
<Axis
|
||||
id={getAxisId('timestamp')}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={dateFormatter}
|
||||
/>
|
||||
<Axis id={getAxisId('values')} position={Position.Left} tickFormat={valueFormatter} />
|
||||
{metric &&
|
||||
metric.series.map(series => (
|
||||
<SeriesChart
|
||||
key={`series-${section.id}-${series.id}`}
|
||||
id={`series-${section.id}-${series.id}`}
|
||||
series={series}
|
||||
name={getChartName(section, series.id, series.label)}
|
||||
type={getChartType(section, series.id)}
|
||||
color={getChartColor(section, series.id)}
|
||||
stack={visConfig.stacked}
|
||||
/>
|
||||
))}
|
||||
<Settings
|
||||
tooltip={tooltipProps}
|
||||
onBrushEnd={handleTimeChange}
|
||||
theme={getChartTheme()}
|
||||
showLegend={true}
|
||||
legendPosition="right"
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
</EuiPageContentBody>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -53,18 +53,24 @@ export const getMaxMinTimestamp = (metric: InfraMetricData): [number, number] =>
|
|||
* Returns the chart name from the visConfig based on the series id, otherwise it
|
||||
* just returns the seriesId
|
||||
*/
|
||||
export const getChartName = (section: InfraMetricLayoutSection, seriesId: string) => {
|
||||
return get(section, ['visConfig', 'seriesOverrides', seriesId, 'name'], seriesId);
|
||||
export const getChartName = (
|
||||
section: InfraMetricLayoutSection,
|
||||
seriesId: string,
|
||||
label: string
|
||||
) => {
|
||||
return get(section, ['visConfig', 'seriesOverrides', seriesId, 'name'], label);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the chart color from the visConfig based on the series id, otherwise it
|
||||
* just returns a default color of #999
|
||||
* just returns null if the color doesn't exists in the overrides.
|
||||
*/
|
||||
export const getChartColor = (section: InfraMetricLayoutSection, seriesId: string) => {
|
||||
const color = new Color(
|
||||
get(section, ['visConfig', 'seriesOverrides', seriesId, 'color'], '#999')
|
||||
);
|
||||
const rawColor: string | null = get(section, ['visConfig', 'seriesOverrides', seriesId, 'color']);
|
||||
if (!rawColor) {
|
||||
return null;
|
||||
}
|
||||
const color = new Color(rawColor);
|
||||
return color.hex().toString();
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import { InfraDataSeries } from '../../../graphql/types';
|
|||
interface Props {
|
||||
id: string;
|
||||
name: string;
|
||||
color: string;
|
||||
color: string | null;
|
||||
series: InfraDataSeries;
|
||||
type: InfraMetricLayoutVisualizationType;
|
||||
stack: boolean | undefined;
|
||||
|
@ -57,7 +57,7 @@ export const AreaChart = ({ id, color, series, name, type, stack }: Props) => {
|
|||
specId: getSpecId(id),
|
||||
};
|
||||
const customColors: CustomSeriesColorsMap = new Map();
|
||||
customColors.set(colors, color);
|
||||
customColors.set(colors, color || '#999');
|
||||
return (
|
||||
<AreaSeries
|
||||
id={getSpecId(id)}
|
||||
|
@ -68,7 +68,7 @@ export const AreaChart = ({ id, color, series, name, type, stack }: Props) => {
|
|||
yAccessors={['value']}
|
||||
data={series.data}
|
||||
areaSeriesStyle={style}
|
||||
customSeriesColors={customColors}
|
||||
customSeriesColors={color ? customColors : void 0}
|
||||
stackAccessors={stack ? ['timestamp'] : void 0}
|
||||
/>
|
||||
);
|
||||
|
@ -77,7 +77,7 @@ export const AreaChart = ({ id, color, series, name, type, stack }: Props) => {
|
|||
export const BarChart = ({ id, color, series, name, type, stack }: Props) => {
|
||||
const style: RecursivePartial<BarSeriesStyle> = {
|
||||
rectBorder: {
|
||||
stroke: color,
|
||||
stroke: color || void 0,
|
||||
strokeWidth: 1,
|
||||
visible: true,
|
||||
},
|
||||
|
@ -90,7 +90,7 @@ export const BarChart = ({ id, color, series, name, type, stack }: Props) => {
|
|||
specId: getSpecId(id),
|
||||
};
|
||||
const customColors: CustomSeriesColorsMap = new Map();
|
||||
customColors.set(colors, color);
|
||||
customColors.set(colors, color || '#999');
|
||||
return (
|
||||
<BarSeries
|
||||
id={getSpecId(id)}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { EuiTitle, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import {
|
||||
Axis,
|
||||
|
@ -39,7 +38,6 @@ import { useKibanaUiSetting } from '../../utils/use_kibana_ui_setting';
|
|||
import { calculateDomain } from './helpers/calculate_domain';
|
||||
|
||||
interface Props {
|
||||
intl: InjectedIntl;
|
||||
title?: string | null;
|
||||
onFilter: (query: string) => void;
|
||||
width?: number | string;
|
||||
|
@ -54,122 +52,120 @@ interface Props {
|
|||
}
|
||||
|
||||
export const MetricsExplorerChart = injectUICapabilities(
|
||||
injectI18n(
|
||||
({
|
||||
source,
|
||||
options,
|
||||
chartOptions,
|
||||
series,
|
||||
title,
|
||||
onFilter,
|
||||
height = 200,
|
||||
width = '100%',
|
||||
timeRange,
|
||||
onTimeChange,
|
||||
uiCapabilities,
|
||||
}: Props) => {
|
||||
const { metrics } = options;
|
||||
const [dateFormat] = useKibanaUiSetting('dateFormat');
|
||||
const handleTimeChange = (from: number, to: number) => {
|
||||
onTimeChange(moment(from).toISOString(), moment(to).toISOString());
|
||||
};
|
||||
const dateFormatter = useMemo(
|
||||
() =>
|
||||
series.rows.length > 0
|
||||
? niceTimeFormatter([first(series.rows).timestamp, last(series.rows).timestamp])
|
||||
: (value: number) => `${value}`,
|
||||
[series.rows]
|
||||
);
|
||||
const tooltipProps = {
|
||||
headerFormatter: useCallback(
|
||||
(data: TooltipValue) => moment(data.value).format(dateFormat || 'Y-MM-DD HH:mm:ss.SSS'),
|
||||
[dateFormat]
|
||||
),
|
||||
};
|
||||
const yAxisFormater = useCallback(createFormatterForMetric(first(metrics)), [options]);
|
||||
const dataDomain = calculateDomain(series, metrics, chartOptions.stack);
|
||||
const domain =
|
||||
chartOptions.yAxisMode === MetricsExplorerYAxisMode.fromZero
|
||||
? { ...dataDomain, min: 0 }
|
||||
: dataDomain;
|
||||
return (
|
||||
<div style={{ padding: 24 }}>
|
||||
{options.groupBy ? (
|
||||
<EuiTitle size="xs">
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<ChartTitle>
|
||||
<EuiToolTip content={title}>
|
||||
<span>{title}</span>
|
||||
</EuiToolTip>
|
||||
</ChartTitle>
|
||||
<EuiFlexItem grow={false}>
|
||||
<MetricsExplorerChartContextMenu
|
||||
timeRange={timeRange}
|
||||
options={options}
|
||||
chartOptions={chartOptions}
|
||||
series={series}
|
||||
onFilter={onFilter}
|
||||
source={source}
|
||||
uiCapabilities={uiCapabilities}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiTitle>
|
||||
) : (
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
({
|
||||
source,
|
||||
options,
|
||||
chartOptions,
|
||||
series,
|
||||
title,
|
||||
onFilter,
|
||||
height = 200,
|
||||
width = '100%',
|
||||
timeRange,
|
||||
onTimeChange,
|
||||
uiCapabilities,
|
||||
}: Props) => {
|
||||
const { metrics } = options;
|
||||
const [dateFormat] = useKibanaUiSetting('dateFormat');
|
||||
const handleTimeChange = (from: number, to: number) => {
|
||||
onTimeChange(moment(from).toISOString(), moment(to).toISOString());
|
||||
};
|
||||
const dateFormatter = useMemo(
|
||||
() =>
|
||||
series.rows.length > 0
|
||||
? niceTimeFormatter([first(series.rows).timestamp, last(series.rows).timestamp])
|
||||
: (value: number) => `${value}`,
|
||||
[series.rows]
|
||||
);
|
||||
const tooltipProps = {
|
||||
headerFormatter: useCallback(
|
||||
(data: TooltipValue) => moment(data.value).format(dateFormat || 'Y-MM-DD HH:mm:ss.SSS'),
|
||||
[dateFormat]
|
||||
),
|
||||
};
|
||||
const yAxisFormater = useCallback(createFormatterForMetric(first(metrics)), [options]);
|
||||
const dataDomain = calculateDomain(series, metrics, chartOptions.stack);
|
||||
const domain =
|
||||
chartOptions.yAxisMode === MetricsExplorerYAxisMode.fromZero
|
||||
? { ...dataDomain, min: 0 }
|
||||
: dataDomain;
|
||||
return (
|
||||
<div style={{ padding: 24 }}>
|
||||
{options.groupBy ? (
|
||||
<EuiTitle size="xs">
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<ChartTitle>
|
||||
<EuiToolTip content={title}>
|
||||
<span>{title}</span>
|
||||
</EuiToolTip>
|
||||
</ChartTitle>
|
||||
<EuiFlexItem grow={false}>
|
||||
<MetricsExplorerChartContextMenu
|
||||
timeRange={timeRange}
|
||||
options={options}
|
||||
chartOptions={chartOptions}
|
||||
series={series}
|
||||
onFilter={onFilter}
|
||||
source={source}
|
||||
timeRange={timeRange}
|
||||
uiCapabilities={uiCapabilities}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiTitle>
|
||||
) : (
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<MetricsExplorerChartContextMenu
|
||||
options={options}
|
||||
chartOptions={chartOptions}
|
||||
series={series}
|
||||
source={source}
|
||||
timeRange={timeRange}
|
||||
uiCapabilities={uiCapabilities}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
<div className="infrastructureChart" style={{ height, width }}>
|
||||
{series.rows.length > 0 ? (
|
||||
<Chart>
|
||||
{metrics.map((metric, id) => (
|
||||
<MetricExplorerSeriesChart
|
||||
type={chartOptions.type}
|
||||
key={id}
|
||||
metric={metric}
|
||||
id={id}
|
||||
series={series}
|
||||
stack={chartOptions.stack}
|
||||
/>
|
||||
))}
|
||||
<Axis
|
||||
id={getAxisId('timestamp')}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={dateFormatter}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId('values')}
|
||||
position={Position.Left}
|
||||
tickFormat={yAxisFormater}
|
||||
domain={domain}
|
||||
/>
|
||||
<Settings
|
||||
tooltip={tooltipProps}
|
||||
onBrushEnd={handleTimeChange}
|
||||
theme={getChartTheme()}
|
||||
/>
|
||||
</Chart>
|
||||
) : options.metrics.length > 0 ? (
|
||||
<MetricsExplorerEmptyChart />
|
||||
) : (
|
||||
<MetricsExplorerNoMetrics />
|
||||
)}
|
||||
<div className="infMetricsExplorerChart" style={{ height, width }}>
|
||||
{series.rows.length > 0 ? (
|
||||
<Chart>
|
||||
{metrics.map((metric, id) => (
|
||||
<MetricExplorerSeriesChart
|
||||
type={chartOptions.type}
|
||||
key={id}
|
||||
metric={metric}
|
||||
id={id}
|
||||
series={series}
|
||||
stack={chartOptions.stack}
|
||||
/>
|
||||
))}
|
||||
<Axis
|
||||
id={getAxisId('timestamp')}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={dateFormatter}
|
||||
/>
|
||||
<Axis
|
||||
id={getAxisId('values')}
|
||||
position={Position.Left}
|
||||
tickFormat={yAxisFormater}
|
||||
domain={domain}
|
||||
/>
|
||||
<Settings
|
||||
tooltip={tooltipProps}
|
||||
onBrushEnd={handleTimeChange}
|
||||
theme={getChartTheme()}
|
||||
/>
|
||||
</Chart>
|
||||
) : options.metrics.length > 0 ? (
|
||||
<MetricsExplorerEmptyChart />
|
||||
) : (
|
||||
<MetricsExplorerNoMetrics />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const ChartTitle = euiStyled.div`
|
||||
|
|
|
@ -26,6 +26,7 @@ export const metricsQuery = gql`
|
|||
id
|
||||
series {
|
||||
id
|
||||
label
|
||||
data {
|
||||
timestamp
|
||||
value
|
||||
|
|
|
@ -2429,6 +2429,30 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "hostDockerOverview",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "hostDockerInfo",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "hostDockerTop5ByCpu",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "hostDockerTop5ByMemory",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "podOverview",
|
||||
"description": "",
|
||||
|
@ -2621,6 +2645,18 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "label",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": { "kind": "SCALAR", "name": "String", "ofType": null }
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"description": "",
|
||||
|
|
|
@ -309,6 +309,8 @@ export interface InfraMetricData {
|
|||
export interface InfraDataSeries {
|
||||
id: string;
|
||||
|
||||
label: string;
|
||||
|
||||
data: InfraDataPoint[];
|
||||
}
|
||||
|
||||
|
@ -574,6 +576,10 @@ export enum InfraMetric {
|
|||
hostLoad = 'hostLoad',
|
||||
hostMemoryUsage = 'hostMemoryUsage',
|
||||
hostNetworkTraffic = 'hostNetworkTraffic',
|
||||
hostDockerOverview = 'hostDockerOverview',
|
||||
hostDockerInfo = 'hostDockerInfo',
|
||||
hostDockerTop5ByCpu = 'hostDockerTop5ByCpu',
|
||||
hostDockerTop5ByMemory = 'hostDockerTop5ByMemory',
|
||||
podOverview = 'podOverview',
|
||||
podCpuUsage = 'podCpuUsage',
|
||||
podMemoryUsage = 'podMemoryUsage',
|
||||
|
@ -839,6 +845,8 @@ export namespace MetricsQuery {
|
|||
|
||||
id: string;
|
||||
|
||||
label: string;
|
||||
|
||||
data: Data[];
|
||||
};
|
||||
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
// This is a temporary workaround for https://github.com/elastic/kibana/issues/39808
|
||||
// A real fix will most likely depend on changes in elastic-charts.
|
||||
|
||||
.infMetricsExplorerChart .echTooltip {
|
||||
.infrastructureChart .echTooltip {
|
||||
max-width: 90vw;
|
||||
}
|
||||
|
||||
.infrastructureChart .echTooltip__label {
|
||||
overflow-x: hidden;
|
||||
white-space: no-wrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,13 @@ export const containerLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
type: InfraMetricLayoutVisualizationType.area,
|
||||
formatter: InfraFormatterType.percent,
|
||||
seriesOverrides: {
|
||||
cpu: { color: theme.eui.euiColorVis1 },
|
||||
cpu: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.containerMetricsLayout.cpuUsageSection.seriesLabel.cpu',
|
||||
{ defaultMessage: 'cpu' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -114,7 +120,13 @@ export const containerLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
type: InfraMetricLayoutVisualizationType.area,
|
||||
formatter: InfraFormatterType.percent,
|
||||
seriesOverrides: {
|
||||
memory: { color: theme.eui.euiColorVis1 },
|
||||
memory: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.containerMetricsLayout.memoryUsageSection.seriesLabel.memory',
|
||||
{ defaultMessage: 'memory' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -106,13 +106,55 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
type: InfraMetricLayoutVisualizationType.area,
|
||||
formatter: InfraFormatterType.percent,
|
||||
seriesOverrides: {
|
||||
user: { color: theme.eui.euiColorVis0 },
|
||||
system: { color: theme.eui.euiColorVis2 },
|
||||
steal: { color: theme.eui.euiColorVis9 },
|
||||
irq: { color: theme.eui.euiColorVis4 },
|
||||
softirq: { color: theme.eui.euiColorVis6 },
|
||||
iowait: { color: theme.eui.euiColorVis7 },
|
||||
nice: { color: theme.eui.euiColorVis5 },
|
||||
user: {
|
||||
color: theme.eui.euiColorVis0,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.user',
|
||||
{ defaultMessage: 'user' }
|
||||
),
|
||||
},
|
||||
system: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.system',
|
||||
{ defaultMessage: 'system' }
|
||||
),
|
||||
},
|
||||
steal: {
|
||||
color: theme.eui.euiColorVis9,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.steal',
|
||||
{ defaultMessage: 'steal' }
|
||||
),
|
||||
},
|
||||
irq: {
|
||||
color: theme.eui.euiColorVis4,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.irq',
|
||||
{ defaultMessage: 'irq' }
|
||||
),
|
||||
},
|
||||
softirq: {
|
||||
color: theme.eui.euiColorVis6,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.softirq',
|
||||
{ defaultMessage: 'softirq' }
|
||||
),
|
||||
},
|
||||
iowait: {
|
||||
color: theme.eui.euiColorVis7,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.iowait',
|
||||
{ defaultMessage: 'iowait' }
|
||||
),
|
||||
},
|
||||
nice: {
|
||||
color: theme.eui.euiColorVis5,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.cpuUsageSection.seriesLabel.nice',
|
||||
{ defaultMessage: 'nice' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -173,9 +215,27 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
formatter: InfraFormatterType.bytes,
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
seriesOverrides: {
|
||||
used: { color: theme.eui.euiColorVis2 },
|
||||
free: { color: theme.eui.euiColorVis0 },
|
||||
cache: { color: theme.eui.euiColorVis1 },
|
||||
used: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.memoryUsageSection.seriesLabel.used',
|
||||
{ defaultMessage: 'Used' }
|
||||
),
|
||||
},
|
||||
free: {
|
||||
color: theme.eui.euiColorVis0,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.memoryUsageSection.seriesLabel.free',
|
||||
{ defaultMessage: 'Free' }
|
||||
),
|
||||
},
|
||||
cache: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.memoryUsageSection.seriesLabel.cache',
|
||||
{ defaultMessage: 'Cache' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -199,7 +259,7 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.networkTrafficSection.networkRxRateSeriesLabel',
|
||||
{
|
||||
defaultMessage: 'in',
|
||||
defaultMessage: 'In',
|
||||
}
|
||||
),
|
||||
},
|
||||
|
@ -208,7 +268,7 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.hostMetricsLayout.networkTrafficSection.networkTxRateSeriesLabel',
|
||||
{
|
||||
defaultMessage: 'out',
|
||||
defaultMessage: 'Out',
|
||||
}
|
||||
),
|
||||
},
|
||||
|
@ -303,8 +363,21 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
visConfig: {
|
||||
formatter: InfraFormatterType.abbreviatedNumber,
|
||||
seriesOverrides: {
|
||||
capacity: { color: theme.eui.euiColorVis2 },
|
||||
used: { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.area },
|
||||
capacity: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodeCpuCapacitySection.seriesLabel.capacity',
|
||||
{ defaultMessage: 'Capacity' }
|
||||
),
|
||||
},
|
||||
used: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodeCpuCapacitySection.seriesLabel.used',
|
||||
{ defaultMessage: 'Used' }
|
||||
),
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -321,8 +394,21 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
visConfig: {
|
||||
formatter: InfraFormatterType.bytes,
|
||||
seriesOverrides: {
|
||||
capacity: { color: theme.eui.euiColorVis2 },
|
||||
used: { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.area },
|
||||
capacity: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodeMemoryCapacitySection.seriesLabel.capacity',
|
||||
{ defaultMessage: 'Capacity' }
|
||||
),
|
||||
},
|
||||
used: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodeMemoryCapacitySection.seriesLabel.used',
|
||||
{ defaultMessage: 'Used' }
|
||||
),
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -339,8 +425,21 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
visConfig: {
|
||||
formatter: InfraFormatterType.bytes,
|
||||
seriesOverrides: {
|
||||
capacity: { color: theme.eui.euiColorVis2 },
|
||||
used: { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.area },
|
||||
capacity: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodeDiskCapacitySection.seriesLabel.capacity',
|
||||
{ defaultMessage: 'Capacity' }
|
||||
),
|
||||
},
|
||||
used: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodeDiskCapacitySection.seriesLabel.used',
|
||||
{ defaultMessage: 'Used' }
|
||||
),
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -357,13 +456,155 @@ export const hostLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
visConfig: {
|
||||
formatter: InfraFormatterType.number,
|
||||
seriesOverrides: {
|
||||
capacity: { color: theme.eui.euiColorVis2 },
|
||||
used: { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.area },
|
||||
capacity: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodePodCapacitySection.seriesLabel.capacity',
|
||||
{ defaultMessage: 'Capacity' }
|
||||
),
|
||||
},
|
||||
used: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.kubernetesMetricsLayout.nodePodCapacitySection.seriesLabel.used',
|
||||
{ defaultMessage: 'Used' }
|
||||
),
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'dockerOverview',
|
||||
label: 'Docker',
|
||||
sections: [
|
||||
{
|
||||
id: InfraMetric.hostDockerOverview,
|
||||
linkToId: 'dockerOverview',
|
||||
label: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.overviewSection.sectionLabel',
|
||||
{
|
||||
defaultMessage: 'Overview',
|
||||
}
|
||||
),
|
||||
requires: ['docker.info'],
|
||||
type: InfraMetricLayoutSectionType.gauges,
|
||||
visConfig: {
|
||||
seriesOverrides: {
|
||||
total: {
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.overviewSection.totalLabel',
|
||||
{
|
||||
defaultMessage: 'Total',
|
||||
}
|
||||
),
|
||||
color: 'secondary',
|
||||
},
|
||||
running: {
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.overviewSection.runningLabel',
|
||||
{
|
||||
defaultMessage: 'Running',
|
||||
}
|
||||
),
|
||||
color: 'secondary',
|
||||
},
|
||||
paused: {
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.overviewSection.pausedLabel',
|
||||
{
|
||||
defaultMessage: 'Paused',
|
||||
}
|
||||
),
|
||||
color: 'secondary',
|
||||
},
|
||||
stopped: {
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.overviewSection.stoppedLabel',
|
||||
{
|
||||
defaultMessage: 'Stopped',
|
||||
}
|
||||
),
|
||||
color: 'secondary',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: InfraMetric.hostDockerInfo,
|
||||
label: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.containerStates.sectionLabel',
|
||||
{
|
||||
defaultMessage: 'Container States',
|
||||
}
|
||||
),
|
||||
requires: ['docker.info'],
|
||||
type: InfraMetricLayoutSectionType.chart,
|
||||
visConfig: {
|
||||
formatter: InfraFormatterType.abbreviatedNumber,
|
||||
stacked: true,
|
||||
seriesOverrides: {
|
||||
running: {
|
||||
color: theme.eui.euiColorVis2,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.containerStates.seriesLabel.running',
|
||||
{ defaultMessage: 'Running' }
|
||||
),
|
||||
},
|
||||
stopped: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.containerStates.seriesLabel.stopped',
|
||||
{ defaultMessage: 'Stopped' }
|
||||
),
|
||||
},
|
||||
paused: {
|
||||
color: theme.eui.euiColorVis7,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.containerStates.seriesLabel.paused',
|
||||
{ defaultMessage: 'Paused' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: InfraMetric.hostDockerTop5ByCpu,
|
||||
label: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.top5Cpu.sectionLabel',
|
||||
{
|
||||
defaultMessage: 'Top 5 Containers by CPU',
|
||||
}
|
||||
),
|
||||
requires: ['docker.cpu'],
|
||||
type: InfraMetricLayoutSectionType.chart,
|
||||
visConfig: {
|
||||
formatter: InfraFormatterType.percent,
|
||||
seriesOverrides: {},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: InfraMetric.hostDockerTop5ByMemory,
|
||||
label: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.dockerMetricsLayout.top5Memory.sectionLabel',
|
||||
{
|
||||
defaultMessage: 'Top 5 Containers by Memory',
|
||||
}
|
||||
),
|
||||
requires: ['docker.memory'],
|
||||
type: InfraMetricLayoutSectionType.chart,
|
||||
visConfig: {
|
||||
formatter: InfraFormatterType.percent,
|
||||
seriesOverrides: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
...nginxLayoutCreator(theme),
|
||||
...awsLayoutCreator(theme),
|
||||
];
|
||||
|
|
|
@ -32,10 +32,26 @@ export const nginxLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
formatter: InfraFormatterType.abbreviatedNumber,
|
||||
stacked: true,
|
||||
seriesOverrides: {
|
||||
'200s': { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.bar },
|
||||
'300s': { color: theme.eui.euiColorVis5, type: InfraMetricLayoutVisualizationType.bar },
|
||||
'400s': { color: theme.eui.euiColorVis2, type: InfraMetricLayoutVisualizationType.bar },
|
||||
'500s': { color: theme.eui.euiColorVis9, type: InfraMetricLayoutVisualizationType.bar },
|
||||
'200s': {
|
||||
color: theme.eui.euiColorVis1,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: '200s',
|
||||
},
|
||||
'300s': {
|
||||
color: theme.eui.euiColorVis5,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: '300s',
|
||||
},
|
||||
'400s': {
|
||||
color: theme.eui.euiColorVis2,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: '400s',
|
||||
},
|
||||
'500s': {
|
||||
color: theme.eui.euiColorVis9,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: '500s',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -53,7 +69,14 @@ export const nginxLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
formatter: InfraFormatterType.abbreviatedNumber,
|
||||
formatterTemplate: '{{value}}/s',
|
||||
seriesOverrides: {
|
||||
rate: { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.area },
|
||||
rate: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.nginxMetricsLayout.requestRateSection.seriesLabel.rate',
|
||||
{ defaultMessage: 'rate' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -73,6 +96,10 @@ export const nginxLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
connections: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
type: InfraMetricLayoutVisualizationType.bar,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.nginxMetricsLayout.activeConnectionsSection.seriesLabel.connections',
|
||||
{ defaultMessage: 'connections' }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -93,7 +93,14 @@ export const podLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
visConfig: {
|
||||
formatter: InfraFormatterType.percent,
|
||||
seriesOverrides: {
|
||||
cpu: { color: theme.eui.euiColorVis1, type: InfraMetricLayoutVisualizationType.area },
|
||||
cpu: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.podMetricsLayout.cpuUsageSection.seriesLabel.cpu',
|
||||
{ defaultMessage: 'cpu' }
|
||||
),
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -112,6 +119,10 @@ export const podLayoutCreator: InfraMetricLayoutCreator = theme => [
|
|||
seriesOverrides: {
|
||||
memory: {
|
||||
color: theme.eui.euiColorVis1,
|
||||
name: i18n.translate(
|
||||
'xpack.infra.metricDetailPage.podMetricsLayout.memoryUsageSection.seriesLabel.memory',
|
||||
{ defaultMessage: 'memory' }
|
||||
),
|
||||
type: InfraMetricLayoutVisualizationType.area,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -19,6 +19,10 @@ export const metricsSchema: any = gql`
|
|||
hostLoad
|
||||
hostMemoryUsage
|
||||
hostNetworkTraffic
|
||||
hostDockerOverview
|
||||
hostDockerInfo
|
||||
hostDockerTop5ByCpu
|
||||
hostDockerTop5ByMemory
|
||||
podOverview
|
||||
podCpuUsage
|
||||
podMemoryUsage
|
||||
|
@ -51,6 +55,7 @@ export const metricsSchema: any = gql`
|
|||
|
||||
type InfraDataSeries {
|
||||
id: ID!
|
||||
label: String!
|
||||
data: [InfraDataPoint!]!
|
||||
}
|
||||
|
||||
|
|
|
@ -337,6 +337,8 @@ export interface InfraMetricData {
|
|||
export interface InfraDataSeries {
|
||||
id: string;
|
||||
|
||||
label: string;
|
||||
|
||||
data: InfraDataPoint[];
|
||||
}
|
||||
|
||||
|
@ -602,6 +604,10 @@ export enum InfraMetric {
|
|||
hostLoad = 'hostLoad',
|
||||
hostMemoryUsage = 'hostMemoryUsage',
|
||||
hostNetworkTraffic = 'hostNetworkTraffic',
|
||||
hostDockerOverview = 'hostDockerOverview',
|
||||
hostDockerInfo = 'hostDockerInfo',
|
||||
hostDockerTop5ByCpu = 'hostDockerTop5ByCpu',
|
||||
hostDockerTop5ByMemory = 'hostDockerTop5ByMemory',
|
||||
podOverview = 'podOverview',
|
||||
podCpuUsage = 'podCpuUsage',
|
||||
podMemoryUsage = 'podMemoryUsage',
|
||||
|
@ -1693,6 +1699,8 @@ export namespace InfraDataSeriesResolvers {
|
|||
export interface Resolvers<Context = InfraContext, TypeParent = InfraDataSeries> {
|
||||
id?: IdResolver<string, TypeParent, Context>;
|
||||
|
||||
label?: LabelResolver<string, TypeParent, Context>;
|
||||
|
||||
data?: DataResolver<InfraDataPoint[], TypeParent, Context>;
|
||||
}
|
||||
|
||||
|
@ -1701,6 +1709,11 @@ export namespace InfraDataSeriesResolvers {
|
|||
Parent,
|
||||
Context
|
||||
>;
|
||||
export type LabelResolver<
|
||||
R = string,
|
||||
Parent = InfraDataSeries,
|
||||
Context = InfraContext
|
||||
> = Resolver<R, Parent, Context>;
|
||||
export type DataResolver<
|
||||
R = InfraDataPoint[],
|
||||
Parent = InfraDataSeries,
|
||||
|
|
|
@ -204,6 +204,7 @@ export interface InfraTSVBPanel {
|
|||
|
||||
export interface InfraTSVBSeries {
|
||||
id: string;
|
||||
label: string;
|
||||
data: InfraTSVBDataPoint[];
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter {
|
|||
series: panel.series.map(series => {
|
||||
return {
|
||||
id: series.id,
|
||||
label: series.label,
|
||||
data: series.data.map(point => ({ timestamp: point[0], value: point[1] })),
|
||||
};
|
||||
}),
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
InfraMetricModelCreator,
|
||||
InfraMetricModelMetricType,
|
||||
InfraMetricModel,
|
||||
} from '../../adapter_types';
|
||||
import { InfraMetric } from '../../../../../graphql/types';
|
||||
|
||||
export const hostDockerInfo: InfraMetricModelCreator = (
|
||||
timeField,
|
||||
indexPattern,
|
||||
interval
|
||||
): InfraMetricModel => ({
|
||||
id: InfraMetric.hostDockerInfo,
|
||||
requires: ['docker.info'],
|
||||
index_pattern: indexPattern,
|
||||
interval,
|
||||
time_field: timeField,
|
||||
type: 'timeseries',
|
||||
series: [
|
||||
{
|
||||
id: 'running',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.running',
|
||||
id: 'max-running',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
{
|
||||
id: 'paused',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.paused',
|
||||
id: 'max-paused',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
{
|
||||
id: 'stopped',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.stopped',
|
||||
id: 'max-stopped',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
InfraMetricModelCreator,
|
||||
InfraMetricModelMetricType,
|
||||
InfraMetricModel,
|
||||
} from '../../adapter_types';
|
||||
import { InfraMetric } from '../../../../../graphql/types';
|
||||
|
||||
export const hostDockerOverview: InfraMetricModelCreator = (
|
||||
timeField,
|
||||
indexPattern,
|
||||
interval
|
||||
): InfraMetricModel => ({
|
||||
id: InfraMetric.hostDockerOverview,
|
||||
requires: ['docker.info'],
|
||||
index_pattern: indexPattern,
|
||||
interval,
|
||||
time_field: timeField,
|
||||
type: 'gauge',
|
||||
series: [
|
||||
{
|
||||
id: 'total',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.total',
|
||||
id: 'max-total',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
{
|
||||
id: 'running',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.running',
|
||||
id: 'max-running',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
{
|
||||
id: 'paused',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.paused',
|
||||
id: 'max-paused',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
{
|
||||
id: 'stopped',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.info.containers.stopped',
|
||||
id: 'max-stopped',
|
||||
type: InfraMetricModelMetricType.max,
|
||||
},
|
||||
],
|
||||
split_mode: 'everything',
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
InfraMetricModelCreator,
|
||||
InfraMetricModelMetricType,
|
||||
InfraMetricModel,
|
||||
} from '../../adapter_types';
|
||||
import { InfraMetric } from '../../../../../graphql/types';
|
||||
|
||||
export const hostDockerTop5ByCpu: InfraMetricModelCreator = (
|
||||
timeField,
|
||||
indexPattern,
|
||||
interval
|
||||
): InfraMetricModel => ({
|
||||
id: InfraMetric.hostDockerTop5ByCpu,
|
||||
requires: ['docker.cpu'],
|
||||
index_pattern: indexPattern,
|
||||
interval,
|
||||
time_field: timeField,
|
||||
type: 'timeseries',
|
||||
series: [
|
||||
{
|
||||
id: 'avg-cpu',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.cpu.total.pct',
|
||||
id: 'avg-cpu-metric',
|
||||
type: InfraMetricModelMetricType.avg,
|
||||
},
|
||||
],
|
||||
split_mode: 'terms',
|
||||
terms_field: 'container.name',
|
||||
terms_order_by: 'avg-cpu',
|
||||
terms_size: 5,
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
InfraMetricModelCreator,
|
||||
InfraMetricModelMetricType,
|
||||
InfraMetricModel,
|
||||
} from '../../adapter_types';
|
||||
import { InfraMetric } from '../../../../../graphql/types';
|
||||
|
||||
export const hostDockerTop5ByMemory: InfraMetricModelCreator = (
|
||||
timeField,
|
||||
indexPattern,
|
||||
interval
|
||||
): InfraMetricModel => ({
|
||||
id: InfraMetric.hostDockerTop5ByMemory,
|
||||
requires: ['docker.memory'],
|
||||
index_pattern: indexPattern,
|
||||
interval,
|
||||
time_field: timeField,
|
||||
type: 'timeseries',
|
||||
series: [
|
||||
{
|
||||
id: 'avg-memory',
|
||||
metrics: [
|
||||
{
|
||||
field: 'docker.memory.usage.pct',
|
||||
id: 'avg-memory-metric',
|
||||
type: InfraMetricModelMetricType.avg,
|
||||
},
|
||||
],
|
||||
split_mode: 'terms',
|
||||
terms_field: 'container.name',
|
||||
terms_order_by: 'avg-memory',
|
||||
terms_size: 5,
|
||||
},
|
||||
],
|
||||
});
|
|
@ -18,6 +18,10 @@ import { hostLoad } from './host/host_load';
|
|||
import { hostMemoryUsage } from './host/host_memory_usage';
|
||||
import { hostNetworkTraffic } from './host/host_network_traffic';
|
||||
import { hostSystemOverview } from './host/host_system_overview';
|
||||
import { hostDockerOverview } from './host/host_docker_overview';
|
||||
import { hostDockerInfo } from './host/host_docker_info';
|
||||
import { hostDockerTop5ByCpu } from './host/host_docker_top_5_by_cpu';
|
||||
import { hostDockerTop5ByMemory } from './host/host_docker_top_5_by_memory';
|
||||
|
||||
import { podCpuUsage } from './pod/pod_cpu_usage';
|
||||
import { podLogUsage } from './pod/pod_log_usage';
|
||||
|
@ -60,6 +64,10 @@ export const metricModels: InfraMetricModels = {
|
|||
[InfraMetric.hostLoad]: hostLoad,
|
||||
[InfraMetric.hostMemoryUsage]: hostMemoryUsage,
|
||||
[InfraMetric.hostNetworkTraffic]: hostNetworkTraffic,
|
||||
[InfraMetric.hostDockerOverview]: hostDockerOverview,
|
||||
[InfraMetric.hostDockerInfo]: hostDockerInfo,
|
||||
[InfraMetric.hostDockerTop5ByCpu]: hostDockerTop5ByCpu,
|
||||
[InfraMetric.hostDockerTop5ByMemory]: hostDockerTop5ByMemory,
|
||||
|
||||
[InfraMetric.podOverview]: podOverview,
|
||||
[InfraMetric.podCpuUsage]: podCpuUsage,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue