Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proof of Concept] Add otel metrics to alerting plugin #133171

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5a8bc3b
Add otel metrics to alerting plugin
matschaffer May 31, 2022
08b66fb
Hacking around test failures
matschaffer May 31, 2022
49c6f7f
Revert "Hacking around test failures"
matschaffer Jun 2, 2022
92e94df
Guard otel initialization & remove debug logging
matschaffer Jun 2, 2022
c1904e1
Merge branch 'main' into kibana-128755-otel-metrics-poc
kibanamachine Jun 2, 2022
2a41cf4
Follow readonly lint recommendation
matschaffer Jun 2, 2022
7ec3148
Merge branch 'main' into kibana-128755-otel-metrics-poc
kibanamachine Jun 6, 2022
634f538
Move to 10s interval
matschaffer Jun 2, 2022
028664a
Use otel api for meter type
matschaffer Jun 6, 2022
845e3e5
Fix mock
matschaffer Jun 6, 2022
3cc35fa
Set service name
matschaffer Jun 6, 2022
da43f0b
Use otel metrics from monitoring_collection plugin
matschaffer Jun 6, 2022
b47e16a
Typo on otlp
matschaffer Jun 6, 2022
86f9eb5
Put getMetrics back in mock
matschaffer Jun 6, 2022
a71f4af
Take out resource due to type check issue
matschaffer Jun 6, 2022
2efc930
Switch to 0.29 and global metrics meter provider
matschaffer Jun 8, 2022
48e79b8
Use http/s to toggle grpc secure handling
matschaffer Jun 8, 2022
5aad5c3
Remove unnecesary getMeter method
matschaffer Jun 8, 2022
b796dd3
Remove unnecessary unused meterProvider member
matschaffer Jun 8, 2022
9593dde
Avoid double grpcjs versions
matschaffer Jun 8, 2022
2f4a200
Merge branch 'main' into kibana-128755-otel-metrics-poc
kibanamachine Jun 8, 2022
ec49742
Update tests for new SDK & global meter provider
matschaffer Jun 8, 2022
12f231a
Remove extra config call
matschaffer Jun 8, 2022
f12a484
Merge branch 'main' into kibana-128755-otel-metrics-poc
kibanamachine Jun 9, 2022
10b63f0
Add prometheus exporter
matschaffer Jun 9, 2022
df02d12
Wire up prometheus exporter when configured
matschaffer Jun 9, 2022
c77ff35
Fix unconfigured case
matschaffer Jun 9, 2022
4c32ab6
Move opentelemetry integration up to plugin level
matschaffer Jun 9, 2022
53339f8
Merge branch 'main' into kibana-128755-otel-metrics-poc
kibanamachine Jun 9, 2022
339951f
Add missing test mocks
matschaffer Jun 13, 2022
f6ec93c
Merge branch 'main' into kibana-128755-otel-metrics-poc
matschaffer Jun 13, 2022
05389c3
Add authenticated prometheus endpoint
matschaffer Jun 13, 2022
a657820
Add note about upstream PR
matschaffer Jun 13, 2022
aee16d6
Wire up additional otel attributes
matschaffer Jun 13, 2022
2804efc
Additional instrumentation
matschaffer Jun 14, 2022
d02dceb
Test against real metrics with test meter
matschaffer Jun 14, 2022
371296a
Add OTLP header config
matschaffer Jun 14, 2022
330dbbd
Merge remote-tracking branch 'upstream/main' into kibana-128755-otel-…
matschaffer Jun 15, 2022
927fc11
Merge branch 'main' into kibana-128755-otel-metrics-poc
matschaffer Jun 21, 2022
a3c9c48
Merge branch 'main' into kibana-128755-otel-metrics-poc
matschaffer Jun 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"@emotion/css": "^11.9.0",
"@emotion/react": "^11.9.0",
"@emotion/serialize": "^1.0.3",
"@grpc/grpc-js": "^1.5.9",
"@hapi/accept": "^5.0.2",
"@hapi/boom": "^9.1.4",
"@hapi/cookie": "^11.0.2",
Expand Down Expand Up @@ -237,6 +238,12 @@
"@mapbox/mapbox-gl-draw": "1.3.0",
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
"@mapbox/vector-tile": "1.3.1",
"@opentelemetry/api-metrics": "0.29.2",
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.29.2",
"@opentelemetry/exporter-prometheus": "^0.29.2",
"@opentelemetry/resources": "^1.3.1",
"@opentelemetry/sdk-metrics-base": "^0.29.2",
"@opentelemetry/semantic-conventions": "^1.3.1",
"@reduxjs/toolkit": "^1.6.1",
"@slack/webhook": "^5.0.4",
"@turf/along": "6.0.1",
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/alerting/server/monitoring/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export { registerNodeCollector } from './register_node_collector';
export { registerClusterCollector } from './register_cluster_collector';
export * from './types';
export * from './in_memory_metrics';
export * from './metrics';
13 changes: 13 additions & 0 deletions x-pack/plugins/alerting/server/monitoring/metrics.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 { metrics } from '@opentelemetry/api-metrics';
import { Metrics } from './metrics';

export const metricsMock = {
create: () => new Metrics(metrics.getMeter('kibana.alerting.metrics.mock')),
};
22 changes: 22 additions & 0 deletions x-pack/plugins/alerting/server/monitoring/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 { Counter, Histogram, Meter } from '@opentelemetry/api-metrics';

export class Metrics {
ruleExecutionsTotal: Counter;
ruleExecutions: Counter;
ruleFailures: Counter;
ruleDuration: Histogram;

constructor(meter: Meter) {
this.ruleExecutionsTotal = meter.createCounter('ruleExecutionsTotal');
this.ruleExecutions = meter.createCounter('ruleExecutions');
this.ruleFailures = meter.createCounter('ruleFailures');
this.ruleDuration = meter.createHistogram('ruleDuration');
}
}
11 changes: 10 additions & 1 deletion x-pack/plugins/alerting/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
import { PluginStartContract as FeaturesPluginStart } from '@kbn/features-plugin/server';
import { PluginStart as DataPluginStart } from '@kbn/data-plugin/server';
import { MonitoringCollectionSetup } from '@kbn/monitoring-collection-plugin/server';
import { metrics } from '@opentelemetry/api-metrics';
import { RuleTypeRegistry } from './rule_type_registry';
import { TaskRunnerFactory } from './task_runner';
import { RulesClientFactory } from './rules_client_factory';
Expand Down Expand Up @@ -77,7 +78,12 @@ import { getHealth } from './health/get_health';
import { AlertingAuthorizationClientFactory } from './alerting_authorization_client_factory';
import { AlertingAuthorization } from './authorization';
import { getSecurityHealth, SecurityHealth } from './lib/get_security_health';
import { registerNodeCollector, registerClusterCollector, InMemoryMetrics } from './monitoring';
import {
registerNodeCollector,
registerClusterCollector,
InMemoryMetrics,
Metrics,
} from './monitoring';
import { getRuleTaskTimeout } from './lib/get_rule_task_timeout';
import { getActionsConfigMap } from './lib/get_actions_config_map';

Expand Down Expand Up @@ -173,6 +179,7 @@ export class AlertingPlugin {
private kibanaBaseUrl: string | undefined;
private usageCounter: UsageCounter | undefined;
private inMemoryMetrics: InMemoryMetrics;
private metrics: Metrics;

constructor(initializerContext: PluginInitializerContext) {
this.config = initializerContext.config.get();
Expand All @@ -183,6 +190,7 @@ export class AlertingPlugin {
this.telemetryLogger = initializerContext.logger.get('usage');
this.kibanaVersion = initializerContext.env.packageInfo.version;
this.inMemoryMetrics = new InMemoryMetrics(initializerContext.logger.get('in_memory_metrics'));
this.metrics = new Metrics(metrics.getMeter('kibana.alerting'));
}

public setup(
Expand Down Expand Up @@ -227,6 +235,7 @@ export class AlertingPlugin {
licensing: plugins.licensing,
minimumScheduleInterval: this.config.rules.minimumScheduleInterval,
inMemoryMetrics: this.inMemoryMetrics,
metrics: this.metrics,
});
this.ruleTypeRegistry = ruleTypeRegistry;

Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/alerting/server/rule_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import { licenseStateMock } from './lib/license_state.mock';
import { licensingMock } from '@kbn/licensing-plugin/server/mocks';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import { inMemoryMetricsMock } from './monitoring/in_memory_metrics.mock';
import { metricsMock } from './monitoring/metrics.mock';

const logger = loggingSystemMock.create().get();
let mockedLicenseState: jest.Mocked<ILicenseState>;
let ruleTypeRegistryParams: ConstructorOptions;

const taskManager = taskManagerMock.createSetup();
const inMemoryMetrics = inMemoryMetricsMock.create();
const metrics = metricsMock.create();

beforeEach(() => {
jest.resetAllMocks();
Expand All @@ -33,6 +35,7 @@ beforeEach(() => {
licensing: licensingMock.createSetup(),
minimumScheduleInterval: { value: '1m', enforce: false },
inMemoryMetrics,
metrics,
};
});

Expand Down
8 changes: 6 additions & 2 deletions x-pack/plugins/alerting/server/rule_type_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
} from '../common';
import { ILicenseState } from './lib/license_state';
import { getRuleTypeFeatureUsageName } from './lib/get_rule_type_feature_usage_name';
import { InMemoryMetrics } from './monitoring';
import { InMemoryMetrics, Metrics } from './monitoring';
import { AlertingRulesConfig } from '.';

export interface ConstructorOptions {
Expand All @@ -42,6 +42,7 @@ export interface ConstructorOptions {
licensing: LicensingPluginSetup;
minimumScheduleInterval: AlertingRulesConfig['minimumScheduleInterval'];
inMemoryMetrics: InMemoryMetrics;
metrics: Metrics;
}

export interface RegistryRuleType
Expand Down Expand Up @@ -139,6 +140,7 @@ export class RuleTypeRegistry {
private readonly minimumScheduleInterval: AlertingRulesConfig['minimumScheduleInterval'];
private readonly licensing: LicensingPluginSetup;
private readonly inMemoryMetrics: InMemoryMetrics;
private readonly metrics: Metrics;

constructor({
logger,
Expand All @@ -148,6 +150,7 @@ export class RuleTypeRegistry {
licensing,
minimumScheduleInterval,
inMemoryMetrics,
metrics,
}: ConstructorOptions) {
this.logger = logger;
this.taskManager = taskManager;
Expand All @@ -156,6 +159,7 @@ export class RuleTypeRegistry {
this.licensing = licensing;
this.minimumScheduleInterval = minimumScheduleInterval;
this.inMemoryMetrics = inMemoryMetrics;
this.metrics = metrics;
}

public has(id: string) {
Expand Down Expand Up @@ -274,7 +278,7 @@ export class RuleTypeRegistry {
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId | RecoveredActionGroupId
>(normalizedRuleType, context, this.inMemoryMetrics),
>(normalizedRuleType, context, this.inMemoryMetrics, this.metrics),
},
});
// No need to notify usage on basic alert types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import { licensingMock } from '@kbn/licensing-plugin/server/mocks';
import { isRuleExportable } from './is_rule_exportable';
import { inMemoryMetricsMock } from '../monitoring/in_memory_metrics.mock';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import { metricsMock } from '../monitoring/metrics.mock';

let ruleTypeRegistryParams: ConstructorOptions;
let logger: MockedLogger;
let mockedLicenseState: jest.Mocked<ILicenseState>;
const taskManager = taskManagerMock.createSetup();
const inMemoryMetrics = inMemoryMetricsMock.create();
const metrics = metricsMock.create();

beforeEach(() => {
jest.resetAllMocks();
Expand All @@ -34,6 +36,7 @@ beforeEach(() => {
licensing: licensingMock.createSetup(),
minimumScheduleInterval: { value: '1m', enforce: false },
inMemoryMetrics,
metrics,
};
});

Expand Down
Loading