Skip to content

Commit

Permalink
Merge branch 'main' into 172506-obsux-add-feedback-form-to-apm
Browse files Browse the repository at this point in the history
  • Loading branch information
jennypavlova authored Jan 5, 2024
2 parents b3355d2 + 702b207 commit 0b4d35e
Show file tree
Hide file tree
Showing 23 changed files with 816 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ export enum InfraFormatterType {
percent = 'percent',
}

// Custom threshold alert types

// Alert fields['kibana.alert.group] type
export type GroupBy = Array<{ field: string; value: string }>;

/*
* Utils
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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 { getIntervalInSeconds } from './get_interval_in_seconds';

describe('getIntervalInSeconds', () => {
const testData = [
{ interval: '5ms', result: 0.005 },
{ interval: '70s', result: 70 },
{ interval: '25m', result: 1500 },
{ interval: '10h', result: 36000 },
{ interval: '3d', result: 259200 },
{ interval: '1w', result: 604800 },
{ interval: '1y', result: 30758400 },
];

it.each(testData)('getIntervalInSeconds($interval) = $result', ({ interval, result }) => {
expect(getIntervalInSeconds(interval)).toBe(result);
});

it('Throws error if interval is not valid', () => {
expect(() => getIntervalInSeconds('invalid')).toThrow('Invalid interval string format.');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.
*/

const intervalUnits = ['y', 'M', 'w', 'd', 'h', 'm', 's', 'ms'];
const INTERVAL_STRING_RE = new RegExp('^([0-9\\.]*)\\s*(' + intervalUnits.join('|') + ')$');

interface UnitsToSeconds {
[unit: string]: number;
}

const units: UnitsToSeconds = {
ms: 0.001,
s: 1,
m: 60,
h: 3600,
d: 86400,
w: 86400 * 7,
M: 86400 * 30,
y: 86400 * 356,
};

export const getIntervalInSeconds = (interval: string): number => {
const matches = interval.match(INTERVAL_STRING_RE);
if (matches) {
return parseFloat(matches[1]) * units[matches[2]];
}
throw new Error('Invalid interval string format.');
};
1 change: 1 addition & 0 deletions x-pack/plugins/observability/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"dataViews",
"dataViewEditor",
"embeddable",
"fieldFormats",
"uiActions",
"presentationUtil",
"exploratoryView",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ export function ObservabilityAlertSearchBar({
(alertStatus: AlertStatus) => {
try {
onEsQueryChange(
buildEsQuery(
{
buildEsQuery({
timeRange: {
to: rangeTo,
from: rangeFrom,
},
kuery,
[...getAlertStatusQuery(alertStatus), ...defaultSearchQueries],
getEsQueryConfig(uiSettings)
)
queries: [...getAlertStatusQuery(alertStatus), ...defaultSearchQueries],
config: getEsQueryConfig(uiSettings),
})
);
} catch (error) {
toasts.addError(error, {
Expand Down Expand Up @@ -89,15 +89,15 @@ export function ObservabilityAlertSearchBar({
({ dateRange, query }) => {
try {
// First try to create es query to make sure query is valid, then save it in state
const esQuery = buildEsQuery(
{
const esQuery = buildEsQuery({
timeRange: {
to: dateRange.to,
from: dateRange.from,
},
query,
[...getAlertStatusQuery(status), ...defaultSearchQueries],
getEsQueryConfig(uiSettings)
);
kuery: query,
queries: [...getAlertStatusQuery(status), ...defaultSearchQueries],
config: getEsQueryConfig(uiSettings),
});
if (query) onKueryChange(query);
timeFilterService.setTime(dateRange);
onRangeFromChange(dateRange.from);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
buildCustomThresholdAlert,
buildCustomThresholdRule,
} from '../mocks/custom_threshold_rule';
} from '../../mocks/custom_threshold_rule';
import AlertDetailsAppSection from './alert_details_app_section';
import { ExpressionChart } from './expression_chart';
import { ExpressionChart } from '../expression_chart';

const mockedChartStartContract = chartPluginMock.createStartContract();

Expand All @@ -33,11 +33,11 @@ jest.mock('@kbn/observability-get-padded-alert-time-range-util', () => ({
}),
}));

jest.mock('./expression_chart', () => ({
jest.mock('../expression_chart', () => ({
ExpressionChart: jest.fn(() => <div data-test-subj="ExpressionChart" />),
}));

jest.mock('../../../utils/kibana_react', () => ({
jest.mock('../../../../utils/kibana_react', () => ({
useKibana: () => ({
services: {
...mockCoreMock.createStart(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ import { Rule, RuleTypeParams } from '@kbn/alerting-plugin/common';
import { AlertAnnotation, AlertActiveTimeRangeAnnotation } from '@kbn/observability-alert-details';
import { getPaddedAlertTimeRange } from '@kbn/observability-get-padded-alert-time-range-util';
import { DataView } from '@kbn/data-views-plugin/common';
import { MetricsExplorerChartType } from '../../../../common/custom_threshold_rule/types';
import { useKibana } from '../../../utils/kibana_react';
import { metricValueFormatter } from '../../../../common/custom_threshold_rule/metric_value_formatter';
import { AlertSummaryField, TopAlert } from '../../..';

import { ExpressionChart } from './expression_chart';
import { TIME_LABELS } from './criterion_preview_chart/criterion_preview_chart';
import { Threshold } from './custom_threshold';
import { AlertParams, CustomThresholdRuleTypeParams } from '../types';
import { MetricsExplorerChartType } from '../../../../../common/custom_threshold_rule/types';
import { useLicense } from '../../../../hooks/use_license';
import { useKibana } from '../../../../utils/kibana_react';
import { metricValueFormatter } from '../../../../../common/custom_threshold_rule/metric_value_formatter';
import { AlertSummaryField, TopAlert } from '../../../..';
import { AlertParams, CustomThresholdRuleTypeParams } from '../../types';
import { ExpressionChart } from '../expression_chart';
import { TIME_LABELS } from '../criterion_preview_chart/criterion_preview_chart';
import { Threshold } from '../custom_threshold';
import { LogRateAnalysis } from './log_rate_analysis';

// TODO Use a generic props for app sections https://github.com/elastic/kibana/issues/152690
export type CustomThresholdRule = Rule<CustomThresholdRuleTypeParams>;
Expand All @@ -57,8 +58,11 @@ export default function AlertDetailsAppSection({
ruleLink,
setAlertSummaryFields,
}: AppSectionProps) {
const { uiSettings, charts, data } = useKibana().services;
const services = useKibana().services;
const { uiSettings, charts, data } = services;
const { euiTheme } = useEuiTheme();
const { hasAtLeast } = useLicense();
const hasLogRateAnalysisLicense = hasAtLeast('platinum');
const [dataView, setDataView] = useState<DataView>();
const [, setDataViewError] = useState<Error>();
const ruleParams = rule.params as RuleTypeParams & AlertParams;
Expand All @@ -83,6 +87,7 @@ export default function AlertDetailsAppSection({
key={ALERT_TIME_RANGE_ANNOTATION_ID}
/>,
];

useEffect(() => {
setAlertSummaryFields([
{
Expand Down Expand Up @@ -181,6 +186,9 @@ export default function AlertDetailsAppSection({
</EuiPanel>
</EuiFlexItem>
))}
{hasLogRateAnalysisLicense && (
<LogRateAnalysis alert={alert} dataView={dataView} rule={rule} services={services} />
)}
</EuiFlexGroup>
) : null;

Expand Down
Loading

0 comments on commit 0b4d35e

Please sign in to comment.