Skip to content

Commit

Permalink
[SIEM][Detection Engine] Adds an error aggregator by error reason and…
Browse files Browse the repository at this point in the history
… a way to filter them (#63707)

## Summary

Changes the error handling for when responses are returning with errors from the backend. We were aggregating on error status codes, but this will aggregate on the error reason per rule run and report those instead.

* Adds a utility function
* Adds unit tests for the utility function
* Adds TypeScript Types for the utility function
* Adds sample helpers for the mocks for testing 

### Checklist

- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
  • Loading branch information
FrankHassanabad authored Apr 16, 2020
1 parent 2bd7a89 commit d88f9a3
Show file tree
Hide file tree
Showing 5 changed files with 353 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { SignalSourceHit, SignalSearchResponse } from '../types';
import { SignalSourceHit, SignalSearchResponse, BulkResponse, BulkItem } from '../types';
import {
Logger,
SavedObject,
Expand Down Expand Up @@ -416,3 +416,68 @@ export const exampleFindRuleStatusResponse: (
});

export const mockLogger: Logger = loggingServiceMock.createLogger();

export const sampleBulkErrorItem = (
{
status,
reason,
}: {
status: number;
reason: string;
} = { status: 400, reason: 'Invalid call' }
): BulkItem => {
return {
create: {
_index: 'mock_index',
_id: '123',
_version: 1,
status,
_shards: {
total: 1,
successful: 0,
failed: 1,
},
error: {
type: 'Invalid',
reason,
shard: 'shard 123',
index: 'mock_index',
},
},
};
};

export const sampleBulkItem = (): BulkItem => {
return {
create: {
_index: 'mock_index',
_id: '123',
_version: 1,
status: 200,
result: 'some result here',
_shards: {
total: 1,
successful: 1,
failed: 0,
},
},
};
};

export const sampleEmptyBulkResponse = (): BulkResponse => ({
took: 0,
errors: false,
items: [],
});

export const sampleBulkError = (): BulkResponse => ({
took: 0,
errors: true,
items: [sampleBulkErrorItem()],
});

export const sampleBulkResponse = (): BulkResponse => ({
took: 0,
errors: true,
items: [sampleBulkItem()],
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { AlertServices } from '../../../../../../../plugins/alerting/server';
import { SignalSearchResponse, BulkResponse } from './types';
import { RuleAlertAction } from '../../../../common/detection_engine/types';
import { RuleTypeParams, RefreshTypes } from '../types';
import { generateId, makeFloatString } from './utils';
import { generateId, makeFloatString, errorAggregator } from './utils';
import { buildBulkBody } from './build_bulk_body';
import { Logger } from '../../../../../../../../src/core/server';

Expand Down Expand Up @@ -134,17 +134,10 @@ export const singleBulkCreate = async ({
logger.debug(`took property says bulk took: ${response.took} milliseconds`);

if (response.errors) {
const itemsWithErrors = response.items.filter(item => item.create.error);
const errorCountsByStatus = countBy(itemsWithErrors, item => item.create.status);
delete errorCountsByStatus['409']; // Duplicate signals are expected

if (!isEmpty(errorCountsByStatus)) {
const errorCountByMessage = errorAggregator(response, [409]);
if (!isEmpty(errorCountByMessage)) {
logger.error(
`[-] bulkResponse had errors with response statuses:counts of...\n${JSON.stringify(
errorCountsByStatus,
null,
2
)}`
`[-] bulkResponse had errors with responses of: ${JSON.stringify(errorCountByMessage)}`
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,35 +59,35 @@ export interface SignalSource {
};
}

export interface BulkItem {
create: {
_index: string;
_type?: string;
_id: string;
_version: number;
result?: string;
_shards?: {
total: number;
successful: number;
failed: number;
};
_seq_no?: number;
_primary_term?: number;
status: number;
error?: {
type: string;
reason: string;
index_uuid?: string;
shard: string;
index: string;
};
};
}

export interface BulkResponse {
took: number;
errors: boolean;
items: [
{
create: {
_index: string;
_type?: string;
_id: string;
_version: number;
result?: string;
_shards?: {
total: number;
successful: number;
failed: number;
};
_seq_no?: number;
_primary_term?: number;
status: number;
error?: {
type: string;
reason: string;
index_uuid?: string;
shard: string;
index: string;
};
};
}
];
items: BulkItem[];
}

export interface MGetResponse {
Expand Down Expand Up @@ -169,3 +169,5 @@ export interface RuleAlertAttributes extends AlertAttributes {
ruleId: string;
};
}

export type BulkResponseErrorAggregation = Record<string, { count: number; statusCode: number }>;
Loading

0 comments on commit d88f9a3

Please sign in to comment.