mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[APM] Add transaction name filter in latency threshold rule (#154241)
Part of the #152329 1. Adds a synthrace scenario that generates many transactions per service 2. Fixes the duration chart preview when selecting All option - https://github.com/elastic/kibana/issues/152195 3. Introduces the `Transaction name` filter in the rule type. ### Pages loading the rule type 1. APM 2. Alert 3. Management rule ### Consider - [ ] Update/Adding documentation example https://www.elastic.co/guide/en/kibana/master/apm-alerts.html#apm-create-transaction-alert ## Creating a rule https://user-images.githubusercontent.com/3369346/231740745-425c8eb8-6798-4ce4-b375-4ef96afdb334.mov ## Updating a rule https://user-images.githubusercontent.com/3369346/231742035-28f50dfd-64bb-475d-b037-331eea4188d7.mov ### Before https://user-images.githubusercontent.com/3369346/232799038-2edaa199-b970-48f2-b3ca-728273e4bf44.mov ### Notes #### Feedback The default action messages don't include any links. I will create a follow-up ticket to improve the messages with actionable links. Related bugs but out of the scope of the PR - https://github.com/elastic/kibana/issues/154818 - https://github.com/elastic/kibana/issues/154704 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
79969fbf2c
commit
7c70508b7b
17 changed files with 283 additions and 33 deletions
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import { ApmFields, apm, Instance } from '@kbn/apm-synthtrace-client';
|
||||
import { Scenario } from '../cli/scenario';
|
||||
import { getSynthtraceEnvironment } from '../lib/utils/get_synthtrace_environment';
|
||||
|
||||
const ENVIRONMENT = getSynthtraceEnvironment(__filename);
|
||||
|
||||
const scenario: Scenario<ApmFields> = async (runOptions) => {
|
||||
const { logger } = runOptions;
|
||||
const { numServices = 3 } = runOptions.scenarioOpts || {};
|
||||
const numTransactions = 100;
|
||||
|
||||
return {
|
||||
generate: ({ range }) => {
|
||||
const urls = ['GET /order', 'POST /basket', 'DELETE /basket', 'GET /products'];
|
||||
|
||||
const successfulTimestamps = range.ratePerMinute(180);
|
||||
const failedTimestamps = range.interval('1m').rate(180);
|
||||
|
||||
const instances = [...Array(numServices).keys()].map((index) =>
|
||||
apm
|
||||
.service({ name: `synth-go-${index}`, environment: ENVIRONMENT, agentName: 'go' })
|
||||
.instance(`instance-${index}`)
|
||||
);
|
||||
|
||||
const transactionNames = [...Array(numTransactions).keys()].map(
|
||||
(index) => `${urls[index % urls.length]}/${index}`
|
||||
);
|
||||
|
||||
const instanceSpans = (instance: Instance, transactionName: string) => {
|
||||
const successfulTraceEvents = successfulTimestamps.generator((timestamp) =>
|
||||
instance.transaction({ transactionName }).timestamp(timestamp).duration(1000).success()
|
||||
);
|
||||
|
||||
const failedTraceEvents = failedTimestamps.generator((timestamp) =>
|
||||
instance
|
||||
.transaction({ transactionName })
|
||||
.timestamp(timestamp)
|
||||
.duration(1000)
|
||||
.failure()
|
||||
.errors(
|
||||
instance
|
||||
.error({ message: '[ResponseError] index_not_found_exception' })
|
||||
.timestamp(timestamp + 50)
|
||||
)
|
||||
);
|
||||
|
||||
const metricsets = range
|
||||
.interval('30s')
|
||||
.rate(1)
|
||||
.generator((timestamp) =>
|
||||
instance
|
||||
.appMetrics({
|
||||
'system.memory.actual.free': 800,
|
||||
'system.memory.total': 1000,
|
||||
'system.cpu.total.norm.pct': 0.6,
|
||||
'system.process.cpu.total.norm.pct': 0.7,
|
||||
})
|
||||
.timestamp(timestamp)
|
||||
);
|
||||
|
||||
return [successfulTraceEvents, failedTraceEvents, metricsets];
|
||||
};
|
||||
|
||||
return logger.perf('generating_apm_events', () =>
|
||||
instances
|
||||
.flatMap((instance) =>
|
||||
transactionNames.map((transactionName) => ({ instance, transactionName }))
|
||||
)
|
||||
.flatMap(({ instance, transactionName }, index) =>
|
||||
instanceSpans(instance, transactionName)
|
||||
)
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default scenario;
|
|
@ -25,7 +25,8 @@ export const transactionDurationMessage = i18n.translate(
|
|||
defaultMessage: `\\{\\{alertName\\}\\} alert is firing because of the following conditions:
|
||||
|
||||
- Service name: \\{\\{context.serviceName\\}\\}
|
||||
- Type: \\{\\{context.transactionType\\}\\}
|
||||
- Transaction type: \\{\\{context.transactionType\\}\\}
|
||||
- Transaction name: \\{\\{context.transactionName\\}\\}
|
||||
- Environment: \\{\\{context.environment\\}\\}
|
||||
- Latency threshold: \\{\\{context.threshold\\}\\}ms
|
||||
- Latency observed: \\{\\{context.triggerValue\\}\\} over the last \\{\\{context.interval\\}\\}`,
|
||||
|
|
|
@ -20,6 +20,7 @@ export const errorCountParamsSchema = schema.object({
|
|||
export const transactionDurationParamsSchema = schema.object({
|
||||
serviceName: schema.maybe(schema.string()),
|
||||
transactionType: schema.maybe(schema.string()),
|
||||
transactionName: schema.maybe(schema.string()),
|
||||
windowSize: schema.number(),
|
||||
windowUnit: schema.string(),
|
||||
threshold: schema.number(),
|
||||
|
|
|
@ -11,11 +11,18 @@ import { CoreStart } from '@kbn/core/public';
|
|||
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
|
||||
import { RuleParams, TransactionDurationRuleType } from '.';
|
||||
import { AggregationType } from '../../../../../common/rules/apm_rule_types';
|
||||
import { AlertMetadata } from '../../utils/helper';
|
||||
import { ENVIRONMENT_ALL } from '../../../../../common/environment_filter_values';
|
||||
|
||||
const KibanaReactContext = createKibanaReactContext({
|
||||
notifications: { toasts: { add: () => {} } },
|
||||
} as unknown as Partial<CoreStart>);
|
||||
|
||||
interface Args {
|
||||
ruleParams: RuleParams;
|
||||
metadata?: AlertMetadata;
|
||||
}
|
||||
|
||||
export default {
|
||||
title: 'alerting/TransactionDurationRuleType',
|
||||
component: TransactionDurationRuleType,
|
||||
|
@ -32,16 +39,11 @@ export default {
|
|||
],
|
||||
};
|
||||
|
||||
export const Example: Story = () => {
|
||||
const [params, setParams] = useState<RuleParams>({
|
||||
aggregationType: AggregationType.Avg,
|
||||
environment: 'testEnvironment',
|
||||
serviceName: 'testServiceName',
|
||||
threshold: 1500,
|
||||
transactionType: 'testTransactionType',
|
||||
windowSize: 5,
|
||||
windowUnit: 'm',
|
||||
});
|
||||
export const CreatingInApmServiceOverview: Story<Args> = ({
|
||||
ruleParams,
|
||||
metadata,
|
||||
}) => {
|
||||
const [params, setParams] = useState<RuleParams>(ruleParams);
|
||||
|
||||
function setRuleParams(property: string, value: any) {
|
||||
setParams({ ...params, [property]: value });
|
||||
|
@ -50,8 +52,57 @@ export const Example: Story = () => {
|
|||
return (
|
||||
<TransactionDurationRuleType
|
||||
ruleParams={params}
|
||||
metadata={metadata}
|
||||
setRuleParams={setRuleParams}
|
||||
setRuleProperty={() => {}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
CreatingInApmServiceOverview.args = {
|
||||
ruleParams: {
|
||||
aggregationType: AggregationType.Avg,
|
||||
environment: 'testEnvironment',
|
||||
serviceName: 'testServiceName',
|
||||
threshold: 1500,
|
||||
transactionType: 'testTransactionType',
|
||||
transactionName: 'GET /api/customer/:id',
|
||||
windowSize: 5,
|
||||
windowUnit: 'm',
|
||||
},
|
||||
metadata: {
|
||||
environment: ENVIRONMENT_ALL.value,
|
||||
serviceName: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
export const CreatingInStackManagement: Story<Args> = ({
|
||||
ruleParams,
|
||||
metadata,
|
||||
}) => {
|
||||
const [params, setParams] = useState<RuleParams>(ruleParams);
|
||||
|
||||
function setRuleParams(property: string, value: any) {
|
||||
setParams({ ...params, [property]: value });
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionDurationRuleType
|
||||
ruleParams={params}
|
||||
metadata={metadata}
|
||||
setRuleParams={setRuleParams}
|
||||
setRuleProperty={() => {}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
CreatingInStackManagement.args = {
|
||||
ruleParams: {
|
||||
aggregationType: AggregationType.Avg,
|
||||
environment: 'testEnvironment',
|
||||
threshold: 1500,
|
||||
windowSize: 5,
|
||||
windowUnit: 'm',
|
||||
},
|
||||
metadata: undefined,
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
IsAboveField,
|
||||
ServiceField,
|
||||
TransactionTypeField,
|
||||
TransactionNameField,
|
||||
} from '../../utils/fields';
|
||||
import { AlertMetadata, getIntervalAndTimeRange } from '../../utils/helper';
|
||||
import { ApmRuleParamsContainer } from '../../ui_components/apm_rule_params_container';
|
||||
|
@ -38,9 +39,10 @@ import { PopoverExpression } from '../../ui_components/popover_expression';
|
|||
export interface RuleParams {
|
||||
aggregationType: AggregationType;
|
||||
environment: string;
|
||||
serviceName: string;
|
||||
threshold: number;
|
||||
transactionType: string;
|
||||
transactionType?: string;
|
||||
transactionName?: string;
|
||||
serviceName?: string;
|
||||
windowSize: number;
|
||||
windowUnit: string;
|
||||
}
|
||||
|
@ -105,6 +107,7 @@ export function TransactionDurationRuleType(props: Props) {
|
|||
environment: params.environment,
|
||||
serviceName: params.serviceName,
|
||||
transactionType: params.transactionType,
|
||||
transactionName: params.transactionName,
|
||||
interval,
|
||||
start,
|
||||
end,
|
||||
|
@ -119,6 +122,7 @@ export function TransactionDurationRuleType(props: Props) {
|
|||
params.environment,
|
||||
params.serviceName,
|
||||
params.transactionType,
|
||||
params.transactionName,
|
||||
params.windowSize,
|
||||
params.windowUnit,
|
||||
]
|
||||
|
@ -149,7 +153,8 @@ export function TransactionDurationRuleType(props: Props) {
|
|||
onChange={(value) => {
|
||||
if (value !== params.serviceName) {
|
||||
setRuleParams('serviceName', value);
|
||||
setRuleParams('transactionType', '');
|
||||
setRuleParams('transactionType', undefined);
|
||||
setRuleParams('transactionName', undefined);
|
||||
setRuleParams('environment', ENVIRONMENT_ALL.value);
|
||||
}
|
||||
}}
|
||||
|
@ -164,6 +169,11 @@ export function TransactionDurationRuleType(props: Props) {
|
|||
onChange={(value) => setRuleParams('environment', value)}
|
||||
serviceName={params.serviceName}
|
||||
/>,
|
||||
<TransactionNameField
|
||||
currentValue={params.transactionName}
|
||||
onChange={(value) => setRuleParams('transactionName', value)}
|
||||
serviceName={params.serviceName}
|
||||
/>,
|
||||
<PopoverExpression
|
||||
value={params.aggregationType}
|
||||
title={i18n.translate('xpack.apm.transactionDurationRuleType.when', {
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
SERVICE_ENVIRONMENT,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
TRANSACTION_NAME,
|
||||
} from '../../../../common/es_fields/apm';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
|
@ -39,7 +40,7 @@ export function ServiceField({
|
|||
>
|
||||
<SuggestionsSelect
|
||||
customOptions={
|
||||
allowAll ? [{ label: allOptionText, value: '' }] : undefined
|
||||
allowAll ? [{ label: allOptionText, value: undefined }] : undefined
|
||||
}
|
||||
customOptionText={i18n.translate(
|
||||
'xpack.apm.serviceNamesSelectCustomOptionText',
|
||||
|
@ -98,6 +99,46 @@ export function EnvironmentField({
|
|||
);
|
||||
}
|
||||
|
||||
export function TransactionNameField({
|
||||
currentValue,
|
||||
onChange,
|
||||
serviceName,
|
||||
}: {
|
||||
currentValue?: string;
|
||||
onChange: (value?: string) => void;
|
||||
serviceName?: string;
|
||||
}) {
|
||||
const label = i18n.translate('xpack.apm.alerting.fields.transaction.name', {
|
||||
defaultMessage: 'Name',
|
||||
});
|
||||
|
||||
return (
|
||||
<PopoverExpression value={currentValue || allOptionText} title={label}>
|
||||
<SuggestionsSelect
|
||||
customOptions={[{ label: allOptionText, value: undefined }]}
|
||||
customOptionText={i18n.translate(
|
||||
'xpack.apm.alerting.transaction.name.custom.text',
|
||||
{
|
||||
defaultMessage: 'Add \\{searchValue\\} as a new transaction name',
|
||||
}
|
||||
)}
|
||||
defaultValue={currentValue}
|
||||
fieldName={TRANSACTION_NAME}
|
||||
onChange={onChange}
|
||||
placeholder={i18n.translate(
|
||||
'xpack.apm.transactionNamesSelectPlaceholder',
|
||||
{
|
||||
defaultMessage: 'Select transaction name',
|
||||
}
|
||||
)}
|
||||
start={moment().subtract(24, 'h').toISOString()}
|
||||
end={moment().toISOString()}
|
||||
serviceName={serviceName}
|
||||
/>
|
||||
</PopoverExpression>
|
||||
);
|
||||
}
|
||||
|
||||
export function TransactionTypeField({
|
||||
currentValue,
|
||||
onChange,
|
||||
|
@ -113,7 +154,7 @@ export function TransactionTypeField({
|
|||
return (
|
||||
<PopoverExpression value={currentValue || allOptionText} title={label}>
|
||||
<SuggestionsSelect
|
||||
customOptions={[{ label: allOptionText, value: '' }]}
|
||||
customOptions={[{ label: allOptionText, value: undefined }]}
|
||||
customOptionText={i18n.translate(
|
||||
'xpack.apm.transactionTypesSelectCustomOptionText',
|
||||
{
|
||||
|
|
|
@ -66,6 +66,13 @@ export const apmActionVariables = {
|
|||
),
|
||||
name: 'transactionType' as const,
|
||||
},
|
||||
transactionName: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.transactionName',
|
||||
{ defaultMessage: 'The transaction name the alert is created for' }
|
||||
),
|
||||
name: 'transactionName' as const,
|
||||
},
|
||||
triggerValue: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.triggerValue',
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
SERVICE_ENVIRONMENT,
|
||||
SERVICE_LANGUAGE_NAME,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
} from '../../../common/es_fields/apm';
|
||||
import { registerTransactionDurationRuleType } from './rule_types/transaction_duration/register_transaction_duration_rule_type';
|
||||
|
@ -45,6 +46,10 @@ export const apmRuleTypeAlertFieldMap = {
|
|||
type: 'keyword',
|
||||
required: false,
|
||||
},
|
||||
[TRANSACTION_NAME]: {
|
||||
type: 'keyword',
|
||||
required: false,
|
||||
},
|
||||
[PROCESSOR_EVENT]: {
|
||||
type: 'keyword',
|
||||
required: false,
|
||||
|
|
|
@ -29,6 +29,7 @@ const alertParamsRt = t.intersection([
|
|||
]),
|
||||
serviceName: t.string,
|
||||
transactionType: t.string,
|
||||
transactionName: t.string,
|
||||
}),
|
||||
environmentRt,
|
||||
rangeRt,
|
||||
|
|
|
@ -111,9 +111,7 @@ export function registerErrorCountRuleType({
|
|||
},
|
||||
},
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.error } },
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName, {
|
||||
queryEmptyString: false,
|
||||
}),
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName),
|
||||
...environmentQuery(ruleParams.environment),
|
||||
],
|
||||
},
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
SERVICE_NAME,
|
||||
SERVICE_ENVIRONMENT,
|
||||
TRANSACTION_TYPE,
|
||||
TRANSACTION_NAME,
|
||||
} from '../../../../../common/es_fields/apm';
|
||||
import { environmentQuery } from '../../../../../common/utils/environment_query';
|
||||
import { AlertParams } from '../../route';
|
||||
|
@ -48,6 +49,7 @@ export async function getTransactionDurationChartPreview({
|
|||
environment,
|
||||
serviceName,
|
||||
transactionType,
|
||||
transactionName,
|
||||
interval,
|
||||
start,
|
||||
end,
|
||||
|
@ -63,6 +65,7 @@ export async function getTransactionDurationChartPreview({
|
|||
filter: [
|
||||
...termQuery(SERVICE_NAME, serviceName),
|
||||
...termQuery(TRANSACTION_TYPE, transactionType),
|
||||
...termQuery(TRANSACTION_NAME, transactionName),
|
||||
...rangeQuery(start, end),
|
||||
...environmentQuery(environment),
|
||||
...getDocumentTypeFilterForTransactions(searchAggregatedTransactions),
|
||||
|
|
|
@ -52,6 +52,7 @@ describe('registerTransactionDurationRuleType', () => {
|
|||
transactionType: 'request',
|
||||
serviceName: 'opbeans-java',
|
||||
aggregationType: 'avg',
|
||||
transactionName: 'GET /orders',
|
||||
};
|
||||
await executor({ params });
|
||||
expect(scheduleActions).toHaveBeenCalledTimes(1);
|
||||
|
@ -59,6 +60,7 @@ describe('registerTransactionDurationRuleType', () => {
|
|||
alertDetailsUrl: expect.stringContaining(
|
||||
'http://localhost:5601/eyr/app/observability/alerts/'
|
||||
),
|
||||
transactionName: 'GET /orders',
|
||||
environment: 'Not defined',
|
||||
interval: `5 mins`,
|
||||
reason:
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
PROCESSOR_EVENT,
|
||||
SERVICE_ENVIRONMENT,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
} from '../../../../../common/es_fields/apm';
|
||||
import {
|
||||
|
@ -94,6 +95,7 @@ export function registerTransactionDurationRuleType({
|
|||
apmActionVariables.reason,
|
||||
apmActionVariables.serviceName,
|
||||
apmActionVariables.transactionType,
|
||||
apmActionVariables.transactionName,
|
||||
apmActionVariables.threshold,
|
||||
apmActionVariables.triggerValue,
|
||||
apmActionVariables.viewInAppUrl,
|
||||
|
@ -146,12 +148,9 @@ export function registerTransactionDurationRuleType({
|
|||
...getDocumentTypeFilterForTransactions(
|
||||
searchAggregatedTransactions
|
||||
),
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName, {
|
||||
queryEmptyString: false,
|
||||
}),
|
||||
...termQuery(TRANSACTION_TYPE, ruleParams.transactionType, {
|
||||
queryEmptyString: false,
|
||||
}),
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName),
|
||||
...termQuery(TRANSACTION_TYPE, ruleParams.transactionType),
|
||||
...termQuery(TRANSACTION_NAME, ruleParams.transactionName),
|
||||
...environmentQuery(ruleParams.environment),
|
||||
] as QueryDslQueryContainer[],
|
||||
},
|
||||
|
@ -268,6 +267,7 @@ export function registerTransactionDurationRuleType({
|
|||
[SERVICE_NAME]: serviceName,
|
||||
...getEnvironmentEsField(environment),
|
||||
[TRANSACTION_TYPE]: transactionType,
|
||||
[TRANSACTION_NAME]: ruleParams.transactionName,
|
||||
[PROCESSOR_EVENT]: ProcessorEvent.transaction,
|
||||
[ALERT_EVALUATION_VALUE]: transactionDuration,
|
||||
[ALERT_EVALUATION_THRESHOLD]: ruleParams.threshold,
|
||||
|
@ -284,6 +284,7 @@ export function registerTransactionDurationRuleType({
|
|||
),
|
||||
reason,
|
||||
serviceName,
|
||||
transactionName: ruleParams.transactionName, // #Note once we group by transactionName, use the transactionName key from the bucket
|
||||
threshold: ruleParams.threshold,
|
||||
transactionType,
|
||||
triggerValue: transactionDurationFormatted,
|
||||
|
|
|
@ -142,12 +142,8 @@ export function registerTransactionErrorRateRuleType({
|
|||
],
|
||||
},
|
||||
},
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName, {
|
||||
queryEmptyString: false,
|
||||
}),
|
||||
...termQuery(TRANSACTION_TYPE, ruleParams.transactionType, {
|
||||
queryEmptyString: false,
|
||||
}),
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName),
|
||||
...termQuery(TRANSACTION_TYPE, ruleParams.transactionType),
|
||||
...environmentQuery(ruleParams.environment),
|
||||
],
|
||||
},
|
||||
|
|
|
@ -115,5 +115,54 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
)
|
||||
).to.equal(true);
|
||||
});
|
||||
|
||||
it('transaction_duration with transaction name', async () => {
|
||||
const options = {
|
||||
params: {
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
serviceName: 'opbeans-java',
|
||||
transactionName: 'DispatcherServlet#doGet',
|
||||
transactionType: 'request',
|
||||
environment: 'ENVIRONMENT_ALL',
|
||||
interval: '5m',
|
||||
},
|
||||
},
|
||||
};
|
||||
const response = await apmApiClient.readUser({
|
||||
...options,
|
||||
endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview',
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.latencyChartPreview[0].data[0]).to.eql({
|
||||
x: 1627974600000,
|
||||
y: 18485.85714285714,
|
||||
});
|
||||
});
|
||||
|
||||
it('transaction_duration with nonexistent transaction name', async () => {
|
||||
const options = {
|
||||
params: {
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
serviceName: 'opbeans-java',
|
||||
transactionType: 'request',
|
||||
transactionName: 'foo',
|
||||
environment: 'ENVIRONMENT_ALL',
|
||||
interval: '5m',
|
||||
},
|
||||
},
|
||||
};
|
||||
const response = await apmApiClient.readUser({
|
||||
...options,
|
||||
endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview',
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.latencyChartPreview).to.eql([]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
name: 'Latency threshold | synth-go',
|
||||
params: {
|
||||
serviceName: 'synth-go',
|
||||
transactionType: '',
|
||||
transactionType: undefined,
|
||||
windowSize: 99,
|
||||
windowUnit: 'y',
|
||||
threshold: 100,
|
||||
|
|
|
@ -48,7 +48,7 @@ export default function ServiceAlerts({ getService }: FtrProviderContext) {
|
|||
name: `Latency threshold | ${goService}`,
|
||||
params: {
|
||||
serviceName: goService,
|
||||
transactionType: '',
|
||||
transactionType: undefined,
|
||||
windowSize: 99,
|
||||
windowUnit: 'y',
|
||||
threshold: 100,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue