return error message when usage collector failed (#136507)

* return error message when usage collector is failed
This commit is contained in:
Ersin Erdal 2022-08-10 17:57:51 +02:00 committed by GitHub
parent 3aa0599305
commit e59c7958de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 264 additions and 58 deletions

View file

@ -112,6 +112,7 @@ Object {
"some.type": 1,
},
"countTotal": 4,
"hasErrors": false,
}
`);
});
@ -130,6 +131,8 @@ Object {
Object {
"countByType": Object {},
"countTotal": 0,
"errorMessage": "oh no",
"hasErrors": true,
}
`);
});
@ -194,6 +197,7 @@ Object {
"countEmailByService": Object {},
"countNamespaces": 1,
"countTotal": 2,
"hasErrors": false,
}
`);
});
@ -295,6 +299,7 @@ Object {
"countEmailByService": Object {},
"countNamespaces": 1,
"countTotal": 4,
"hasErrors": false,
}
`);
});
@ -316,6 +321,8 @@ Object {
"countEmailByService": Object {},
"countNamespaces": 0,
"countTotal": 0,
"errorMessage": "oh no",
"hasErrors": true,
}
`);
});
@ -438,6 +445,7 @@ Object {
"some.type": 1,
},
"countTotal": 6,
"hasErrors": false,
}
`);
});
@ -546,6 +554,7 @@ Object {
},
"countNamespaces": 1,
"countTotal": 6,
"hasErrors": false,
}
`);
});
@ -645,6 +654,7 @@ Object {
},
"countNamespaces": 3,
"countTotal": 6,
"hasErrors": false,
}
`);
});
@ -744,6 +754,7 @@ Object {
__slack: 7,
},
countTotal: 120,
hasErrors: false,
});
});
@ -765,6 +776,8 @@ Object {
"countFailed": 0,
"countFailedByType": Object {},
"countTotal": 0,
"errorMessage": "oh no",
"hasErrors": true,
}
`);
});

View file

@ -43,7 +43,6 @@ export async function getTotalCount(
`,
},
};
try {
const searchResult = await esClient.search({
index: kibanaIndex,
@ -78,6 +77,7 @@ export async function getTotalCount(
}
}
return {
hasErrors: false,
countTotal:
Object.keys(aggs).reduce(
(total: number, key: string) => parseInt(aggs[key], 10) + total,
@ -86,8 +86,13 @@ export async function getTotalCount(
countByType,
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(`Error executing actions telemetry task: getTotalCount - ${JSON.stringify(err)}`);
return {
hasErrors: true,
errorMessage,
countTotal: 0,
countByType: {},
};
@ -101,6 +106,8 @@ export async function getInUseTotalCount(
referenceType?: string,
preconfiguredActions?: PreConfiguredAction[]
): Promise<{
hasErrors: boolean;
errorMessage?: string;
countTotal: number;
countByType: Record<string, number>;
countByAlertHistoryConnectorType: number;
@ -363,6 +370,7 @@ export async function getInUseTotalCount(
}
return {
hasErrors: false,
countTotal: aggs.total + (preconfiguredActionsAggs?.total ?? 0),
countByType: countByActionTypeId,
countByAlertHistoryConnectorType: preconfiguredAlertHistoryConnectors,
@ -370,10 +378,14 @@ export async function getInUseTotalCount(
countNamespaces: namespacesList.size,
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing actions telemetry task: getInUseTotalCount - ${JSON.stringify(err)}`
);
return {
hasErrors: true,
errorMessage,
countTotal: 0,
countByType: {},
countByAlertHistoryConnectorType: 0,
@ -383,21 +395,6 @@ export async function getInUseTotalCount(
}
}
export async function getInUseByAlertingTotalCounts(
esClient: ElasticsearchClient,
kibanaIndex: string,
logger: Logger,
preconfiguredActions?: PreConfiguredAction[]
): Promise<{
countTotal: number;
countByType: Record<string, number>;
countByAlertHistoryConnectorType: number;
countEmailByService: Record<string, number>;
countNamespaces: number;
}> {
return await getInUseTotalCount(esClient, kibanaIndex, logger, 'alert', preconfiguredActions);
}
function replaceFirstAndLastDotSymbols(strToReplace: string) {
const hasFirstSymbolDot = strToReplace.startsWith('.');
const appliedString = hasFirstSymbolDot ? strToReplace.replace('.', '__') : strToReplace;
@ -410,6 +407,8 @@ export async function getExecutionsPerDayCount(
eventLogIndex: string,
logger: Logger
): Promise<{
hasErrors: boolean;
errorMessage?: string;
countTotal: number;
countByType: Record<string, number>;
countFailed: number;
@ -566,6 +565,7 @@ export async function getExecutionsPerDayCount(
);
return {
hasErrors: false,
countTotal: aggsExecutions.total,
countByType: Object.entries(aggsExecutions.connectorTypes).reduce(
(res: Record<string, number>, [key, value]) => {
@ -588,10 +588,13 @@ export async function getExecutionsPerDayCount(
avgExecutionTimeByType,
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing actions telemetry task: getExecutionsPerDayCount - ${JSON.stringify(err)}`
);
return {
hasErrors: true,
errorMessage,
countTotal: 0,
countByType: {},
countFailed: 0,

View file

@ -6,9 +6,11 @@
*/
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { registerActionsUsageCollector } from './actions_usage_collector';
import { configSchema, ActionsConfig } from '../config';
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
import { ConcreteTaskInstance, TaskManagerStartContract } from '@kbn/task-manager-plugin/server';
const mockTaskManagerStart = taskManagerMock.createStart();
@ -43,4 +45,50 @@ describe('registerActionsUsageCollector', () => {
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('actions');
});
it('should return an error message if fetching data fails', async () => {
mockTaskManagerStart.get.mockRejectedValueOnce(new Error('error message'));
const taskManagerPromise = new Promise<TaskManagerStartContract>((resolve) => {
resolve(mockTaskManagerStart);
});
registerActionsUsageCollector(
usageCollectionMock as UsageCollectionSetup,
config,
taskManagerPromise
);
// @ts-ignore
expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual(
expect.objectContaining({
has_errors: true,
error_messages: ['error message'],
})
);
});
it('should return the task state including error messages', async () => {
const mockStats = {
has_errors: true,
error_messages: ['an error message'],
count_active_total: 1,
count_disabled_total: 10,
};
mockTaskManagerStart.get.mockResolvedValue({
id: '1',
state: mockStats,
} as unknown as ConcreteTaskInstance);
const taskManagerPromise = new Promise<TaskManagerStartContract>((resolve) => {
resolve(mockTaskManagerStart);
});
registerActionsUsageCollector(
usageCollectionMock as UsageCollectionSetup,
config,
taskManagerPromise
);
// @ts-ignore
expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual({
alert_history_connector_enabled: false,
...mockStats,
});
});
});

View file

@ -23,6 +23,8 @@ export function createActionsUsageCollector(
return true;
},
schema: {
has_errors: { type: 'boolean' },
error_messages: { type: 'array', items: { type: 'text' } },
alert_history_connector_enabled: {
type: 'boolean',
_meta: { description: 'Indicates if preconfigured alert history connector is enabled.' },
@ -51,13 +53,16 @@ export function createActionsUsageCollector(
const doc = await getLatestTaskState(await taskManager);
// get the accumulated state from the recurring task
const { runs, ...state } = get(doc, 'state') as ActionsUsage & { runs: number };
return {
...state,
alert_history_connector_enabled: config.preconfiguredAlertHistoryEsIndex,
};
} catch (err) {
const errMessage = err && err.message ? err.message : err.toString();
return {
has_errors: true,
error_messages: [errMessage],
alert_history_connector_enabled: false,
count_total: 0,
count_by_type: {},

View file

@ -101,36 +101,39 @@ export function telemetryTaskRunner(
getTotalCount(esClient, kibanaIndex, logger, preconfiguredActions),
getInUseTotalCount(esClient, kibanaIndex, logger, undefined, preconfiguredActions),
getExecutionsPerDayCount(esClient, eventLogIndex, logger),
])
.then(([totalAggegations, totalInUse, totalExecutionsPerDay]) => {
return {
state: {
runs: (state.runs || 0) + 1,
count_total: totalAggegations.countTotal,
count_by_type: totalAggegations.countByType,
count_active_total: totalInUse.countTotal,
count_active_by_type: totalInUse.countByType,
count_active_alert_history_connectors: totalInUse.countByAlertHistoryConnectorType,
count_active_email_connectors_by_service_type: totalInUse.countEmailByService,
count_actions_namespaces: totalInUse.countNamespaces,
count_actions_executions_per_day: totalExecutionsPerDay.countTotal,
count_actions_executions_by_type_per_day: totalExecutionsPerDay.countByType,
count_actions_executions_failed_per_day: totalExecutionsPerDay.countFailed,
count_actions_executions_failed_by_type_per_day:
totalExecutionsPerDay.countFailedByType,
avg_execution_time_per_day: totalExecutionsPerDay.avgExecutionTime,
avg_execution_time_by_type_per_day: totalExecutionsPerDay.avgExecutionTimeByType,
},
runAt: getNextMidnight(),
};
})
.catch((errMsg) => {
logger.warn(`Error executing actions telemetry task: ${errMsg}`);
return {
state: {},
runAt: getNextMidnight(),
};
});
]).then(([totalAggegations, totalInUse, totalExecutionsPerDay]) => {
const hasErrors =
totalAggegations.hasErrors || totalInUse.hasErrors || totalExecutionsPerDay.hasErrors;
const errorMessages = [
totalAggegations.errorMessage,
totalInUse.errorMessage,
totalExecutionsPerDay.errorMessage,
].filter((message) => message !== undefined);
return {
state: {
has_errors: hasErrors,
...(errorMessages.length > 0 && { error_messages: errorMessages }),
runs: (state.runs || 0) + 1,
count_total: totalAggegations.countTotal,
count_by_type: totalAggegations.countByType,
count_active_total: totalInUse.countTotal,
count_active_by_type: totalInUse.countByType,
count_active_alert_history_connectors: totalInUse.countByAlertHistoryConnectorType,
count_active_email_connectors_by_service_type: totalInUse.countEmailByService,
count_actions_namespaces: totalInUse.countNamespaces,
count_actions_executions_per_day: totalExecutionsPerDay.countTotal,
count_actions_executions_by_type_per_day: totalExecutionsPerDay.countByType,
count_actions_executions_failed_per_day: totalExecutionsPerDay.countFailed,
count_actions_executions_failed_by_type_per_day:
totalExecutionsPerDay.countFailedByType,
avg_execution_time_per_day: totalExecutionsPerDay.avgExecutionTime,
avg_execution_time_by_type_per_day: totalExecutionsPerDay.avgExecutionTimeByType,
},
runAt: getNextMidnight(),
};
});
},
};
};

View file

@ -8,6 +8,8 @@
import { MakeSchemaFrom } from '@kbn/usage-collection-plugin/server';
export interface ActionsUsage {
has_errors: boolean;
error_messages?: string[];
alert_history_connector_enabled: boolean;
count_total: number;
count_by_type: Record<string, number>;

View file

@ -8,6 +8,7 @@
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { registerAlertingUsageCollector } from './alerting_usage_collector';
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
import { ConcreteTaskInstance, TaskManagerStartContract } from '@kbn/task-manager-plugin/server';
const taskManagerStart = taskManagerMock.createStart();
beforeEach(() => jest.resetAllMocks());
@ -38,4 +39,41 @@ describe('registerAlertingUsageCollector', () => {
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('alerts');
});
it('should return an error message if fetching data fails', async () => {
taskManagerStart.get.mockRejectedValueOnce(new Error('error message'));
const taskManagerPromise = new Promise<TaskManagerStartContract>((resolve) => {
resolve(taskManagerStart);
});
registerAlertingUsageCollector(usageCollectionMock as UsageCollectionSetup, taskManagerPromise);
// @ts-ignore
expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual(
expect.objectContaining({
has_errors: true,
error_messages: ['error message'],
})
);
});
it('should return the task state including error messages', async () => {
const mockStats = {
has_errors: true,
error_messages: ['an error message'],
count_active_total: 1,
count_disabled_total: 10,
};
taskManagerStart.get.mockResolvedValue({
id: '1',
state: mockStats,
} as unknown as ConcreteTaskInstance);
const taskManagerPromise = new Promise<TaskManagerStartContract>((resolve) => {
resolve(taskManagerStart);
});
registerAlertingUsageCollector(usageCollectionMock as UsageCollectionSetup, taskManagerPromise);
// @ts-ignore
expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual(
mockStats
);
});
});

View file

@ -126,11 +126,12 @@ export function createAlertingUsageCollector(
// get the accumulated state from the recurring task
const { runs, ...state } = get(doc, 'state') as AlertingUsage & { runs: number };
return {
...state,
};
return state;
} catch (err) {
const errMessage = err && err.message ? err.message : err.toString();
return {
has_errors: true,
error_messages: [errMessage],
count_total: 0,
count_active_total: 0,
count_disabled_total: 0,
@ -202,6 +203,11 @@ export function createAlertingUsageCollector(
}
},
schema: {
has_errors: { type: 'boolean' },
error_messages: {
type: 'array',
items: { type: 'text' },
},
count_total: { type: 'long' },
count_active_total: { type: 'long' },
count_disabled_total: { type: 'long' },

View file

@ -1398,6 +1398,7 @@ describe('event log telemetry', () => {
logs__alert__document__count: 0,
},
},
hasErrors: false,
});
});
@ -1419,6 +1420,8 @@ describe('event log telemetry', () => {
expect(loggerMeta?.tags).toEqual(['alerting', 'telemetry-failed']);
expect(loggerMeta?.error?.stack_trace).toBeDefined();
expect(telemetry).toStrictEqual({
hasErrors: true,
errorMessage: 'oh no',
countTotalRuleExecutions: 0,
countRuleExecutionsByType: {},
countTotalFailedExecutions: 0,
@ -1495,6 +1498,7 @@ describe('event log telemetry', () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
logs__alert__document__count: 1,
},
hasErrors: false,
});
});
@ -1518,6 +1522,8 @@ describe('event log telemetry', () => {
expect(telemetry).toStrictEqual({
countExecutionTimeouts: 0,
countExecutionTimeoutsByType: {},
errorMessage: 'oh no',
hasErrors: true,
});
});
});

View file

@ -37,6 +37,8 @@ interface Opts {
}
interface GetExecutionsPerDayCountResults {
hasErrors: boolean;
errorMessage?: string;
countTotalRuleExecutions: number;
countRuleExecutionsByType: Record<string, number>;
countTotalFailedExecutions: number;
@ -55,6 +57,8 @@ interface GetExecutionsPerDayCountResults {
}
interface GetExecutionTimeoutsPerDayCountResults {
hasErrors: boolean;
errorMessage?: string;
countExecutionTimeouts: number;
countExecutionTimeoutsByType: Record<string, number>;
}
@ -167,12 +171,14 @@ export async function getExecutionsPerDayCount({
aggregations.by_rule_type_id.buckets as GetExecutionCountsAggregationBucket[];
return {
hasErrors: false,
...parseRuleTypeBucket(aggregationsByRuleTypeId),
...parseExecutionFailureByRuleType(aggregationsByRuleTypeId),
...parseExecutionCountAggregationResults(aggregations),
countTotalRuleExecutions: totalRuleExecutions ?? 0,
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getExecutionsPerDayCount - ${JSON.stringify(err)}`,
{
@ -181,6 +187,8 @@ export async function getExecutionsPerDayCount({
}
);
return {
hasErrors: true,
errorMessage,
countTotalRuleExecutions: 0,
countRuleExecutionsByType: {},
countTotalFailedExecutions: 0,
@ -235,10 +243,13 @@ export async function getExecutionTimeoutsPerDayCount({
typeof results.hits.total === 'number' ? results.hits.total : results.hits.total?.value;
return {
hasErrors: false,
countExecutionTimeouts: totalTimedoutExecutionsCount ?? 0,
countExecutionTimeoutsByType: parseSimpleRuleTypeBucket(aggregations.by_rule_type_id.buckets),
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getExecutionsTimeoutsPerDayCount - ${JSON.stringify(
err
@ -249,6 +260,8 @@ export async function getExecutionTimeoutsPerDayCount({
}
);
return {
hasErrors: true,
errorMessage,
countExecutionTimeouts: 0,
countExecutionTimeoutsByType: {},
};

View file

@ -88,6 +88,7 @@ describe('kibana index telemetry', () => {
logs__alert__document__count: 1,
},
count_total: 4,
hasErrors: false,
schedule_time: {
avg: '4.5s',
max: '10s',
@ -129,6 +130,8 @@ describe('kibana index telemetry', () => {
expect(loggerMeta?.tags).toEqual(['alerting', 'telemetry-failed']);
expect(loggerMeta?.error?.stack_trace).toBeDefined();
expect(telemetry).toEqual({
errorMessage: 'oh no',
hasErrors: true,
connectors_per_alert: {
avg: 0,
max: 0,
@ -219,6 +222,7 @@ describe('kibana index telemetry', () => {
},
countNamespaces: 1,
countTotal: 4,
hasErrors: false,
});
});
@ -243,6 +247,8 @@ describe('kibana index telemetry', () => {
countByType: {},
countNamespaces: 0,
countTotal: 0,
errorMessage: 'oh no',
hasErrors: true,
});
});
});

View file

@ -31,12 +31,14 @@ type GetTotalCountsResults = Pick<
| 'throttle_time_number_s'
| 'schedule_time_number_s'
| 'connectors_per_alert'
>;
> & { errorMessage?: string; hasErrors: boolean };
interface GetTotalCountInUseResults {
countTotal: number;
countByType: Record<string, number>;
countNamespaces: number;
errorMessage?: string;
hasErrors: boolean;
}
export async function getTotalCountAggregations({
@ -79,17 +81,17 @@ export async function getTotalCountAggregations({
int parsed = 0;
if (doc['alert.schedule.interval'].size() > 0) {
def interval = doc['alert.schedule.interval'].value;
if (interval.length() > 1) {
// get last char
String timeChar = interval.substring(interval.length() - 1);
// remove last char
interval = interval.substring(0, interval.length() - 1);
if (interval.chars().allMatch(Character::isDigit)) {
// using of regex is not allowed in painless language
parsed = Integer.parseInt(interval);
if (timeChar.equals("s")) {
parsed = parsed;
} else if (timeChar.equals("m")) {
@ -115,17 +117,17 @@ export async function getTotalCountAggregations({
int parsed = 0;
if (doc['alert.throttle'].size() > 0) {
def throttle = doc['alert.throttle'].value;
if (throttle.length() > 1) {
// get last char
String timeChar = throttle.substring(throttle.length() - 1);
// remove last char
throttle = throttle.substring(0, throttle.length() - 1);
if (throttle.chars().allMatch(Character::isDigit)) {
// using of regex is not allowed in painless language
parsed = Integer.parseInt(throttle);
if (timeChar.equals("s")) {
parsed = parsed;
} else if (timeChar.equals("m")) {
@ -186,6 +188,7 @@ export async function getTotalCountAggregations({
typeof results.hits.total === 'number' ? results.hits.total : results.hits.total?.value;
return {
hasErrors: false,
count_total: totalRulesCount ?? 0,
count_by_type: parseSimpleRuleTypeBucket(aggregations.by_rule_type_id.buckets),
throttle_time: {
@ -215,6 +218,8 @@ export async function getTotalCountAggregations({
},
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getTotalCountAggregations - ${JSON.stringify(err)}`,
{
@ -223,6 +228,8 @@ export async function getTotalCountAggregations({
}
);
return {
hasErrors: true,
errorMessage,
count_total: 0,
count_by_type: {},
throttle_time: {
@ -296,11 +303,13 @@ export async function getTotalCountInUse({
typeof results.hits.total === 'number' ? results.hits.total : results.hits.total?.value;
return {
hasErrors: false,
countTotal: totalEnabledRulesCount ?? 0,
countByType: parseSimpleRuleTypeBucket(aggregations.by_rule_type_id.buckets),
countNamespaces: aggregations.namespaces_count.value ?? 0,
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getTotalCountInUse - ${JSON.stringify(err)}`,
{
@ -309,6 +318,8 @@ export async function getTotalCountInUse({
}
);
return {
hasErrors: true,
errorMessage,
countTotal: 0,
countByType: {},
countNamespaces: 0,

View file

@ -225,6 +225,7 @@ describe('task manager telemetry', () => {
logs__alert__document__count: 4,
},
},
hasErrors: false,
});
});
@ -247,6 +248,8 @@ describe('task manager telemetry', () => {
expect(loggerMeta?.tags).toEqual(['alerting', 'telemetry-failed']);
expect(loggerMeta?.error?.stack_trace).toBeDefined();
expect(telemetry).toStrictEqual({
errorMessage: 'oh no',
hasErrors: true,
countFailedAndUnrecognizedTasks: 0,
countFailedAndUnrecognizedTasksByStatus: {},
countFailedAndUnrecognizedTasksByStatusByType: {},

View file

@ -26,6 +26,8 @@ interface GetFailedAndUnrecognizedTasksAggregationBucket extends AggregationsStr
}
interface GetFailedAndUnrecognizedTasksResults {
hasErrors: boolean;
errorMessage?: string;
countFailedAndUnrecognizedTasks: number;
countFailedAndUnrecognizedTasksByStatus: Record<string, number>;
countFailedAndUnrecognizedTasksByStatusByType: Record<string, Record<string, number>>;
@ -115,10 +117,12 @@ export async function getFailedAndUnrecognizedTasksPerDay({
aggregations.by_status.buckets as GetFailedAndUnrecognizedTasksAggregationBucket[];
return {
hasErrors: false,
...parseBucket(aggregationsByStatus),
countFailedAndUnrecognizedTasks: totalFailedAndUnrecognizedTasks ?? 0,
};
} catch (err) {
const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getFailedAndUnrecognizedTasksPerDay - ${JSON.stringify(
err
@ -129,6 +133,8 @@ export async function getFailedAndUnrecognizedTasksPerDay({
}
);
return {
hasErrors: true,
errorMessage,
countFailedAndUnrecognizedTasks: 0,
countFailedAndUnrecognizedTasksByStatus: {},
countFailedAndUnrecognizedTasksByStatusByType: {},

View file

@ -111,10 +111,33 @@ export function telemetryTaskRunner(
dailyExecutionTimeoutCounts,
dailyFailedAndUnrecognizedTasks,
]) => {
const hasErrors =
totalCountAggregations.hasErrors ||
totalInUse.hasErrors ||
dailyExecutionCounts.hasErrors ||
dailyExecutionTimeoutCounts.hasErrors ||
dailyFailedAndUnrecognizedTasks.hasErrors;
const errorMessages = [
totalCountAggregations.errorMessage,
totalInUse.errorMessage,
dailyExecutionCounts.errorMessage,
dailyExecutionTimeoutCounts.errorMessage,
dailyFailedAndUnrecognizedTasks.errorMessage,
].filter((message) => message !== undefined);
return {
state: {
has_errors: hasErrors,
...(errorMessages.length > 0 && { error_messages: errorMessages }),
runs: (state.runs || 0) + 1,
...totalCountAggregations,
count_total: totalCountAggregations.count_total,
count_by_type: totalCountAggregations.count_by_type,
throttle_time: totalCountAggregations.throttle_time,
schedule_time: totalCountAggregations.schedule_time,
throttle_time_number_s: totalCountAggregations.throttle_time_number_s,
schedule_time_number_s: totalCountAggregations.schedule_time_number_s,
connectors_per_alert: totalCountAggregations.connectors_per_alert,
count_active_by_type: totalInUse.countByType,
count_active_total: totalInUse.countTotal,
count_disabled_total: totalCountAggregations.count_total - totalInUse.countTotal,

View file

@ -6,6 +6,8 @@
*/
export interface AlertingUsage {
has_errors: boolean;
error_messages?: string[];
count_total: number;
count_active_total: number;
count_disabled_total: number;

View file

@ -2,6 +2,15 @@
"properties": {
"actions": {
"properties": {
"has_errors": {
"type": "boolean"
},
"error_messages": {
"type": "array",
"items": {
"type": "text"
}
},
"alert_history_connector_enabled": {
"type": "boolean",
"_meta": {
@ -261,6 +270,15 @@
},
"alerts": {
"properties": {
"has_errors": {
"type": "boolean"
},
"error_messages": {
"type": "array",
"items": {
"type": "text"
}
},
"count_total": {
"type": "long"
},