mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[Synthetics] Add availability sparklines on summary page (#135292)
This commit is contained in:
parent
af2557b31a
commit
b127231787
6 changed files with 113 additions and 11 deletions
|
@ -29,10 +29,11 @@ import {
|
|||
TypedLensByValueInput,
|
||||
XYCurveType,
|
||||
XYState,
|
||||
FormulaPublicApi,
|
||||
YAxisMode,
|
||||
MinIndexPatternColumn,
|
||||
MaxIndexPatternColumn,
|
||||
FormulaPublicApi,
|
||||
FormulaIndexPatternColumn,
|
||||
} from '@kbn/lens-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { PersistableFilter } from '@kbn/lens-plugin/common';
|
||||
|
@ -47,6 +48,7 @@ import {
|
|||
PERCENTILE,
|
||||
PERCENTILE_RANKS,
|
||||
ReportTypes,
|
||||
FORMULA_COLUMN,
|
||||
} from './constants';
|
||||
import {
|
||||
ColumnFilter,
|
||||
|
@ -403,10 +405,11 @@ export class LensAttributes {
|
|||
layerConfig: LayerConfig,
|
||||
layerId: string,
|
||||
columnFilter?: string
|
||||
): Record<string, FieldBasedIndexPatternColumn> {
|
||||
): Record<string, FieldBasedIndexPatternColumn | FormulaIndexPatternColumn> {
|
||||
const yAxisColumns = layerConfig.seriesConfig.yAxisColumns;
|
||||
const { sourceField: mainSourceField, label: mainLabel } = yAxisColumns[0];
|
||||
const lensColumns: Record<string, FieldBasedIndexPatternColumn> = {};
|
||||
const lensColumns: Record<string, FieldBasedIndexPatternColumn | FormulaIndexPatternColumn> =
|
||||
{};
|
||||
|
||||
// start at 1, because main y axis will have the first percentile breakdown
|
||||
for (let i = 1; i < PERCENTILE_RANKS.length; i++) {
|
||||
|
@ -522,6 +525,7 @@ export class LensAttributes {
|
|||
}) {
|
||||
const { breakdown, seriesConfig } = layerConfig;
|
||||
const {
|
||||
formula,
|
||||
fieldMeta,
|
||||
columnType,
|
||||
fieldName,
|
||||
|
@ -531,6 +535,16 @@ export class LensAttributes {
|
|||
showPercentileAnnotations,
|
||||
} = this.getFieldMeta(sourceField, layerConfig);
|
||||
|
||||
if (columnType === FORMULA_COLUMN) {
|
||||
return getDistributionInPercentageColumn({
|
||||
layerId,
|
||||
formula,
|
||||
label: columnLabel ?? label,
|
||||
dataView: layerConfig.indexPattern,
|
||||
lensFormulaHelper: this.lensFormulaHelper!,
|
||||
}).main;
|
||||
}
|
||||
|
||||
if (showPercentileAnnotations) {
|
||||
this.addThresholdLayer(fieldName, layerId, layerConfig);
|
||||
}
|
||||
|
@ -607,9 +621,11 @@ export class LensAttributes {
|
|||
timeScale,
|
||||
paramFilters,
|
||||
showPercentileAnnotations,
|
||||
formula,
|
||||
} = parseCustomFieldName(layerConfig.seriesConfig, layerConfig.selectedMetricField);
|
||||
const fieldMeta = layerConfig.indexPattern.getFieldByName(fieldName!);
|
||||
return {
|
||||
formula,
|
||||
palette,
|
||||
fieldMeta,
|
||||
fieldName,
|
||||
|
@ -666,7 +682,10 @@ export class LensAttributes {
|
|||
forAccessorsKeys?: boolean
|
||||
) {
|
||||
const { breakdown } = layerConfig;
|
||||
const lensColumns: Record<string, FieldBasedIndexPatternColumn | SumIndexPatternColumn> = {};
|
||||
const lensColumns: Record<
|
||||
string,
|
||||
FieldBasedIndexPatternColumn | SumIndexPatternColumn | FormulaIndexPatternColumn
|
||||
> = {};
|
||||
const yAxisColumns = layerConfig.seriesConfig.yAxisColumns;
|
||||
const { sourceField: mainSourceField, label: mainLabel } = yAxisColumns[0];
|
||||
|
||||
|
@ -680,6 +699,20 @@ export class LensAttributes {
|
|||
}).supportingColumns;
|
||||
}
|
||||
|
||||
if (mainSourceField && !forAccessorsKeys) {
|
||||
const { columnLabel, formula, columnType } = this.getFieldMeta(mainSourceField, layerConfig);
|
||||
|
||||
if (columnType === FORMULA_COLUMN) {
|
||||
return getDistributionInPercentageColumn({
|
||||
label: columnLabel,
|
||||
layerId,
|
||||
formula,
|
||||
dataView: layerConfig.indexPattern,
|
||||
lensFormulaHelper: this.lensFormulaHelper!,
|
||||
}).supportingColumns;
|
||||
}
|
||||
}
|
||||
|
||||
if (yAxisColumns.length === 1 && breakdown === PERCENTILE) {
|
||||
return this.getPercentileBreakdowns(layerConfig, layerId, columnFilter);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { FormulaPublicApi } from '@kbn/lens-plugin/public';
|
||||
import { FormulaIndexPatternColumn, FormulaPublicApi } from '@kbn/lens-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
|
||||
export function getDistributionInPercentageColumn({
|
||||
|
@ -13,19 +13,22 @@ export function getDistributionInPercentageColumn({
|
|||
dataView,
|
||||
columnFilter,
|
||||
lensFormulaHelper,
|
||||
formula,
|
||||
}: {
|
||||
label?: string;
|
||||
columnFilter?: string;
|
||||
layerId: string;
|
||||
lensFormulaHelper: FormulaPublicApi;
|
||||
dataView: DataView;
|
||||
formula?: string;
|
||||
}) {
|
||||
const yAxisColId = `y-axis-column-${layerId}`;
|
||||
|
||||
let lensFormula = 'count() / overall_sum(count())';
|
||||
let lensFormula = formula ?? 'count() / overall_sum(count())';
|
||||
|
||||
if (columnFilter) {
|
||||
lensFormula = `count(kql='${columnFilter}') / overall_sum(count(kql='${columnFilter}'))`;
|
||||
lensFormula =
|
||||
formula ?? `count(kql='${columnFilter}') / overall_sum(count(kql='${columnFilter}'))`;
|
||||
}
|
||||
|
||||
const { columns } = lensFormulaHelper?.insertOrReplaceFormulaColumn(
|
||||
|
@ -49,5 +52,5 @@ export function getDistributionInPercentageColumn({
|
|||
|
||||
const { [yAxisColId]: main, ...supportingColumns } = columns;
|
||||
|
||||
return { main: columns[yAxisColId], supportingColumns };
|
||||
return { main: columns[yAxisColId] as FormulaIndexPatternColumn, supportingColumns };
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
REPORT_METRIC_FIELD,
|
||||
PERCENTILE,
|
||||
ReportTypes,
|
||||
FORMULA_COLUMN,
|
||||
} from '../constants';
|
||||
import {
|
||||
CLS_LABEL,
|
||||
|
@ -86,6 +87,12 @@ export function getSyntheticsKPIConfig({ dataView }: ConfigProps): SeriesConfig
|
|||
id: MONITOR_DURATION_US,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
{
|
||||
label: 'Monitor availability',
|
||||
id: 'monitor_availability',
|
||||
columnType: FORMULA_COLUMN,
|
||||
formula: "1- (count(kql='summary.down > 0') / count())",
|
||||
},
|
||||
{
|
||||
field: SUMMARY_UP,
|
||||
id: SUMMARY_UP,
|
||||
|
|
|
@ -42,6 +42,7 @@ export interface ExploratoryEmbeddableProps {
|
|||
isSingleMetric?: boolean;
|
||||
legendIsVisible?: boolean;
|
||||
legendPosition?: Position;
|
||||
hideTicks?: boolean;
|
||||
onBrushEnd?: (param: { range: number[] }) => void;
|
||||
caseOwner?: string;
|
||||
reportConfigMap?: ReportConfigMap;
|
||||
|
@ -83,6 +84,7 @@ export default function Embeddable({
|
|||
withActions = true,
|
||||
lensFormulaHelper,
|
||||
align,
|
||||
hideTicks,
|
||||
}: ExploratoryEmbeddableComponentProps) {
|
||||
const LensComponent = lens?.EmbeddableComponent;
|
||||
const LensSaveModalComponent = lens?.SaveModalComponent;
|
||||
|
@ -127,6 +129,14 @@ export default function Embeddable({
|
|||
(attributesJSON.state.visualization as XYState).legend.position = legendPosition;
|
||||
}
|
||||
|
||||
if (hideTicks) {
|
||||
(attributesJSON.state.visualization as XYState).tickLabelsVisibilitySettings = {
|
||||
x: false,
|
||||
yRight: false,
|
||||
yLeft: false,
|
||||
};
|
||||
}
|
||||
|
||||
const actions = useActions({
|
||||
withActions,
|
||||
attributes,
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { ReportTypes, useTheme } from '@kbn/observability-plugin/public';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { ClientPluginsStart } from '../../../../../plugin';
|
||||
|
||||
export const AvailabilitySparklines = () => {
|
||||
const {
|
||||
services: {
|
||||
observability: { ExploratoryViewEmbeddable },
|
||||
},
|
||||
} = useKibana<ClientPluginsStart>();
|
||||
const { monitorId } = useParams<{ monitorId: string }>();
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ExploratoryViewEmbeddable
|
||||
reportType={ReportTypes.KPI}
|
||||
axisTitlesVisibility={{ x: false, yRight: false, yLeft: false }}
|
||||
legendIsVisible={false}
|
||||
hideTicks={true}
|
||||
attributes={[
|
||||
{
|
||||
seriesType: 'area',
|
||||
time: { from: 'now-15m/m', to: 'now' },
|
||||
name: 'Monitor availability',
|
||||
dataType: 'synthetics',
|
||||
selectedMetricField: 'monitor_availability',
|
||||
reportDefinitions: { 'monitor.id': [monitorId] },
|
||||
color: theme.eui.euiColorVis1,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -13,6 +13,7 @@ import { MonitorDurationTrend } from './duration_trend';
|
|||
import { StepDurationPanel } from './step_duration_panel';
|
||||
import { AvailabilityPanel } from './availability_panel';
|
||||
import { MonitorDetailsPanel } from './monitor_details_panel';
|
||||
import { AvailabilitySparklines } from './availability_sparklines';
|
||||
|
||||
export const SummaryTabContent = () => {
|
||||
return (
|
||||
|
@ -27,17 +28,20 @@ export const SummaryTabContent = () => {
|
|||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={2}>
|
||||
<EuiPanel style={{ paddingBottom: 0 }}>
|
||||
<EuiPanel style={{ paddingBottom: 0, height: 150 }}>
|
||||
<EuiTitle size="xs">
|
||||
<h3>{LAST_30DAYS_LABEL}</h3>
|
||||
</EuiTitle>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexGroup gutterSize="none">
|
||||
<EuiFlexItem>
|
||||
<AvailabilityPanel />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>{/* TODO: Add availability sparkline*/}</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<AvailabilitySparklines />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>{/* TODO: Add duration metric*/}</EuiFlexItem>
|
||||
<EuiFlexItem>{/* TODO: Add duration metric sparkline*/}</EuiFlexItem>
|
||||
<EuiFlexItem>{/* TODO: Add error metric and sparkline*/}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
<EuiSpacer size="s" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue