Skip to content

Commit ca1e310

Browse files
dgieselaarkibanamachine
authored andcommitted
@kbn/cleanup-before-exit: Package to install cleanup handlers (elastic#238561)
Adds a package to install cleanup handlers. We have `Cleanup` in `@kbn/dev-cli-runner`, but it uses an outdated version of exit-hook which doesn't support async cleanup handlers. The newer version requires ESM support. Rather than installing another 3rd party lib, I've opted for creating an internal package, also to support blocking process.exit() calls. ## Why In certain scenarios, we'll want to flush data before the process exits. In some cases, such as when running Playwright, some code will call `process.exit` which doesn't allow for cleanup. This means we are not able to export all tracing data which breaks some of our debugging flows. ## How Listeners are added to process for SIGINT, SIGTERM and beforeExit. Additionally, process.exit is overridden. In all cases, registered cleanup handlers are immediately called and given time to complete, before either allowing the process to exit naturally, or calling process.exit(). ## Notes Tests and README were written with GPT-5 Codex. --------- Co-authored-by: kibanamachine <[email protected]>
1 parent c8c96b3 commit ca1e310

File tree

21 files changed

+431
-53
lines changed

21 files changed

+431
-53
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ src/platform/packages/shared/kbn-cbor @elastic/kibana-operations
454454
src/platform/packages/shared/kbn-cell-actions @elastic/security-threat-hunting-investigations
455455
src/platform/packages/shared/kbn-chart-icons @elastic/kibana-visualizations
456456
src/platform/packages/shared/kbn-charts-theme @elastic/kibana-visualizations
457+
src/platform/packages/shared/kbn-cleanup-before-exit @elastic/observability-ui
457458
src/platform/packages/shared/kbn-coloring @elastic/kibana-visualizations
458459
src/platform/packages/shared/kbn-config @elastic/kibana-core
459460
src/platform/packages/shared/kbn-config-schema @elastic/kibana-core

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@
229229
"@kbn/chart-icons": "link:src/platform/packages/shared/kbn-chart-icons",
230230
"@kbn/charts-plugin": "link:src/platform/plugins/shared/charts",
231231
"@kbn/charts-theme": "link:src/platform/packages/shared/kbn-charts-theme",
232+
"@kbn/cleanup-before-exit": "link:src/platform/packages/shared/kbn-cleanup-before-exit",
232233
"@kbn/cloud": "link:src/platform/packages/shared/cloud",
233234
"@kbn/cloud-chat-plugin": "link:x-pack/platform/plugins/private/cloud_integrations/cloud_chat",
234235
"@kbn/cloud-data-migration-plugin": "link:x-pack/platform/plugins/private/cloud_integrations/cloud_data_migration",

src/platform/packages/private/opentelemetry/kbn-metrics/kibana.jsonc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"type": "shared-common",
2+
"type": "shared-server",
33
"id": "@kbn/metrics",
44
"owner": [
55
"@elastic/kibana-core",

src/platform/packages/private/opentelemetry/kbn-metrics/src/init_metrics.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
import { castArray, once } from 'lodash';
10+
import { castArray } from 'lodash';
1111
import { Metadata } from '@grpc/grpc-js';
1212
import { OTLPMetricExporter as OTLPMetricExporterGrpc } from '@opentelemetry/exporter-metrics-otlp-grpc';
1313
import { OTLPMetricExporter as OTLPMetricExporterHttp } from '@opentelemetry/exporter-metrics-otlp-http';
1414
import type { resources } from '@elastic/opentelemetry-node/sdk';
1515
import { api, metrics } from '@elastic/opentelemetry-node/sdk';
1616
import type { MetricsConfig, MonitoringCollectionConfig } from '@kbn/metrics-config';
1717
import { fromExternalVariant } from '@kbn/std';
18+
import { cleanupBeforeExit } from '@kbn/cleanup-before-exit';
1819
import { PrometheusExporter } from './prometheus_exporter';
1920

2021
/**
@@ -132,9 +133,5 @@ export function initMetrics(initMetricsOptions: InitMetricsOptions) {
132133

133134
api.metrics.setGlobalMeterProvider(meterProvider);
134135

135-
const shutdown = once(() => meterProvider.shutdown());
136-
process.on('SIGTERM', shutdown);
137-
process.on('SIGINT', shutdown);
138-
process.on('beforeExit', shutdown);
139-
process.on('uncaughtExceptionMonitor', shutdown);
136+
cleanupBeforeExit(() => meterProvider.shutdown());
140137
}

src/platform/packages/private/opentelemetry/kbn-metrics/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
"@kbn/metrics-config",
1818
"@kbn/std",
1919
"@kbn/core-http-server",
20+
"@kbn/cleanup-before-exit",
2021
]
2122
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# @kbn/cleanup-before-exit
2+
3+
Utilities for registering asynchronous cleanup tasks that should run before a Node.js process exits.
4+
5+
## Usage
6+
7+
```ts
8+
import { cleanupBeforeExit } from '@kbn/cleanup-before-exit';
9+
10+
cleanupBeforeExit(
11+
async () => {
12+
await closeServices();
13+
},
14+
{ blockExit: true, timeout: 10_000 }
15+
);
16+
```
17+
18+
## Options
19+
20+
| Option | Default | Description |
21+
| ----------- | ------- | --------------------------------------------------------------------------------------------------------- |
22+
| `blockExit` | `false` | When `true`, overrides `process.exit` so the process waits for the handler to settle. |
23+
| `timeout` | `5000` | Milliseconds to wait before the handler is considered timed out; the timeout error is logged and ignored. |
24+
25+
Handlers are guaranteed to only run once, all run in parallel, and any rejections are logged via OpenTelemetry `diag`.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
export { cleanupBeforeExit } from './src/cleanup_before_exit';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
module.exports = {
11+
preset: '@kbn/test/jest_node',
12+
rootDir: '../../../../..',
13+
roots: ['<rootDir>/src/platform/packages/shared/kbn-cleanup-before-exit'],
14+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "shared-server",
3+
"id": "@kbn/cleanup-before-exit",
4+
"owner": "@elastic/observability-ui",
5+
"group": "platform",
6+
"visibility": "shared"
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "@kbn/cleanup-before-exit",
3+
"private": true,
4+
"version": "1.0.0",
5+
"license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0"
6+
}

0 commit comments

Comments
 (0)