[Exploratory vie] Added synthetics metrics (#103482)
This commit is contained in:
parent
0c8d5e8f89
commit
5aa8305279
|
@ -6,3 +6,8 @@
|
|||
*/
|
||||
|
||||
export const MONITOR_DURATION_US = 'monitor.duration.us';
|
||||
export const SYNTHETICS_CLS = 'browser.experience.cls';
|
||||
export const SYNTHETICS_LCP = 'browser.experience.lcp.us';
|
||||
export const SYNTHETICS_FCP = 'browser.experience.fcp.us';
|
||||
export const SYNTHETICS_DOCUMENT_ONLOAD = 'browser.experience.load.us';
|
||||
export const SYNTHETICS_DCL = 'browser.experience.dcl.us';
|
||||
|
|
|
@ -72,6 +72,17 @@ export const CLS_LABEL = i18n.translate('xpack.observability.expView.fieldLabels
|
|||
defaultMessage: 'Cumulative layout shift',
|
||||
});
|
||||
|
||||
export const DCL_LABEL = i18n.translate('xpack.observability.expView.fieldLabels.dcl', {
|
||||
defaultMessage: 'DOM content loaded',
|
||||
});
|
||||
|
||||
export const DOCUMENT_ONLOAD_LABEL = i18n.translate(
|
||||
'xpack.observability.expView.fieldLabels.onload',
|
||||
{
|
||||
defaultMessage: 'Document complete (onLoad)',
|
||||
}
|
||||
);
|
||||
|
||||
export const BACKEND_TIME_LABEL = i18n.translate(
|
||||
'xpack.observability.expView.fieldLabels.backend',
|
||||
{
|
||||
|
|
|
@ -7,8 +7,23 @@
|
|||
|
||||
import { ConfigProps, SeriesConfig } from '../../types';
|
||||
import { FieldLabels, REPORT_METRIC_FIELD, RECORDS_PERCENTAGE_FIELD } from '../constants';
|
||||
import { buildExistsFilter } from '../utils';
|
||||
import { MONITORS_DURATION_LABEL, PINGS_LABEL } from '../constants/labels';
|
||||
import {
|
||||
CLS_LABEL,
|
||||
DCL_LABEL,
|
||||
DOCUMENT_ONLOAD_LABEL,
|
||||
FCP_LABEL,
|
||||
LCP_LABEL,
|
||||
MONITORS_DURATION_LABEL,
|
||||
PINGS_LABEL,
|
||||
} from '../constants/labels';
|
||||
import {
|
||||
MONITOR_DURATION_US,
|
||||
SYNTHETICS_CLS,
|
||||
SYNTHETICS_DCL,
|
||||
SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
SYNTHETICS_FCP,
|
||||
SYNTHETICS_LCP,
|
||||
} from '../constants/field_names/synthetics';
|
||||
|
||||
export function getSyntheticsDistributionConfig({
|
||||
series,
|
||||
|
@ -37,10 +52,39 @@ export function getSyntheticsDistributionConfig({
|
|||
'tags',
|
||||
'url.port',
|
||||
],
|
||||
baseFilters: [...buildExistsFilter('summary.up', indexPattern)],
|
||||
baseFilters: [],
|
||||
definitionFields: ['monitor.name', 'url.full'],
|
||||
metricOptions: [
|
||||
{ label: 'Monitor duration', id: 'monitor.duration.us', field: 'monitor.duration.us' },
|
||||
{
|
||||
label: MONITORS_DURATION_LABEL,
|
||||
id: MONITOR_DURATION_US,
|
||||
field: MONITOR_DURATION_US,
|
||||
},
|
||||
{
|
||||
label: LCP_LABEL,
|
||||
field: SYNTHETICS_LCP,
|
||||
id: SYNTHETICS_LCP,
|
||||
},
|
||||
{
|
||||
label: FCP_LABEL,
|
||||
field: SYNTHETICS_FCP,
|
||||
id: SYNTHETICS_FCP,
|
||||
},
|
||||
{
|
||||
label: DCL_LABEL,
|
||||
field: SYNTHETICS_DCL,
|
||||
id: SYNTHETICS_DCL,
|
||||
},
|
||||
{
|
||||
label: DOCUMENT_ONLOAD_LABEL,
|
||||
field: SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
id: SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
},
|
||||
{
|
||||
label: CLS_LABEL,
|
||||
field: SYNTHETICS_CLS,
|
||||
id: SYNTHETICS_CLS,
|
||||
},
|
||||
],
|
||||
labels: { ...FieldLabels, 'monitor.duration.us': MONITORS_DURATION_LABEL },
|
||||
};
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
*/
|
||||
|
||||
import { FieldFormat } from '../../types';
|
||||
import {
|
||||
SYNTHETICS_DCL,
|
||||
SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
SYNTHETICS_FCP,
|
||||
SYNTHETICS_LCP,
|
||||
} from '../constants/field_names/synthetics';
|
||||
|
||||
export const syntheticsFieldFormats: FieldFormat[] = [
|
||||
{
|
||||
|
@ -21,4 +27,56 @@ export const syntheticsFieldFormats: FieldFormat[] = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: SYNTHETICS_LCP,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'humanizePrecise',
|
||||
outputPrecision: 1,
|
||||
showSuffix: true,
|
||||
useShortSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: SYNTHETICS_FCP,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'humanizePrecise',
|
||||
outputPrecision: 1,
|
||||
showSuffix: true,
|
||||
useShortSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'humanizePrecise',
|
||||
outputPrecision: 1,
|
||||
showSuffix: true,
|
||||
useShortSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: SYNTHETICS_DCL,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'humanizePrecise',
|
||||
outputPrecision: 1,
|
||||
showSuffix: true,
|
||||
useShortSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
@ -7,9 +7,24 @@
|
|||
|
||||
import { ConfigProps, SeriesConfig } from '../../types';
|
||||
import { FieldLabels, OPERATION_COLUMN, REPORT_METRIC_FIELD } from '../constants';
|
||||
import { buildExistsFilter } from '../utils';
|
||||
import { DOWN_LABEL, MONITORS_DURATION_LABEL, UP_LABEL } from '../constants/labels';
|
||||
import { MONITOR_DURATION_US } from '../constants/field_names/synthetics';
|
||||
import {
|
||||
CLS_LABEL,
|
||||
DCL_LABEL,
|
||||
DOCUMENT_ONLOAD_LABEL,
|
||||
DOWN_LABEL,
|
||||
FCP_LABEL,
|
||||
LCP_LABEL,
|
||||
MONITORS_DURATION_LABEL,
|
||||
UP_LABEL,
|
||||
} from '../constants/labels';
|
||||
import {
|
||||
MONITOR_DURATION_US,
|
||||
SYNTHETICS_CLS,
|
||||
SYNTHETICS_DCL,
|
||||
SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
SYNTHETICS_FCP,
|
||||
SYNTHETICS_LCP,
|
||||
} from '../constants/field_names/synthetics';
|
||||
const SUMMARY_UP = 'summary.up';
|
||||
const SUMMARY_DOWN = 'summary.down';
|
||||
|
||||
|
@ -29,8 +44,8 @@ export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): SeriesCon
|
|||
],
|
||||
hasOperationType: false,
|
||||
filterFields: ['observer.geo.name', 'monitor.type', 'tags'],
|
||||
breakdownFields: ['observer.geo.name', 'monitor.type'],
|
||||
baseFilters: [...buildExistsFilter('summary.up', indexPattern)],
|
||||
breakdownFields: ['observer.geo.name', 'monitor.type', 'monitor.name'],
|
||||
baseFilters: [],
|
||||
palette: { type: 'palette', name: 'status' },
|
||||
definitionFields: ['monitor.name', 'url.full'],
|
||||
metricOptions: [
|
||||
|
@ -52,6 +67,36 @@ export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): SeriesCon
|
|||
label: DOWN_LABEL,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
{
|
||||
label: LCP_LABEL,
|
||||
field: SYNTHETICS_LCP,
|
||||
id: SYNTHETICS_LCP,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
{
|
||||
label: FCP_LABEL,
|
||||
field: SYNTHETICS_FCP,
|
||||
id: SYNTHETICS_FCP,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
{
|
||||
label: DCL_LABEL,
|
||||
field: SYNTHETICS_DCL,
|
||||
id: SYNTHETICS_DCL,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
{
|
||||
label: DOCUMENT_ONLOAD_LABEL,
|
||||
field: SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
id: SYNTHETICS_DOCUMENT_ONLOAD,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
{
|
||||
label: CLS_LABEL,
|
||||
field: SYNTHETICS_CLS,
|
||||
id: SYNTHETICS_CLS,
|
||||
columnType: OPERATION_COLUMN,
|
||||
},
|
||||
],
|
||||
labels: { ...FieldLabels },
|
||||
};
|
||||
|
|
|
@ -14,14 +14,17 @@ import { getDefaultConfigs } from '../configurations/default_configs';
|
|||
|
||||
import { SeriesUrl, UrlFilter } from '../types';
|
||||
import { useAppIndexPatternContext } from './use_app_index_pattern';
|
||||
import { ALL_VALUES_SELECTED } from '../../field_value_suggestions/field_value_combobox';
|
||||
|
||||
export const getFiltersFromDefs = (reportDefinitions: SeriesUrl['reportDefinitions']) => {
|
||||
return Object.entries(reportDefinitions ?? {}).map(([field, value]) => {
|
||||
return {
|
||||
field,
|
||||
values: value,
|
||||
};
|
||||
}) as UrlFilter[];
|
||||
return Object.entries(reportDefinitions ?? {})
|
||||
.map(([field, value]) => {
|
||||
return {
|
||||
field,
|
||||
values: value,
|
||||
};
|
||||
})
|
||||
.filter(({ values }) => !values.includes(ALL_VALUES_SELECTED)) as UrlFilter[];
|
||||
};
|
||||
|
||||
export const useLensAttributes = (): TypedLensByValueInput['attributes'] | null => {
|
||||
|
|
|
@ -16,6 +16,7 @@ import { PersistableFilter } from '../../../../../../../lens/common';
|
|||
import { ExistsFilter } from '../../../../../../../../../src/plugins/data/common/es_query/filters';
|
||||
import { buildPhrasesFilter } from '../../configurations/utils';
|
||||
import { SeriesConfig } from '../../types';
|
||||
import { ALL_VALUES_SELECTED } from '../../../field_value_suggestions/field_value_combobox';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -51,8 +52,10 @@ export function ReportDefinitionField({ seriesId, field, seriesConfig, onChange
|
|||
definitionFields.forEach((fieldT) => {
|
||||
if (indexPattern && selectedReportDefinitions?.[fieldT] && fieldT !== field) {
|
||||
const values = selectedReportDefinitions?.[fieldT];
|
||||
const valueFilter = buildPhrasesFilter(fieldT, values, indexPattern)[0];
|
||||
filtersN.push(valueFilter.query);
|
||||
if (!values.includes(ALL_VALUES_SELECTED)) {
|
||||
const valueFilter = buildPhrasesFilter(fieldT, values, indexPattern)[0];
|
||||
filtersN.push(valueFilter.query);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -74,6 +77,7 @@ export function ReportDefinitionField({ seriesId, field, seriesConfig, onChange
|
|||
filters={queryFilters}
|
||||
time={series.time}
|
||||
fullWidth={true}
|
||||
allowAllValuesSelection={true}
|
||||
/>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -11,9 +11,11 @@ import { EuiComboBox, EuiFormControlLayout, EuiComboBoxOptionOption } from '@ela
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import styled from 'styled-components';
|
||||
import { FieldValueSelectionProps } from './types';
|
||||
|
||||
const formatOptions = (values?: string[]) => {
|
||||
const uniqueValues = Array.from(new Set(values));
|
||||
export const ALL_VALUES_SELECTED = 'ALL_VALUES';
|
||||
const formatOptions = (values?: string[], allowAllValuesSelection?: boolean) => {
|
||||
const uniqueValues = Array.from(
|
||||
new Set(allowAllValuesSelection ? ['ALL_VALUES', ...(values ?? [])] : values)
|
||||
);
|
||||
|
||||
return (uniqueValues ?? []).map((label) => ({
|
||||
label,
|
||||
|
@ -29,15 +31,24 @@ export function FieldValueCombobox({
|
|||
values,
|
||||
setQuery,
|
||||
compressed = true,
|
||||
allowAllValuesSelection,
|
||||
onChange: onSelectionChange,
|
||||
}: FieldValueSelectionProps) {
|
||||
const [options, setOptions] = useState<ValueOption[]>(
|
||||
formatOptions(union(values?.map(({ label: lb }) => lb) ?? [], selectedValue ?? []))
|
||||
const [options, setOptions] = useState<ValueOption[]>(() =>
|
||||
formatOptions(
|
||||
union(values?.map(({ label: lb }) => lb) ?? [], selectedValue ?? []),
|
||||
allowAllValuesSelection
|
||||
)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setOptions(formatOptions(union(values?.map(({ label: lb }) => lb) ?? [], selectedValue ?? [])));
|
||||
}, [selectedValue, values]);
|
||||
setOptions(
|
||||
formatOptions(
|
||||
union(values?.map(({ label: lb }) => lb) ?? [], selectedValue ?? []),
|
||||
allowAllValuesSelection
|
||||
)
|
||||
);
|
||||
}, [allowAllValuesSelection, selectedValue, values]);
|
||||
|
||||
const onChange = (selectedValuesN: ValueOption[]) => {
|
||||
onSelectionChange(selectedValuesN.map(({ label: lbl }) => lbl));
|
||||
|
|
|
@ -30,6 +30,7 @@ export function FieldValueSuggestions({
|
|||
singleSelection,
|
||||
compressed,
|
||||
asFilterButton,
|
||||
allowAllValuesSelection,
|
||||
asCombobox = true,
|
||||
onChange: onSelectionChange,
|
||||
}: FieldValueSuggestionsProps) {
|
||||
|
@ -73,6 +74,7 @@ export function FieldValueSuggestions({
|
|||
width={width}
|
||||
compressed={compressed}
|
||||
asFilterButton={asFilterButton}
|
||||
allowAllValuesSelection={allowAllValuesSelection}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ interface CommonProps {
|
|||
compressed?: boolean;
|
||||
asFilterButton?: boolean;
|
||||
showCount?: boolean;
|
||||
allowAllValuesSelection?: boolean;
|
||||
}
|
||||
|
||||
export type FieldValueSuggestionsProps = CommonProps & {
|
||||
|
|
Loading…
Reference in a new issue