Skip to content

Commit

Permalink
Onboard Latency Threshold rule type with FAAD (#179080)
Browse files Browse the repository at this point in the history
Towards: #169867

This PR onboards Latency Threshold rule type with FAAD.

### To verify

1. Run the following script to generate APM data:
```
node scripts/synthtrace simple_trace.ts --local --live
```

2. Create a latency threshold rule.
Example:
```
POST kbn:/api/alerting/rule
{
  "params": {
    "aggregationType": "avg",
    "environment": "ENVIRONMENT_ALL",
    "threshold": 400,
    "windowSize": 5,
    "windowUnit": "m"
  },
  "consumer": "alerts",
  "schedule": {
    "interval": "1m"
  },
  "tags": [],
  "name": "testinggg",
  "rule_type_id": "apm.transaction_duration",
  "notify_when": "onActionGroupChange",
  "actions": []
}
```
3. Your rule should create an alert and should saved it in
`.internal.alerts-observability.apm.alerts-default-000001`
Example:
```
GET .internal.alerts-*/_search
```
4. Set `threshold: 10000`

5. The alert should be recovered and the AAD in the above index should
be updated `kibana.alert.status: recovered`.
  • Loading branch information
doakalexi authored Mar 26, 2024
1 parent 8eb2fbd commit a936bf7
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export enum AggregationType {

export const THRESHOLD_MET_GROUP_ID = 'threshold_met';
export type ThresholdMetActionGroupId = typeof THRESHOLD_MET_GROUP_ID;
const THRESHOLD_MET_GROUP: ActionGroup<ThresholdMetActionGroupId> = {
export const THRESHOLD_MET_GROUP: ActionGroup<ThresholdMetActionGroupId> = {
id: THRESHOLD_MET_GROUP_ID,
name: i18n.translate('xpack.apm.a.thresholdMet', {
defaultMessage: 'Threshold met',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const ApmRuleTypeAlertDefinition: IRuleTypeAlerts = {
context: APM_RULE_TYPE_ALERT_CONTEXT,
mappings: { fieldMap: apmRuleTypeAlertFieldMap },
useLegacyAlerts: true,
shouldWrite: false,
};

export interface RegisterRuleDependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import { createRuleTypeMocks } from '../../test_utils';

describe('registerTransactionDurationRuleType', () => {
it('sends alert when value is greater than threshold', async () => {
const { services, dependencies, executor, scheduleActions } =
createRuleTypeMocks();
const { services, dependencies, executor } = createRuleTypeMocks();

registerTransactionDurationRuleType(dependencies);

Expand Down Expand Up @@ -44,6 +43,7 @@ describe('registerTransactionDurationRuleType', () => {
total: 1,
},
});
services.alertsClient.report.mockReturnValue({ uuid: 'test-uuid' });

const params = {
threshold: 3000,
Expand All @@ -55,28 +55,41 @@ describe('registerTransactionDurationRuleType', () => {
transactionName: 'GET /orders',
};
await executor({ params });
expect(scheduleActions).toHaveBeenCalledTimes(1);
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
transactionName: 'GET /orders',
environment: 'development',
interval: `5 mins`,
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
transactionType: 'request',
serviceName: 'opbeans-java',
threshold: 3000,
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
expect(services.alertsClient.setAlertData).toHaveBeenCalledTimes(1);
expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({
context: {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: '5 mins',
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
serviceName: 'opbeans-java',
threshold: 3000,
transactionName: 'GET /orders',
transactionType: 'request',
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
},
id: 'opbeans-java_development_request',
payload: {
'kibana.alert.evaluation.threshold': 3000000,
'kibana.alert.evaluation.value': 5500000,
'kibana.alert.reason':
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
'processor.event': 'transaction',
'service.environment': 'development',
'service.name': 'opbeans-java',
'transaction.name': 'GET /orders',
'transaction.type': 'request',
},
});
});

it('sends alert when rule is configured with group by on transaction.name', async () => {
const { services, dependencies, executor, scheduleActions } =
createRuleTypeMocks();
const { services, dependencies, executor } = createRuleTypeMocks();

registerTransactionDurationRuleType(dependencies);

Expand Down Expand Up @@ -109,6 +122,7 @@ describe('registerTransactionDurationRuleType', () => {
total: 1,
},
});
services.alertsClient.report.mockReturnValue({ uuid: 'test-uuid' });

const params = {
threshold: 3000,
Expand All @@ -125,28 +139,41 @@ describe('registerTransactionDurationRuleType', () => {
],
};
await executor({ params });
expect(scheduleActions).toHaveBeenCalledTimes(1);
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: `5 mins`,
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request, name: GET /products. Alert when > 3.0 s.',
transactionType: 'request',
serviceName: 'opbeans-java',
threshold: 3000,
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
transactionName: 'GET /products',
expect(services.alertsClient.setAlertData).toHaveBeenCalledTimes(1);
expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({
context: {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: '5 mins',
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request, name: GET /products. Alert when > 3.0 s.',
serviceName: 'opbeans-java',
threshold: 3000,
transactionName: 'GET /products',
transactionType: 'request',
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
},
id: 'opbeans-java_development_request_GET /products',
payload: {
'kibana.alert.evaluation.threshold': 3000000,
'kibana.alert.evaluation.value': 5500000,
'kibana.alert.reason':
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request, name: GET /products. Alert when > 3.0 s.',
'processor.event': 'transaction',
'service.environment': 'development',
'service.name': 'opbeans-java',
'transaction.name': 'GET /products',
'transaction.type': 'request',
},
});
});

it('sends alert when rule is configured with preselected group by', async () => {
const { services, dependencies, executor, scheduleActions } =
createRuleTypeMocks();
const { services, dependencies, executor } = createRuleTypeMocks();

registerTransactionDurationRuleType(dependencies);

Expand Down Expand Up @@ -179,6 +206,7 @@ describe('registerTransactionDurationRuleType', () => {
total: 1,
},
});
services.alertsClient.report.mockReturnValue({ uuid: 'test-uuid' });

const params = {
threshold: 3000,
Expand All @@ -191,27 +219,41 @@ describe('registerTransactionDurationRuleType', () => {
};

await executor({ params });
expect(scheduleActions).toHaveBeenCalledTimes(1);
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: `5 mins`,
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
transactionType: 'request',
serviceName: 'opbeans-java',
threshold: 3000,
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
expect(services.alertsClient.setAlertData).toHaveBeenCalledTimes(1);
expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({
context: {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: '5 mins',
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
serviceName: 'opbeans-java',
threshold: 3000,
transactionName: undefined,
transactionType: 'request',
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
},
id: 'opbeans-java_development_request',
payload: {
'kibana.alert.evaluation.threshold': 3000000,
'kibana.alert.evaluation.value': 5500000,
'kibana.alert.reason':
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
'processor.event': 'transaction',
'service.environment': 'development',
'service.name': 'opbeans-java',
'transaction.name': undefined,
'transaction.type': 'request',
},
});
});

it('sends alert when service.environment field does not exist in the source', async () => {
const { services, dependencies, executor, scheduleActions } =
createRuleTypeMocks();
const { services, dependencies, executor } = createRuleTypeMocks();

registerTransactionDurationRuleType(dependencies);

Expand Down Expand Up @@ -249,6 +291,7 @@ describe('registerTransactionDurationRuleType', () => {
total: 1,
},
});
services.alertsClient.report.mockReturnValue({ uuid: 'test-uuid' });

const params = {
threshold: 3000,
Expand All @@ -265,28 +308,41 @@ describe('registerTransactionDurationRuleType', () => {
],
};
await executor({ params });
expect(scheduleActions).toHaveBeenCalledTimes(1);
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'Not defined',
interval: `5 mins`,
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: Not defined, type: request, name: tx-java. Alert when > 3.0 s.',
transactionType: 'request',
serviceName: 'opbeans-java',
threshold: 3000,
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=ENVIRONMENT_ALL',
transactionName: 'tx-java',
expect(services.alertsClient.setAlertData).toHaveBeenCalledTimes(1);
expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({
context: {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'Not defined',
interval: '5 mins',
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: Not defined, type: request, name: tx-java. Alert when > 3.0 s.',
serviceName: 'opbeans-java',
threshold: 3000,
transactionName: 'tx-java',
transactionType: 'request',
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=ENVIRONMENT_ALL',
},
id: 'opbeans-java_ENVIRONMENT_NOT_DEFINED_request_tx-java',
payload: {
'kibana.alert.evaluation.threshold': 3000000,
'kibana.alert.evaluation.value': 5500000,
'kibana.alert.reason':
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: Not defined, type: request, name: tx-java. Alert when > 3.0 s.',
'processor.event': 'transaction',
'service.environment': 'ENVIRONMENT_NOT_DEFINED',
'service.name': 'opbeans-java',
'transaction.name': 'tx-java',
'transaction.type': 'request',
},
});
});

it('sends alert when rule is configured with a filter query', async () => {
const { services, dependencies, executor, scheduleActions } =
createRuleTypeMocks();
const { services, dependencies, executor } = createRuleTypeMocks();

registerTransactionDurationRuleType(dependencies);

Expand Down Expand Up @@ -319,6 +375,7 @@ describe('registerTransactionDurationRuleType', () => {
total: 1,
},
});
services.alertsClient.report.mockReturnValue({ uuid: 'test-uuid' });

const params = {
threshold: 3000,
Expand All @@ -337,21 +394,36 @@ describe('registerTransactionDurationRuleType', () => {
};

await executor({ params });
expect(scheduleActions).toHaveBeenCalledTimes(1);
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: `5 mins`,
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
transactionType: 'request',
serviceName: 'opbeans-java',
threshold: 3000,
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
expect(services.alertsClient.setAlertData).toHaveBeenCalledTimes(1);
expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({
context: {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
environment: 'development',
interval: '5 mins',
reason:
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
serviceName: 'opbeans-java',
threshold: 3000,
transactionName: undefined,
transactionType: 'request',
triggerValue: '5,500 ms',
viewInAppUrl:
'http://localhost:5601/eyr/app/apm/services/opbeans-java?transactionType=request&environment=development',
},
id: 'opbeans-java_development_request',
payload: {
'kibana.alert.evaluation.threshold': 3000000,
'kibana.alert.evaluation.value': 5500000,
'kibana.alert.reason':
'Avg. latency is 5.5 s in the last 5 mins for service: opbeans-java, env: development, type: request. Alert when > 3.0 s.',
'processor.event': 'transaction',
'service.environment': 'development',
'service.name': 'opbeans-java',
'transaction.name': undefined,
'transaction.type': 'request',
},
});
});
});
Loading

0 comments on commit a936bf7

Please sign in to comment.