diff --git a/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor._constructor_.md b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor._constructor_.md
new file mode 100644
index 0000000000000..3a9efc0eacdb6
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor._constructor_.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [EventLoopDelaysMonitor](./kibana-plugin-core-server.eventloopdelaysmonitor.md) > [(constructor)](./kibana-plugin-core-server.eventloopdelaysmonitor._constructor_.md)
+
+## EventLoopDelaysMonitor.(constructor)
+
+Constructs a new instance of the `EventLoopDelaysMonitor` class
+
+Signature:
+
+```typescript
+constructor();
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.collect.md b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.collect.md
new file mode 100644
index 0000000000000..6277f59067239
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.collect.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [EventLoopDelaysMonitor](./kibana-plugin-core-server.eventloopdelaysmonitor.md) > [collect](./kibana-plugin-core-server.eventloopdelaysmonitor.collect.md)
+
+## EventLoopDelaysMonitor.collect() method
+
+Signature:
+
+```typescript
+collect(): IntervalHistogram;
+```
+Returns:
+
+`IntervalHistogram`
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.md b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.md
new file mode 100644
index 0000000000000..15d02ecd5f25d
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.md
@@ -0,0 +1,26 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [EventLoopDelaysMonitor](./kibana-plugin-core-server.eventloopdelaysmonitor.md)
+
+## EventLoopDelaysMonitor class
+
+Signature:
+
+```typescript
+export declare class EventLoopDelaysMonitor
+```
+
+## Constructors
+
+| Constructor | Modifiers | Description |
+| --- | --- | --- |
+| [(constructor)()](./kibana-plugin-core-server.eventloopdelaysmonitor._constructor_.md) | | Constructs a new instance of the EventLoopDelaysMonitor
class |
+
+## Methods
+
+| Method | Modifiers | Description |
+| --- | --- | --- |
+| [collect()](./kibana-plugin-core-server.eventloopdelaysmonitor.collect.md) | | |
+| [reset()](./kibana-plugin-core-server.eventloopdelaysmonitor.reset.md) | | |
+| [stop()](./kibana-plugin-core-server.eventloopdelaysmonitor.stop.md) | | |
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.reset.md b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.reset.md
new file mode 100644
index 0000000000000..c593d0341bbed
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.reset.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [EventLoopDelaysMonitor](./kibana-plugin-core-server.eventloopdelaysmonitor.md) > [reset](./kibana-plugin-core-server.eventloopdelaysmonitor.reset.md)
+
+## EventLoopDelaysMonitor.reset() method
+
+Signature:
+
+```typescript
+reset(): void;
+```
+Returns:
+
+`void`
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.stop.md b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.stop.md
new file mode 100644
index 0000000000000..86e76d0c6fba4
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.eventloopdelaysmonitor.stop.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [EventLoopDelaysMonitor](./kibana-plugin-core-server.eventloopdelaysmonitor.md) > [stop](./kibana-plugin-core-server.eventloopdelaysmonitor.stop.md)
+
+## EventLoopDelaysMonitor.stop() method
+
+Signature:
+
+```typescript
+stop(): void;
+```
+Returns:
+
+`void`
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.exceeds.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.exceeds.md
new file mode 100644
index 0000000000000..664bdb8f24d7b
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.exceeds.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [exceeds](./kibana-plugin-core-server.intervalhistogram.exceeds.md)
+
+## IntervalHistogram.exceeds property
+
+Signature:
+
+```typescript
+exceeds: number;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.fromtimestamp.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.fromtimestamp.md
new file mode 100644
index 0000000000000..00fa8dcb84430
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.fromtimestamp.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [fromTimestamp](./kibana-plugin-core-server.intervalhistogram.fromtimestamp.md)
+
+## IntervalHistogram.fromTimestamp property
+
+Signature:
+
+```typescript
+fromTimestamp: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.lastupdatedat.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.lastupdatedat.md
new file mode 100644
index 0000000000000..58e75fc2ba437
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.lastupdatedat.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [lastUpdatedAt](./kibana-plugin-core-server.intervalhistogram.lastupdatedat.md)
+
+## IntervalHistogram.lastUpdatedAt property
+
+Signature:
+
+```typescript
+lastUpdatedAt: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.max.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.max.md
new file mode 100644
index 0000000000000..14d7fe6b68c4b
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.max.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [max](./kibana-plugin-core-server.intervalhistogram.max.md)
+
+## IntervalHistogram.max property
+
+Signature:
+
+```typescript
+max: number;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.md
new file mode 100644
index 0000000000000..20f71420a0d88
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.md
@@ -0,0 +1,25 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md)
+
+## IntervalHistogram interface
+
+Signature:
+
+```typescript
+export interface IntervalHistogram
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [exceeds](./kibana-plugin-core-server.intervalhistogram.exceeds.md) | number
| |
+| [fromTimestamp](./kibana-plugin-core-server.intervalhistogram.fromtimestamp.md) | string
| |
+| [lastUpdatedAt](./kibana-plugin-core-server.intervalhistogram.lastupdatedat.md) | string
| |
+| [max](./kibana-plugin-core-server.intervalhistogram.max.md) | number
| |
+| [mean](./kibana-plugin-core-server.intervalhistogram.mean.md) | number
| |
+| [min](./kibana-plugin-core-server.intervalhistogram.min.md) | number
| |
+| [percentiles](./kibana-plugin-core-server.intervalhistogram.percentiles.md) | {
50: number;
75: number;
95: number;
99: number;
}
| |
+| [stddev](./kibana-plugin-core-server.intervalhistogram.stddev.md) | number
| |
+
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.mean.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.mean.md
new file mode 100644
index 0000000000000..e6794bfa5fe52
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.mean.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [mean](./kibana-plugin-core-server.intervalhistogram.mean.md)
+
+## IntervalHistogram.mean property
+
+Signature:
+
+```typescript
+mean: number;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.min.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.min.md
new file mode 100644
index 0000000000000..d0eb929601f18
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.min.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [min](./kibana-plugin-core-server.intervalhistogram.min.md)
+
+## IntervalHistogram.min property
+
+Signature:
+
+```typescript
+min: number;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.percentiles.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.percentiles.md
new file mode 100644
index 0000000000000..b0adc9531c0b1
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.percentiles.md
@@ -0,0 +1,16 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [percentiles](./kibana-plugin-core-server.intervalhistogram.percentiles.md)
+
+## IntervalHistogram.percentiles property
+
+Signature:
+
+```typescript
+percentiles: {
+ 50: number;
+ 75: number;
+ 95: number;
+ 99: number;
+ };
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.stddev.md b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.stddev.md
new file mode 100644
index 0000000000000..bca5ab56cb237
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.intervalhistogram.stddev.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) > [stddev](./kibana-plugin-core-server.intervalhistogram.stddev.md)
+
+## IntervalHistogram.stddev property
+
+Signature:
+
+```typescript
+stddev: number;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md
index 96bb82c8968df..a702c5fe7b97b 100644
--- a/docs/development/core/server/kibana-plugin-core-server.md
+++ b/docs/development/core/server/kibana-plugin-core-server.md
@@ -19,6 +19,7 @@ The plugin integrates with the core system via lifecycle events: `setup`
| [BasePath](./kibana-plugin-core-server.basepath.md) | Access or manipulate the Kibana base path |
| [CspConfig](./kibana-plugin-core-server.cspconfig.md) | CSP configuration for use in Kibana. |
| [ElasticsearchConfig](./kibana-plugin-core-server.elasticsearchconfig.md) | Wrapper of config schema. |
+| [EventLoopDelaysMonitor](./kibana-plugin-core-server.eventloopdelaysmonitor.md) | |
| [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md) | Kibana specific abstraction for an incoming request. |
| [RouteValidationError](./kibana-plugin-core-server.routevalidationerror.md) | Error to return when the validation is not successful. |
| [SavedObjectsClient](./kibana-plugin-core-server.savedobjectsclient.md) | |
@@ -97,6 +98,7 @@ The plugin integrates with the core system via lifecycle events: `setup`
| [IExternalUrlPolicy](./kibana-plugin-core-server.iexternalurlpolicy.md) | A policy describing whether access to an external destination is allowed. |
| [IKibanaResponse](./kibana-plugin-core-server.ikibanaresponse.md) | A response data object, expected to returned as a result of [RequestHandler](./kibana-plugin-core-server.requesthandler.md) execution |
| [IKibanaSocket](./kibana-plugin-core-server.ikibanasocket.md) | A tiny abstraction for TCP socket. |
+| [IntervalHistogram](./kibana-plugin-core-server.intervalhistogram.md) | |
| [IRenderOptions](./kibana-plugin-core-server.irenderoptions.md) | |
| [IRouter](./kibana-plugin-core-server.irouter.md) | Registers route handlers for specified resource path and method. See [RouteConfig](./kibana-plugin-core-server.routeconfig.md) and [RequestHandler](./kibana-plugin-core-server.requesthandler.md) for more information about arguments to route registrations. |
| [ISavedObjectsPointInTimeFinder](./kibana-plugin-core-server.isavedobjectspointintimefinder.md) | |
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md
index 9803c0fbd53cc..1572c1ae3131e 100644
--- a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md
+++ b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md
@@ -19,7 +19,8 @@ export interface OpsMetrics
| [collected\_at](./kibana-plugin-core-server.opsmetrics.collected_at.md) | Date
| Time metrics were recorded at. |
| [concurrent\_connections](./kibana-plugin-core-server.opsmetrics.concurrent_connections.md) | OpsServerMetrics['concurrent_connections']
| number of current concurrent connections to the server |
| [os](./kibana-plugin-core-server.opsmetrics.os.md) | OpsOsMetrics
| OS related metrics |
-| [process](./kibana-plugin-core-server.opsmetrics.process.md) | OpsProcessMetrics
| Process related metrics |
+| [process](./kibana-plugin-core-server.opsmetrics.process.md) | OpsProcessMetrics
| Process related metrics. Deprecated in favor of processes field. |
+| [processes](./kibana-plugin-core-server.opsmetrics.processes.md) | OpsProcessMetrics[]
| Process related metrics. Reports an array of objects for each kibana pid. |
| [requests](./kibana-plugin-core-server.opsmetrics.requests.md) | OpsServerMetrics['requests']
| server requests stats |
| [response\_times](./kibana-plugin-core-server.opsmetrics.response_times.md) | OpsServerMetrics['response_times']
| server response time stats |
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.process.md b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.process.md
index b3759fadafc0a..9da2c0644dc84 100644
--- a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.process.md
+++ b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.process.md
@@ -4,7 +4,11 @@
## OpsMetrics.process property
-Process related metrics
+> Warning: This API is now obsolete.
+>
+>
+
+Process related metrics. Deprecated in favor of processes field.
Signature:
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.processes.md b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.processes.md
new file mode 100644
index 0000000000000..cf1f0a7c54475
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.processes.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [OpsMetrics](./kibana-plugin-core-server.opsmetrics.md) > [processes](./kibana-plugin-core-server.opsmetrics.processes.md)
+
+## OpsMetrics.processes property
+
+Process related metrics. Reports an array of objects for each kibana pid.
+
+Signature:
+
+```typescript
+processes: OpsProcessMetrics[];
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay.md b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay.md
index 239f94e37d00e..d626b9cf8f98c 100644
--- a/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay.md
+++ b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay.md
@@ -4,7 +4,7 @@
## OpsProcessMetrics.event\_loop\_delay property
-node event loop delay
+mean event loop delay since last collection
Signature:
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay_histogram.md b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay_histogram.md
new file mode 100644
index 0000000000000..1d870b19f2d1f
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.event_loop_delay_histogram.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [OpsProcessMetrics](./kibana-plugin-core-server.opsprocessmetrics.md) > [event\_loop\_delay\_histogram](./kibana-plugin-core-server.opsprocessmetrics.event_loop_delay_histogram.md)
+
+## OpsProcessMetrics.event\_loop\_delay\_histogram property
+
+node event loop delay histogram since last collection
+
+Signature:
+
+```typescript
+event_loop_delay_histogram: IntervalHistogram;
+```
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.md b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.md
index 79763b783470e..fdaaf594232fd 100644
--- a/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.md
+++ b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.md
@@ -16,8 +16,10 @@ export interface OpsProcessMetrics
| Property | Type | Description |
| --- | --- | --- |
-| [event\_loop\_delay](./kibana-plugin-core-server.opsprocessmetrics.event_loop_delay.md) | number
| node event loop delay |
+| [event\_loop\_delay\_histogram](./kibana-plugin-core-server.opsprocessmetrics.event_loop_delay_histogram.md) | IntervalHistogram
| node event loop delay histogram since last collection |
+| [event\_loop\_delay](./kibana-plugin-core-server.opsprocessmetrics.event_loop_delay.md) | number
| mean event loop delay since last collection |
| [memory](./kibana-plugin-core-server.opsprocessmetrics.memory.md) | {
heap: {
total_in_bytes: number;
used_in_bytes: number;
size_limit: number;
};
resident_set_size_in_bytes: number;
}
| process memory usage |
+| [name](./kibana-plugin-core-server.opsprocessmetrics.name.md) | 'coordinator' | 'server_worker'
| name of process (example: 'coordinator' \| 'server\_worker' \| 'task\_worker' \| 'reporting\_worker') |
| [pid](./kibana-plugin-core-server.opsprocessmetrics.pid.md) | number
| pid of the kibana process |
| [uptime\_in\_millis](./kibana-plugin-core-server.opsprocessmetrics.uptime_in_millis.md) | number
| uptime of the kibana process |
diff --git a/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.name.md b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.name.md
new file mode 100644
index 0000000000000..72f98fb7e717d
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-core-server.opsprocessmetrics.name.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [OpsProcessMetrics](./kibana-plugin-core-server.opsprocessmetrics.md) > [name](./kibana-plugin-core-server.opsprocessmetrics.name.md)
+
+## OpsProcessMetrics.name property
+
+name of process (example: 'coordinator' \| 'server\_worker' \| 'task\_worker' \| 'reporting\_worker')
+
+Signature:
+
+```typescript
+name: 'coordinator' | 'server_worker';
+```
diff --git a/src/core/public/core_app/status/lib/load_status.test.ts b/src/core/public/core_app/status/lib/load_status.test.ts
index e412192ea00ee..7411cab5892ac 100644
--- a/src/core/public/core_app/status/lib/load_status.test.ts
+++ b/src/core/public/core_app/status/lib/load_status.test.ts
@@ -9,6 +9,7 @@
import { StatusResponse } from '../../../../types/status';
import { httpServiceMock } from '../../../http/http_service.mock';
import { notificationServiceMock } from '../../../notifications/notifications_service.mock';
+import { mocked } from '../../../../server/metrics/event_loop_delays/event_loop_delays_monitor.mocks';
import { loadStatus } from './load_status';
const mockedResponse: StatusResponse = {
@@ -61,6 +62,8 @@ const mockedResponse: StatusResponse = {
},
},
process: {
+ name: 'server_worker' as const,
+ pid: 1,
memory: {
heap: {
size_limit: 1000000,
@@ -70,9 +73,26 @@ const mockedResponse: StatusResponse = {
resident_set_size_in_bytes: 1,
},
event_loop_delay: 1,
- pid: 1,
+ event_loop_delay_histogram: mocked.createHistogram(),
uptime_in_millis: 1,
},
+ processes: [
+ {
+ name: 'server_worker' as const,
+ pid: 1,
+ memory: {
+ heap: {
+ size_limit: 1000000,
+ used_in_bytes: 100,
+ total_in_bytes: 0,
+ },
+ resident_set_size_in_bytes: 1,
+ },
+ event_loop_delay: 1,
+ event_loop_delay_histogram: mocked.createHistogram(),
+ uptime_in_millis: 1,
+ },
+ ],
response_times: {
avg_in_millis: 4000,
max_in_millis: 8000,
diff --git a/src/core/server/index.ts b/src/core/server/index.ts
index 1c3a0850d3b79..f2eb7ccd3a253 100644
--- a/src/core/server/index.ts
+++ b/src/core/server/index.ts
@@ -378,7 +378,9 @@ export type {
OpsProcessMetrics,
MetricsServiceSetup,
MetricsServiceStart,
+ IntervalHistogram,
} from './metrics';
+export { EventLoopDelaysMonitor } from './metrics';
export type { I18nServiceSetup } from './i18n';
export type {
diff --git a/src/core/server/metrics/collectors/collector.mock.ts b/src/core/server/metrics/collectors/collector.mock.ts
index bf45925bf583f..088156fa2ff5e 100644
--- a/src/core/server/metrics/collectors/collector.mock.ts
+++ b/src/core/server/metrics/collectors/collector.mock.ts
@@ -8,8 +8,10 @@
import { MetricsCollector } from './types';
-const createCollector = (collectReturnValue: any = {}): jest.Mocked> => {
- const collector: jest.Mocked> = {
+const createCollector = (
+ collectReturnValue: any = {}
+): jest.Mocked> => {
+ const collector: jest.Mocked> = {
collect: jest.fn().mockResolvedValue(collectReturnValue),
reset: jest.fn(),
};
diff --git a/src/core/server/metrics/collectors/mocks.ts b/src/core/server/metrics/collectors/mocks.ts
index ad8dd9fa57966..425751899ddc9 100644
--- a/src/core/server/metrics/collectors/mocks.ts
+++ b/src/core/server/metrics/collectors/mocks.ts
@@ -6,7 +6,8 @@
* Side Public License, v 1.
*/
-import { MetricsCollector } from './types';
+import type { MetricsCollector } from './types';
+import { createMockOpsProcessMetrics } from './process.mocks';
const createMock = () => {
const mocked: jest.Mocked> = {
@@ -21,4 +22,5 @@ const createMock = () => {
export const collectorMock = {
create: createMock,
+ createOpsProcessMetrics: createMockOpsProcessMetrics,
};
diff --git a/src/core/server/metrics/collectors/process.mocks.ts b/src/core/server/metrics/collectors/process.mocks.ts
new file mode 100644
index 0000000000000..e9c002f320fb5
--- /dev/null
+++ b/src/core/server/metrics/collectors/process.mocks.ts
@@ -0,0 +1,25 @@
+/*
+ * 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 { mocked } from '../event_loop_delays/event_loop_delays_monitor.mocks';
+import type { OpsProcessMetrics } from './types';
+
+export function createMockOpsProcessMetrics(): OpsProcessMetrics {
+ const histogram = mocked.createHistogram();
+
+ return {
+ name: 'server_worker' as const,
+ memory: {
+ heap: { total_in_bytes: 1, used_in_bytes: 1, size_limit: 1 },
+ resident_set_size_in_bytes: 1,
+ },
+ event_loop_delay: 1,
+ event_loop_delay_histogram: histogram,
+ pid: 1,
+ uptime_in_millis: 1,
+ };
+}
diff --git a/src/core/server/metrics/collectors/process.test.ts b/src/core/server/metrics/collectors/process.test.ts
index 0395cd8d597fd..ff861d5c8bef1 100644
--- a/src/core/server/metrics/collectors/process.test.ts
+++ b/src/core/server/metrics/collectors/process.test.ts
@@ -9,6 +9,7 @@
import v8, { HeapInfo } from 'v8';
import { ProcessMetricsCollector } from './process';
+/* eslint-disable dot-notation */
describe('ProcessMetricsCollector', () => {
let collector: ProcessMetricsCollector;
@@ -20,28 +21,34 @@ describe('ProcessMetricsCollector', () => {
jest.restoreAllMocks();
});
- it('collects pid from the process', async () => {
- const metrics = await collector.collect();
+ it('collects pid from the process', () => {
+ const metrics = collector.collect();
- expect(metrics.pid).toEqual(process.pid);
+ expect(metrics).toHaveLength(1);
+ expect(metrics[0].pid).toEqual(process.pid);
});
- it('collects event loop delay', async () => {
- const metrics = await collector.collect();
-
- expect(metrics.event_loop_delay).toBeGreaterThan(0);
+ it('collects event loop delay', () => {
+ const mockEventLoopDelayMonitor = { collect: jest.fn().mockReturnValue({ mean: 13 }) };
+ // @ts-expect-error-next-line readonly private method.
+ collector['eventLoopDelayMonitor'] = mockEventLoopDelayMonitor;
+ const metrics = collector.collect();
+ expect(metrics).toHaveLength(1);
+ expect(metrics[0].event_loop_delay).toBe(13);
+ expect(mockEventLoopDelayMonitor.collect).toBeCalledTimes(1);
});
- it('collects uptime info from the process', async () => {
+ it('collects uptime info from the process', () => {
const uptime = 58986;
jest.spyOn(process, 'uptime').mockImplementation(() => uptime);
- const metrics = await collector.collect();
+ const metrics = collector.collect();
- expect(metrics.uptime_in_millis).toEqual(uptime * 1000);
+ expect(metrics).toHaveLength(1);
+ expect(metrics[0].uptime_in_millis).toEqual(uptime * 1000);
});
- it('collects memory info from the process', async () => {
+ it('collects memory info from the process', () => {
const heapTotal = 58986;
const heapUsed = 4688;
const heapSizeLimit = 5788;
@@ -61,11 +68,12 @@ describe('ProcessMetricsCollector', () => {
} as HeapInfo)
);
- const metrics = await collector.collect();
+ const metrics = collector.collect();
- expect(metrics.memory.heap.total_in_bytes).toEqual(heapTotal);
- expect(metrics.memory.heap.used_in_bytes).toEqual(heapUsed);
- expect(metrics.memory.heap.size_limit).toEqual(heapSizeLimit);
- expect(metrics.memory.resident_set_size_in_bytes).toEqual(rss);
+ expect(metrics).toHaveLength(1);
+ expect(metrics[0].memory.heap.total_in_bytes).toEqual(heapTotal);
+ expect(metrics[0].memory.heap.used_in_bytes).toEqual(heapUsed);
+ expect(metrics[0].memory.heap.size_limit).toEqual(heapSizeLimit);
+ expect(metrics[0].memory.resident_set_size_in_bytes).toEqual(rss);
});
});
diff --git a/src/core/server/metrics/collectors/process.ts b/src/core/server/metrics/collectors/process.ts
index d7ff967114f00..8205de65a6b78 100644
--- a/src/core/server/metrics/collectors/process.ts
+++ b/src/core/server/metrics/collectors/process.ts
@@ -7,15 +7,23 @@
*/
import v8 from 'v8';
-import { Bench } from '@hapi/hoek';
import { OpsProcessMetrics, MetricsCollector } from './types';
+import { EventLoopDelaysMonitor } from '../event_loop_delays';
-export class ProcessMetricsCollector implements MetricsCollector {
- public async collect(): Promise {
+export class ProcessMetricsCollector implements MetricsCollector {
+ static getMainThreadMetrics(processes: OpsProcessMetrics[]): undefined | OpsProcessMetrics {
+ return processes.find(({ name }) => name === 'server_worker');
+ }
+
+ private readonly eventLoopDelayMonitor = new EventLoopDelaysMonitor();
+
+ private getCurrentPidMetrics(): OpsProcessMetrics {
+ const eventLoopDelayHistogram = this.eventLoopDelayMonitor.collect();
const heapStats = v8.getHeapStatistics();
const memoryUsage = process.memoryUsage();
- const [eventLoopDelay] = await Promise.all([getEventLoopDelay()]);
+
return {
+ name: 'server_worker' as const,
memory: {
heap: {
total_in_bytes: memoryUsage.heapTotal,
@@ -25,19 +33,17 @@ export class ProcessMetricsCollector implements MetricsCollector => {
- const bench = new Bench();
- return new Promise((resolve) => {
- setImmediate(() => {
- return resolve(bench.elapsed());
- });
- });
-};
+ public reset() {
+ this.eventLoopDelayMonitor.reset();
+ }
+}
diff --git a/src/core/server/metrics/collectors/types.ts b/src/core/server/metrics/collectors/types.ts
index ec9746aaae769..597b5cafccd1e 100644
--- a/src/core/server/metrics/collectors/types.ts
+++ b/src/core/server/metrics/collectors/types.ts
@@ -5,11 +5,12 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
+import type { IntervalHistogram } from '../event_loop_delays';
/** Base interface for all metrics gatherers */
export interface MetricsCollector {
/** collect the data currently gathered by the collector */
- collect(): Promise;
+ collect(): Promise | T;
/** reset the internal state of the collector */
reset(): void;
}
@@ -19,6 +20,10 @@ export interface MetricsCollector {
* @public
*/
export interface OpsProcessMetrics {
+ /** pid of the kibana process */
+ pid: number;
+ /** name of process (example: 'coordinator' | 'server_worker' | 'task_worker' | 'reporting_worker') */
+ name: 'coordinator' | 'server_worker';
/** process memory usage */
memory: {
/** heap memory usage */
@@ -33,10 +38,10 @@ export interface OpsProcessMetrics {
/** node rss */
resident_set_size_in_bytes: number;
};
- /** node event loop delay */
+ /** mean event loop delay since last collection*/
event_loop_delay: number;
- /** pid of the kibana process */
- pid: number;
+ /** node event loop delay histogram since last collection */
+ event_loop_delay_histogram: IntervalHistogram;
/** uptime of the kibana process */
uptime_in_millis: number;
}
diff --git a/src/core/server/metrics/event_loop_delays/__mocks__/perf_hooks.ts b/src/core/server/metrics/event_loop_delays/__mocks__/perf_hooks.ts
new file mode 100644
index 0000000000000..7ebc926713617
--- /dev/null
+++ b/src/core/server/metrics/event_loop_delays/__mocks__/perf_hooks.ts
@@ -0,0 +1,21 @@
+/*
+ * 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 { mocked } from '../event_loop_delays_monitor.mocks';
+
+export const mockMonitor = {
+ enable: jest.fn(),
+ percentile: jest.fn(),
+ disable: jest.fn(),
+ reset: jest.fn(),
+};
+
+export const monitorEventLoopDelay = jest.fn().mockReturnValue({
+ ...mockMonitor,
+ ...mocked.createHistogram(),
+});
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.mocks.ts b/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.mocks.ts
similarity index 61%
rename from src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.mocks.ts
rename to src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.mocks.ts
index f266a27a7034f..66daf8fce3f5b 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.mocks.ts
+++ b/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.mocks.ts
@@ -6,23 +6,8 @@
* Side Public License, v 1.
*/
import moment from 'moment';
-import type { IntervalHistogram } from './event_loop_delays';
-
-export const mockMonitorEnable = jest.fn();
-export const mockMonitorPercentile = jest.fn();
-export const mockMonitorReset = jest.fn();
-export const mockMonitorDisable = jest.fn();
-export const monitorEventLoopDelay = jest.fn().mockReturnValue({
- enable: mockMonitorEnable,
- percentile: mockMonitorPercentile,
- disable: mockMonitorDisable,
- reset: mockMonitorReset,
- ...createMockHistogram(),
-});
-
-jest.doMock('perf_hooks', () => ({
- monitorEventLoopDelay,
-}));
+import type { IntervalHistogram } from 'kibana/server';
+import type { EventLoopDelaysMonitor } from './event_loop_delays_monitor';
function createMockHistogram(overwrites: Partial = {}): IntervalHistogram {
const now = moment();
@@ -45,6 +30,22 @@ function createMockHistogram(overwrites: Partial = {}): Inter
};
}
+function createMockEventLoopDelaysMonitor() {
+ const mockCollect = jest.fn();
+ const MockEventLoopDelaysMonitor: jest.MockedClass<
+ typeof EventLoopDelaysMonitor
+ > = jest.fn().mockReturnValue({
+ collect: mockCollect,
+ reset: jest.fn(),
+ stop: jest.fn(),
+ });
+
+ mockCollect.mockReturnValue(createMockHistogram());
+
+ return new MockEventLoopDelaysMonitor();
+}
+
export const mocked = {
createHistogram: createMockHistogram,
+ createEventLoopDelaysMonitor: createMockEventLoopDelaysMonitor,
};
diff --git a/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.test.ts b/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.test.ts
new file mode 100644
index 0000000000000..fbb1fbba617a6
--- /dev/null
+++ b/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.test.ts
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/* eslint-disable dot-notation */
+jest.mock('perf_hooks');
+import { monitorEventLoopDelay } from 'perf_hooks';
+import { EventLoopDelaysMonitor } from './event_loop_delays_monitor';
+
+describe('EventLoopDelaysMonitor', () => {
+ beforeAll(() => {
+ jest.useFakeTimers('modern');
+ const mockNow = jest.getRealSystemTime();
+ jest.setSystemTime(mockNow);
+ });
+ afterEach(() => jest.clearAllMocks());
+ afterAll(() => jest.useRealTimers());
+
+ test('#constructor enables monitoring', () => {
+ const eventLoopDelaysMonitor = new EventLoopDelaysMonitor();
+ expect(monitorEventLoopDelay).toBeCalledTimes(1);
+ expect(eventLoopDelaysMonitor['loopMonitor'].enable).toBeCalledTimes(1);
+ });
+
+ test('#collect returns event loop delays histogram', () => {
+ const eventLoopDelaysMonitor = new EventLoopDelaysMonitor();
+ expect(eventLoopDelaysMonitor['loopMonitor'].disable).toBeCalledTimes(0);
+ expect(eventLoopDelaysMonitor['loopMonitor'].enable).toBeCalledTimes(1);
+ const histogramData = eventLoopDelaysMonitor.collect();
+ expect(eventLoopDelaysMonitor['loopMonitor'].disable).toBeCalledTimes(1);
+ expect(eventLoopDelaysMonitor['loopMonitor'].enable).toBeCalledTimes(2);
+ expect(eventLoopDelaysMonitor['loopMonitor'].percentile).toHaveBeenNthCalledWith(1, 50);
+ expect(eventLoopDelaysMonitor['loopMonitor'].percentile).toHaveBeenNthCalledWith(2, 75);
+ expect(eventLoopDelaysMonitor['loopMonitor'].percentile).toHaveBeenNthCalledWith(3, 95);
+ expect(eventLoopDelaysMonitor['loopMonitor'].percentile).toHaveBeenNthCalledWith(4, 99);
+
+ expect(Object.keys(histogramData)).toMatchInlineSnapshot(`
+ Array [
+ "min",
+ "max",
+ "mean",
+ "exceeds",
+ "stddev",
+ "fromTimestamp",
+ "lastUpdatedAt",
+ "percentiles",
+ ]
+ `);
+ });
+ test('#reset resets histogram data', () => {
+ const eventLoopDelaysMonitor = new EventLoopDelaysMonitor();
+ eventLoopDelaysMonitor.reset();
+ expect(eventLoopDelaysMonitor['loopMonitor'].reset).toBeCalledTimes(1);
+ });
+ test('#stop disables monitoring event loop delays', () => {
+ const eventLoopDelaysMonitor = new EventLoopDelaysMonitor();
+ expect(eventLoopDelaysMonitor['loopMonitor'].disable).toBeCalledTimes(0);
+ eventLoopDelaysMonitor.stop();
+ expect(eventLoopDelaysMonitor['loopMonitor'].disable).toBeCalledTimes(1);
+ });
+});
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.ts b/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.ts
similarity index 83%
rename from src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.ts
rename to src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.ts
index f5de44a061d5a..cf8f9e780e48f 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.ts
+++ b/src/core/server/metrics/event_loop_delays/event_loop_delays_monitor.ts
@@ -8,7 +8,6 @@
import type { EventLoopDelayMonitor } from 'perf_hooks';
import { monitorEventLoopDelay } from 'perf_hooks';
-import { MONITOR_EVENT_LOOP_DELAYS_RESOLUTION } from './constants';
export interface IntervalHistogram {
fromTimestamp: string;
@@ -26,30 +25,30 @@ export interface IntervalHistogram {
};
}
-export class EventLoopDelaysCollector {
+export class EventLoopDelaysMonitor {
private readonly loopMonitor: EventLoopDelayMonitor;
private fromTimestamp: Date;
constructor() {
- const monitor = monitorEventLoopDelay({
- resolution: MONITOR_EVENT_LOOP_DELAYS_RESOLUTION,
- });
+ const monitor = monitorEventLoopDelay();
monitor.enable();
this.fromTimestamp = new Date();
this.loopMonitor = monitor;
}
public collect(): IntervalHistogram {
+ const lastUpdated = new Date();
+ this.loopMonitor.disable();
const { min, max, mean, exceeds, stddev } = this.loopMonitor;
- return {
+ const collectedData: IntervalHistogram = {
min,
max,
mean,
exceeds,
stddev,
fromTimestamp: this.fromTimestamp.toISOString(),
- lastUpdatedAt: new Date().toISOString(),
+ lastUpdatedAt: lastUpdated.toISOString(),
percentiles: {
50: this.loopMonitor.percentile(50),
75: this.loopMonitor.percentile(75),
@@ -57,6 +56,9 @@ export class EventLoopDelaysCollector {
99: this.loopMonitor.percentile(99),
},
};
+
+ this.loopMonitor.enable();
+ return collectedData;
}
public reset() {
diff --git a/src/core/server/metrics/event_loop_delays/index.ts b/src/core/server/metrics/event_loop_delays/index.ts
new file mode 100644
index 0000000000000..50d2e35e388e3
--- /dev/null
+++ b/src/core/server/metrics/event_loop_delays/index.ts
@@ -0,0 +1,10 @@
+/*
+ * 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.
+ */
+
+export { EventLoopDelaysMonitor } from './event_loop_delays_monitor';
+export type { IntervalHistogram } from './event_loop_delays_monitor';
diff --git a/src/core/server/metrics/index.ts b/src/core/server/metrics/index.ts
index 0631bb2b35801..63e475a25918d 100644
--- a/src/core/server/metrics/index.ts
+++ b/src/core/server/metrics/index.ts
@@ -17,3 +17,5 @@ export type { OpsProcessMetrics, OpsServerMetrics, OpsOsMetrics } from './collec
export { MetricsService } from './metrics_service';
export { opsConfig } from './ops_config';
export type { OpsConfigType } from './ops_config';
+export { EventLoopDelaysMonitor } from './event_loop_delays';
+export type { IntervalHistogram } from './event_loop_delays';
diff --git a/src/core/server/metrics/logging/get_ops_metrics_log.test.ts b/src/core/server/metrics/logging/get_ops_metrics_log.test.ts
index e535b9babf92b..2d7a6bebf255e 100644
--- a/src/core/server/metrics/logging/get_ops_metrics_log.test.ts
+++ b/src/core/server/metrics/logging/get_ops_metrics_log.test.ts
@@ -8,19 +8,15 @@
import { OpsMetrics } from '..';
import { getEcsOpsMetricsLog } from './get_ops_metrics_log';
+import { collectorMock } from '../collectors/mocks';
function createBaseOpsMetrics(): OpsMetrics {
+ const mockProcess = collectorMock.createOpsProcessMetrics();
+
return {
collected_at: new Date('2020-01-01 01:00:00'),
- process: {
- memory: {
- heap: { total_in_bytes: 1, used_in_bytes: 1, size_limit: 1 },
- resident_set_size_in_bytes: 1,
- },
- event_loop_delay: 1,
- pid: 1,
- uptime_in_millis: 1,
- },
+ process: mockProcess,
+ processes: [mockProcess],
os: {
platform: 'darwin' as const,
platformRelease: 'test',
diff --git a/src/core/server/metrics/metrics_service.mock.ts b/src/core/server/metrics/metrics_service.mock.ts
index b023824df64d3..5c41e78d8efcb 100644
--- a/src/core/server/metrics/metrics_service.mock.ts
+++ b/src/core/server/metrics/metrics_service.mock.ts
@@ -8,8 +8,9 @@
import { BehaviorSubject } from 'rxjs';
import type { PublicMethodsOf } from '@kbn/utility-types';
-
import type { MetricsService } from './metrics_service';
+import { collectorMock } from './collectors/mocks';
+import { mocked as eventLoopDelaysMonitorMock } from './event_loop_delays/event_loop_delays_monitor.mocks';
import {
InternalMetricsServiceSetup,
InternalMetricsServiceStart,
@@ -22,18 +23,14 @@ const createInternalSetupContractMock = () => {
collectionInterval: 30000,
getOpsMetrics$: jest.fn(),
};
+
+ const processMock = collectorMock.createOpsProcessMetrics();
+
setupContract.getOpsMetrics$.mockReturnValue(
new BehaviorSubject({
collected_at: new Date('2020-01-01 01:00:00'),
- process: {
- memory: {
- heap: { total_in_bytes: 1, used_in_bytes: 1, size_limit: 1 },
- resident_set_size_in_bytes: 1,
- },
- event_loop_delay: 1,
- pid: 1,
- uptime_in_millis: 1,
- },
+ process: processMock,
+ processes: [processMock],
os: {
platform: 'darwin' as const,
platformRelease: 'test',
@@ -81,4 +78,5 @@ export const metricsServiceMock = {
createStartContract: createStartContractMock,
createInternalSetupContract: createInternalSetupContractMock,
createInternalStartContract: createInternalStartContractMock,
+ createEventLoopDelaysMonitor: eventLoopDelaysMonitorMock.createEventLoopDelaysMonitor,
};
diff --git a/src/core/server/metrics/ops_metrics_collector.test.ts b/src/core/server/metrics/ops_metrics_collector.test.ts
index 3faa771db1dae..7d263d8b7d6af 100644
--- a/src/core/server/metrics/ops_metrics_collector.test.ts
+++ b/src/core/server/metrics/ops_metrics_collector.test.ts
@@ -28,7 +28,7 @@ describe('OpsMetricsCollector', () => {
describe('#collect', () => {
it('gathers metrics from the underlying collectors', async () => {
mockOsCollector.collect.mockResolvedValue('osMetrics');
- mockProcessCollector.collect.mockResolvedValue('processMetrics');
+ mockProcessCollector.collect.mockResolvedValue(['processMetrics']);
mockServerCollector.collect.mockResolvedValue({
requests: 'serverRequestsMetrics',
response_times: 'serverTimingMetrics',
@@ -43,6 +43,7 @@ describe('OpsMetricsCollector', () => {
expect(metrics).toEqual({
collected_at: expect.any(Date),
process: 'processMetrics',
+ processes: ['processMetrics'],
os: 'osMetrics',
requests: 'serverRequestsMetrics',
response_times: 'serverTimingMetrics',
diff --git a/src/core/server/metrics/ops_metrics_collector.ts b/src/core/server/metrics/ops_metrics_collector.ts
index 74e8b8246d83c..98f78e4b12180 100644
--- a/src/core/server/metrics/ops_metrics_collector.ts
+++ b/src/core/server/metrics/ops_metrics_collector.ts
@@ -28,14 +28,16 @@ export class OpsMetricsCollector implements MetricsCollector {
}
public async collect(): Promise {
- const [process, os, server] = await Promise.all([
+ const [processes, os, server] = await Promise.all([
this.processCollector.collect(),
this.osCollector.collect(),
this.serverCollector.collect(),
]);
+
return {
collected_at: new Date(),
- process,
+ process: processes[0],
+ processes,
os,
...server,
};
diff --git a/src/core/server/metrics/types.ts b/src/core/server/metrics/types.ts
index d70b8c9ff4208..8beeae2ff7adf 100644
--- a/src/core/server/metrics/types.ts
+++ b/src/core/server/metrics/types.ts
@@ -7,7 +7,7 @@
*/
import { Observable } from 'rxjs';
-import { OpsProcessMetrics, OpsOsMetrics, OpsServerMetrics } from './collectors';
+import type { OpsProcessMetrics, OpsOsMetrics, OpsServerMetrics } from './collectors';
/**
* APIs to retrieves metrics gathered and exposed by the core platform.
@@ -51,8 +51,13 @@ export type InternalMetricsServiceStart = MetricsServiceStart;
export interface OpsMetrics {
/** Time metrics were recorded at. */
collected_at: Date;
- /** Process related metrics */
+ /**
+ * Process related metrics. Deprecated in favor of processes field.
+ * @deprecated
+ */
process: OpsProcessMetrics;
+ /** Process related metrics. Reports an array of objects for each kibana pid.*/
+ processes: OpsProcessMetrics[];
/** OS related metrics */
os: OpsOsMetrics;
/** server response time stats */
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index 67b08f4c0d9b7..248e115cddcb4 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -883,6 +883,19 @@ export interface ErrorHttpResponseOptions {
headers?: ResponseHeaders;
}
+// Warning: (ae-missing-release-tag) "EventLoopDelaysMonitor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export class EventLoopDelaysMonitor {
+ constructor();
+ // (undocumented)
+ collect(): IntervalHistogram;
+ // (undocumented)
+ reset(): void;
+ // (undocumented)
+ stop(): void;
+}
+
// @public (undocumented)
export interface ExecutionContextSetup {
withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R;
@@ -1116,6 +1129,33 @@ export interface IKibanaSocket {
}): Promise;
}
+// Warning: (ae-missing-release-tag) "IntervalHistogram" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export interface IntervalHistogram {
+ // (undocumented)
+ exceeds: number;
+ // (undocumented)
+ fromTimestamp: string;
+ // (undocumented)
+ lastUpdatedAt: string;
+ // (undocumented)
+ max: number;
+ // (undocumented)
+ mean: number;
+ // (undocumented)
+ min: number;
+ // (undocumented)
+ percentiles: {
+ 50: number;
+ 75: number;
+ 95: number;
+ 99: number;
+ };
+ // (undocumented)
+ stddev: number;
+}
+
// @public (undocumented)
export interface IRenderOptions {
includeUserSettings?: boolean;
@@ -1401,7 +1441,9 @@ export interface OpsMetrics {
collected_at: Date;
concurrent_connections: OpsServerMetrics['concurrent_connections'];
os: OpsOsMetrics;
+ // @deprecated
process: OpsProcessMetrics;
+ processes: OpsProcessMetrics[];
requests: OpsServerMetrics['requests'];
response_times: OpsServerMetrics['response_times'];
}
@@ -1442,6 +1484,7 @@ export interface OpsOsMetrics {
// @public
export interface OpsProcessMetrics {
event_loop_delay: number;
+ event_loop_delay_histogram: IntervalHistogram;
memory: {
heap: {
total_in_bytes: number;
@@ -1450,6 +1493,7 @@ export interface OpsProcessMetrics {
};
resident_set_size_in_bytes: number;
};
+ name: 'coordinator' | 'server_worker';
pid: number;
uptime_in_millis: number;
}
diff --git a/src/core/server/status/routes/status.ts b/src/core/server/status/routes/status.ts
index 43a596bd1e0ec..df0300c9fa0c2 100644
--- a/src/core/server/status/routes/status.ts
+++ b/src/core/server/status/routes/status.ts
@@ -106,6 +106,7 @@ export const registerStatusRoute = ({ router, config, metrics, status }: Deps) =
collection_interval_in_millis: metrics.collectionInterval,
os: lastMetrics.os,
process: lastMetrics.process,
+ processes: lastMetrics.processes,
response_times: lastMetrics.response_times,
concurrent_connections: lastMetrics.concurrent_connections,
requests: {
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/constants.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/constants.ts
index d6201deff5fec..4661441a15a6b 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/constants.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/constants.ts
@@ -31,11 +31,6 @@ export const MONITOR_EVENT_LOOP_DELAYS_RESET = 24 * 60 * 60 * 1000;
*/
export const MONITOR_EVENT_LOOP_DELAYS_START = 1 * 60 * 1000;
-/**
- * Event loop monitoring sampling rate in milliseconds.
- */
-export const MONITOR_EVENT_LOOP_DELAYS_RESOLUTION = 10;
-
/**
* Mean event loop delay threshold for logging a warning.
*/
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.test.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.test.ts
deleted file mode 100644
index b40030e210176..0000000000000
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/event_loop_delays.test.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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 {
- mockMonitorEnable,
- mockMonitorPercentile,
- monitorEventLoopDelay,
- mockMonitorReset,
- mockMonitorDisable,
-} from './event_loop_delays.mocks';
-import { EventLoopDelaysCollector } from './event_loop_delays';
-
-describe('EventLoopDelaysCollector', () => {
- jest.useFakeTimers('modern');
- const mockNow = jest.getRealSystemTime();
- jest.setSystemTime(mockNow);
-
- beforeEach(() => jest.clearAllMocks());
- afterAll(() => jest.useRealTimers());
-
- test('#constructor enables monitoring', () => {
- new EventLoopDelaysCollector();
- expect(monitorEventLoopDelay).toBeCalledWith({ resolution: 10 });
- expect(mockMonitorEnable).toBeCalledTimes(1);
- });
-
- test('#collect returns event loop delays histogram', () => {
- const eventLoopDelaysCollector = new EventLoopDelaysCollector();
- const histogramData = eventLoopDelaysCollector.collect();
- expect(mockMonitorPercentile).toHaveBeenNthCalledWith(1, 50);
- expect(mockMonitorPercentile).toHaveBeenNthCalledWith(2, 75);
- expect(mockMonitorPercentile).toHaveBeenNthCalledWith(3, 95);
- expect(mockMonitorPercentile).toHaveBeenNthCalledWith(4, 99);
-
- expect(Object.keys(histogramData)).toMatchInlineSnapshot(`
- Array [
- "min",
- "max",
- "mean",
- "exceeds",
- "stddev",
- "fromTimestamp",
- "lastUpdatedAt",
- "percentiles",
- ]
- `);
- });
- test('#reset resets histogram data', () => {
- const eventLoopDelaysCollector = new EventLoopDelaysCollector();
- eventLoopDelaysCollector.reset();
- expect(mockMonitorReset).toBeCalledTimes(1);
- });
- test('#stop disables monitoring event loop delays', () => {
- const eventLoopDelaysCollector = new EventLoopDelaysCollector();
- eventLoopDelaysCollector.stop();
- expect(mockMonitorDisable).toBeCalledTimes(1);
- });
-});
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts
index 94840ccfc2748..499227d796f1e 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/rollups/integration_tests/daily_rollups.test.ts
@@ -14,7 +14,7 @@ import {
createRootWithCorePlugins,
} from '../../../../../../../core/test_helpers/kbn_server';
import { rollDailyData } from '../daily';
-import { mocked } from '../../event_loop_delays.mocks';
+import { metricsServiceMock } from '../../../../../../../core/server/mocks';
import {
SAVED_OBJECTS_DAILY_TYPE,
@@ -26,17 +26,16 @@ import moment from 'moment';
const { startES } = createTestServers({
adjustTimeout: (t: number) => jest.setTimeout(t),
});
-
+const eventLoopDelaysMonitor = metricsServiceMock.createEventLoopDelaysMonitor();
function createRawObject(date: moment.MomentInput) {
const pid = Math.round(Math.random() * 10000);
return {
type: SAVED_OBJECTS_DAILY_TYPE,
id: serializeSavedObjectId({ pid, date }),
attributes: {
- ...mocked.createHistogram({
- fromTimestamp: moment(date).startOf('day').toISOString(),
- lastUpdatedAt: moment(date).toISOString(),
- }),
+ ...eventLoopDelaysMonitor.collect(),
+ fromTimestamp: moment(date).startOf('day').toISOString(),
+ lastUpdatedAt: moment(date).toISOString(),
processId: pid,
},
};
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.test.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.test.ts
index 022040615bd45..ee610d918d61c 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.test.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.test.ts
@@ -11,9 +11,8 @@ import {
serializeSavedObjectId,
deleteHistogramSavedObjects,
} from './saved_objects';
-import { savedObjectsRepositoryMock } from '../../../../../core/server/mocks';
+import { savedObjectsRepositoryMock, metricsServiceMock } from '../../../../../core/server/mocks';
import type { SavedObjectsFindResponse } from '../../../../../core/server/';
-import { mocked } from './event_loop_delays.mocks';
describe('serializeSavedObjectId', () => {
it('returns serialized id', () => {
@@ -23,9 +22,8 @@ describe('serializeSavedObjectId', () => {
});
describe('storeHistogram', () => {
- const mockHistogram = mocked.createHistogram();
+ const eventLoopDelaysMonitor = metricsServiceMock.createEventLoopDelaysMonitor();
const mockInternalRepository = savedObjectsRepositoryMock.create();
-
jest.useFakeTimers('modern');
const mockNow = jest.getRealSystemTime();
jest.setSystemTime(mockNow);
@@ -34,6 +32,7 @@ describe('storeHistogram', () => {
afterAll(() => jest.useRealTimers());
it('stores histogram data in a savedObject', async () => {
+ const mockHistogram = eventLoopDelaysMonitor.collect();
await storeHistogram(mockHistogram, mockInternalRepository);
const pid = process.pid;
const id = serializeSavedObjectId({ date: mockNow, pid });
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.ts
index 610a6697da364..b66451d1fb764 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/saved_objects.ts
@@ -12,8 +12,7 @@ import type {
ISavedObjectsRepository,
} from 'kibana/server';
import moment from 'moment';
-import type { IntervalHistogram } from './event_loop_delays';
-
+import type { IntervalHistogram } from 'kibana/server';
export const SAVED_OBJECTS_DAILY_TYPE = 'event_loop_delays_daily';
export interface EventLoopDelaysDaily extends SavedObjectAttributes, IntervalHistogram {
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.test.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.test.ts
index e0d8c20ead75a..ea8309cff31e7 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.test.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.test.ts
@@ -7,43 +7,45 @@
*/
import { Subject } from 'rxjs';
-
-import {
- mockMonitorPercentile,
- monitorEventLoopDelay,
- mockMonitorReset,
- mockMonitorDisable,
-} from './event_loop_delays.mocks';
-import { savedObjectsRepositoryMock } from '../../../../../core/server/mocks';
+import { savedObjectsRepositoryMock, metricsServiceMock } from '../../../../../core/server/mocks';
import { startTrackingEventLoopDelaysUsage } from './track_delays';
describe('startTrackingEventLoopDelaysUsage', () => {
+ const eventLoopDelaysMonitor = metricsServiceMock.createEventLoopDelaysMonitor();
const mockInternalRepository = savedObjectsRepositoryMock.create();
const stopMonitoringEventLoop$ = new Subject();
-
beforeAll(() => jest.useFakeTimers('modern'));
beforeEach(() => jest.clearAllMocks());
afterEach(() => stopMonitoringEventLoop$.next());
- it('initializes EventLoopDelaysCollector and starts timer', () => {
+ it('collects eventLoopDelaysMonitor metrics after start delay', () => {
const collectionStartDelay = 1000;
- startTrackingEventLoopDelaysUsage(mockInternalRepository, stopMonitoringEventLoop$, {
- collectionStartDelay,
- });
+ startTrackingEventLoopDelaysUsage(
+ mockInternalRepository,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor,
+ {
+ collectionStartDelay,
+ }
+ );
- expect(monitorEventLoopDelay).toBeCalledTimes(1);
- expect(mockMonitorPercentile).toBeCalledTimes(0);
+ expect(eventLoopDelaysMonitor.collect).toBeCalledTimes(0);
jest.advanceTimersByTime(collectionStartDelay);
- expect(mockMonitorPercentile).toBeCalled();
+ expect(eventLoopDelaysMonitor.collect).toBeCalledTimes(1);
});
it('stores event loop delays every collectionInterval duration', () => {
const collectionStartDelay = 100;
const collectionInterval = 1000;
- startTrackingEventLoopDelaysUsage(mockInternalRepository, stopMonitoringEventLoop$, {
- collectionStartDelay,
- collectionInterval,
- });
+ startTrackingEventLoopDelaysUsage(
+ mockInternalRepository,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor,
+ {
+ collectionStartDelay,
+ collectionInterval,
+ }
+ );
expect(mockInternalRepository.create).toBeCalledTimes(0);
jest.advanceTimersByTime(collectionStartDelay);
@@ -54,28 +56,36 @@ describe('startTrackingEventLoopDelaysUsage', () => {
expect(mockInternalRepository.create).toBeCalledTimes(3);
});
- it('resets histogram every histogramReset duration', () => {
+ it('resets eventLoopDelaysMonitor every histogramReset duration', () => {
const collectionStartDelay = 0;
const collectionInterval = 1000;
const histogramReset = 5000;
- startTrackingEventLoopDelaysUsage(mockInternalRepository, stopMonitoringEventLoop$, {
- collectionStartDelay,
- collectionInterval,
- histogramReset,
- });
+ startTrackingEventLoopDelaysUsage(
+ mockInternalRepository,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor,
+ {
+ collectionStartDelay,
+ collectionInterval,
+ histogramReset,
+ }
+ );
- expect(mockMonitorReset).toBeCalledTimes(0);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(0);
jest.advanceTimersByTime(collectionInterval * 5);
- expect(mockMonitorReset).toBeCalledTimes(1);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(1);
jest.advanceTimersByTime(collectionInterval * 5);
- expect(mockMonitorReset).toBeCalledTimes(2);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(2);
});
it('stops monitoring event loop delays once stopMonitoringEventLoop$.next is called', () => {
- startTrackingEventLoopDelaysUsage(mockInternalRepository, stopMonitoringEventLoop$);
-
- expect(mockMonitorDisable).toBeCalledTimes(0);
+ startTrackingEventLoopDelaysUsage(
+ mockInternalRepository,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor
+ );
+ expect(eventLoopDelaysMonitor.stop).toBeCalledTimes(0);
stopMonitoringEventLoop$.next();
- expect(mockMonitorDisable).toBeCalledTimes(1);
+ expect(eventLoopDelaysMonitor.stop).toBeCalledTimes(1);
});
});
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.ts
index 70638d3b07cbc..d5006c801bddd 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_delays.ts
@@ -9,13 +9,13 @@
import { takeUntil, finalize, map } from 'rxjs/operators';
import { Observable, timer } from 'rxjs';
import type { ISavedObjectsRepository } from 'kibana/server';
+import type { EventLoopDelaysMonitor } from '../../../../../core/server';
import {
MONITOR_EVENT_LOOP_DELAYS_START,
MONITOR_EVENT_LOOP_DELAYS_INTERVAL,
MONITOR_EVENT_LOOP_DELAYS_RESET,
} from './constants';
import { storeHistogram } from './saved_objects';
-import { EventLoopDelaysCollector } from './event_loop_delays';
/**
* The monitoring of the event loop starts immediately.
@@ -25,6 +25,7 @@ import { EventLoopDelaysCollector } from './event_loop_delays';
export function startTrackingEventLoopDelaysUsage(
internalRepository: ISavedObjectsRepository,
stopMonitoringEventLoop$: Observable,
+ eventLoopDelaysMonitor: EventLoopDelaysMonitor,
configs: {
collectionStartDelay?: number;
collectionInterval?: number;
@@ -37,19 +38,18 @@ export function startTrackingEventLoopDelaysUsage(
histogramReset = MONITOR_EVENT_LOOP_DELAYS_RESET,
} = configs;
- const eventLoopDelaysCollector = new EventLoopDelaysCollector();
const resetOnCount = Math.ceil(histogramReset / collectionInterval);
timer(collectionStartDelay, collectionInterval)
.pipe(
map((i) => (i + 1) % resetOnCount === 0),
takeUntil(stopMonitoringEventLoop$),
- finalize(() => eventLoopDelaysCollector.stop())
+ finalize(() => eventLoopDelaysMonitor.stop())
)
.subscribe(async (shouldReset) => {
- const histogram = eventLoopDelaysCollector.collect();
+ const histogram = eventLoopDelaysMonitor.collect();
if (shouldReset) {
- eventLoopDelaysCollector.reset();
+ eventLoopDelaysMonitor.reset();
}
await storeHistogram(histogram, internalRepository);
});
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.test.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.test.ts
index 1ff49a735a775..49b1943033719 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.test.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.test.ts
@@ -7,13 +7,8 @@
*/
import { Subject } from 'rxjs';
-import {
- mockMonitorPercentile,
- monitorEventLoopDelay,
- mockMonitorReset,
-} from './event_loop_delays.mocks';
+import { loggingSystemMock, metricsServiceMock } from '../../../../../core/server/mocks';
import { startTrackingEventLoopDelaysThreshold } from './track_threshold';
-import { loggingSystemMock } from '../../../../../core/server/mocks';
import { usageCountersServiceMock } from '../../../../usage_collection/server/usage_counters/usage_counters_service.mock';
describe('startTrackingEventLoopDelaysThreshold', () => {
@@ -21,6 +16,7 @@ describe('startTrackingEventLoopDelaysThreshold', () => {
const stopMonitoringEventLoop$ = new Subject();
const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract();
const mockEventLoopCounter = mockUsageCountersSetup.createUsageCounter('testCounter');
+ const eventLoopDelaysMonitor = metricsServiceMock.createEventLoopDelaysMonitor();
beforeAll(() => jest.useFakeTimers('modern'));
beforeEach(() => jest.clearAllMocks());
@@ -29,15 +25,20 @@ describe('startTrackingEventLoopDelaysThreshold', () => {
it('initializes EventLoopDelaysCollector and starts timer', () => {
const collectionStartDelay = 1000;
const warnThreshold = 1000;
- startTrackingEventLoopDelaysThreshold(mockEventLoopCounter, logger, stopMonitoringEventLoop$, {
- warnThreshold,
- collectionStartDelay,
- });
+ startTrackingEventLoopDelaysThreshold(
+ mockEventLoopCounter,
+ logger,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor,
+ {
+ warnThreshold,
+ collectionStartDelay,
+ }
+ );
- expect(monitorEventLoopDelay).toBeCalledTimes(1);
- expect(mockMonitorPercentile).toBeCalledTimes(0);
+ expect(eventLoopDelaysMonitor.collect).toBeCalledTimes(0);
jest.advanceTimersByTime(collectionStartDelay);
- expect(mockMonitorPercentile).toBeCalled();
+ expect(eventLoopDelaysMonitor.collect).toBeCalledTimes(1);
});
it('logs a warning and increments usage counter when the mean delay exceeds the threshold', () => {
@@ -45,48 +46,60 @@ describe('startTrackingEventLoopDelaysThreshold', () => {
const collectionInterval = 1000;
const warnThreshold = 10;
- startTrackingEventLoopDelaysThreshold(mockEventLoopCounter, logger, stopMonitoringEventLoop$, {
- warnThreshold,
- collectionStartDelay,
- collectionInterval,
- });
+ startTrackingEventLoopDelaysThreshold(
+ mockEventLoopCounter,
+ logger,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor,
+ {
+ warnThreshold,
+ collectionStartDelay,
+ collectionInterval,
+ }
+ );
expect(logger.warn).toBeCalledTimes(0);
expect(mockEventLoopCounter.incrementCounter).toBeCalledTimes(0);
- expect(mockMonitorReset).toBeCalledTimes(0);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(0);
jest.advanceTimersByTime(collectionStartDelay);
expect(logger.warn).toBeCalledTimes(1);
expect(mockEventLoopCounter.incrementCounter).toBeCalledTimes(1);
- expect(mockMonitorReset).toBeCalledTimes(1);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(1);
jest.advanceTimersByTime(collectionInterval);
expect(logger.warn).toBeCalledTimes(2);
expect(mockEventLoopCounter.incrementCounter).toBeCalledTimes(2);
- expect(mockMonitorReset).toBeCalledTimes(2);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(2);
jest.advanceTimersByTime(collectionInterval);
expect(mockEventLoopCounter.incrementCounter).toBeCalledTimes(3);
expect(logger.warn).toBeCalledTimes(3);
- expect(mockMonitorReset).toBeCalledTimes(3);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(3);
});
it('does not log warning or increment usage if threshold did not exceed mean delay', () => {
const collectionStartDelay = 100;
const warnThreshold = 15;
- startTrackingEventLoopDelaysThreshold(mockEventLoopCounter, logger, stopMonitoringEventLoop$, {
- warnThreshold,
- collectionStartDelay,
- });
+ startTrackingEventLoopDelaysThreshold(
+ mockEventLoopCounter,
+ logger,
+ stopMonitoringEventLoop$,
+ eventLoopDelaysMonitor,
+ {
+ warnThreshold,
+ collectionStartDelay,
+ }
+ );
expect(logger.warn).toBeCalledTimes(0);
expect(mockEventLoopCounter.incrementCounter).toBeCalledTimes(0);
- expect(mockMonitorReset).toBeCalledTimes(0);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(0);
jest.advanceTimersByTime(collectionStartDelay);
expect(logger.warn).toBeCalledTimes(0);
expect(mockEventLoopCounter.incrementCounter).toBeCalledTimes(0);
- expect(mockMonitorReset).toBeCalledTimes(1);
+ expect(eventLoopDelaysMonitor.reset).toBeCalledTimes(1);
});
});
diff --git a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.ts b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.ts
index 246d88496a158..ba4e12a7bfced 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/event_loop_delays/track_threshold.ts
@@ -17,7 +17,7 @@ import {
MONITOR_EVENT_LOOP_WARN_THRESHOLD,
ONE_MILLISECOND_AS_NANOSECONDS,
} from './constants';
-import { EventLoopDelaysCollector } from './event_loop_delays';
+import type { EventLoopDelaysMonitor } from '../../../../../core/server';
/**
* The monitoring of the event loop starts immediately.
@@ -29,6 +29,7 @@ export function startTrackingEventLoopDelaysThreshold(
eventLoopCounter: UsageCounter,
logger: Logger,
stopMonitoringEventLoop$: Observable,
+ eventLoopDelaysMonitor: EventLoopDelaysMonitor,
configs: {
warnThreshold?: number;
collectionStartDelay?: number;
@@ -41,14 +42,13 @@ export function startTrackingEventLoopDelaysThreshold(
collectionInterval = MONITOR_EVENT_LOOP_THRESHOLD_INTERVAL,
} = configs;
- const eventLoopDelaysCollector = new EventLoopDelaysCollector();
timer(collectionStartDelay, collectionInterval)
.pipe(
takeUntil(stopMonitoringEventLoop$),
- finalize(() => eventLoopDelaysCollector.stop())
+ finalize(() => eventLoopDelaysMonitor.stop())
)
.subscribe(async () => {
- const { mean } = eventLoopDelaysCollector.collect();
+ const { mean } = eventLoopDelaysMonitor.collect();
const meanDurationMs = moment
.duration(mean / ONE_MILLISECOND_AS_NANOSECONDS)
.asMilliseconds();
@@ -64,6 +64,6 @@ export function startTrackingEventLoopDelaysThreshold(
});
}
- eventLoopDelaysCollector.reset();
+ eventLoopDelaysMonitor.reset();
});
}
diff --git a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/__snapshots__/index.test.ts.snap b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/__snapshots__/index.test.ts.snap
deleted file mode 100644
index 678237ffb6ea2..0000000000000
--- a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/__snapshots__/index.test.ts.snap
+++ /dev/null
@@ -1,43 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`telemetry_ops_stats should return something when there is a metric 1`] = `
-Object {
- "concurrent_connections": 20,
- "os": Object {
- "load": Object {
- "15m": 3,
- "1m": 0.5,
- "5m": 1,
- },
- "memory": Object {
- "free_in_bytes": 10,
- "total_in_bytes": 10,
- "used_in_bytes": 10,
- },
- "platform": "darwin",
- "platformRelease": "test",
- "uptime_in_millis": 1000,
- },
- "process": Object {
- "event_loop_delay": 10,
- "memory": Object {
- "heap": Object {
- "size_limit": 0,
- "total_in_bytes": 0,
- "used_in_bytes": 0,
- },
- "resident_set_size_in_bytes": 0,
- },
- "uptime_in_millis": 1000,
- },
- "requests": Object {
- "disconnects": 10,
- "total": 100,
- },
- "response_times": Object {
- "average": 100,
- "max": 200,
- },
- "timestamp": Any,
-}
-`;
diff --git a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/__snapshots__/ops_stats_collector.test.ts.snap b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/__snapshots__/ops_stats_collector.test.ts.snap
new file mode 100644
index 0000000000000..69176fef2f4a5
--- /dev/null
+++ b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/__snapshots__/ops_stats_collector.test.ts.snap
@@ -0,0 +1,61 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`telemetry_ops_stats should return something when there is a metric 1`] = `
+Object {
+ "concurrent_connections": 1,
+ "os": Object {
+ "load": Object {
+ "15m": 1,
+ "1m": 1,
+ "5m": 1,
+ },
+ "memory": Object {
+ "free_in_bytes": 1,
+ "total_in_bytes": 1,
+ "used_in_bytes": 1,
+ },
+ "platform": "darwin",
+ "platformRelease": "test",
+ "uptime_in_millis": 1,
+ },
+ "process": Object {
+ "event_loop_delay": 1,
+ "event_loop_delay_histogram": Any