mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Allow customizing ES client maxSockets (#126937)
* Allow customizing ES client maxSockets * Make maxSockets required (schema defaults to Infinity) * Fix UTs * Misc tweaks + extra UTs * Update asciidoc * Code cleanup Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
76f491b81d
commit
bbddc4233b
12 changed files with 90 additions and 3 deletions
|
@ -62,6 +62,10 @@
|
|||
# must be a positive integer.
|
||||
#elasticsearch.requestTimeout: 30000
|
||||
|
||||
# The maximum number of sockets that can be used for communications with elasticsearch.
|
||||
# Defaults to `Infinity`.
|
||||
#elasticsearch.maxSockets: 1024
|
||||
|
||||
# Specifies whether Kibana should use compression for communications with elasticsearch
|
||||
# Defaults to `false`.
|
||||
#elasticsearch.compression: false
|
||||
|
|
|
@ -9,7 +9,7 @@ Configuration options to be used to create a [cluster client](./kibana-plugin-co
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'compression' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password' | 'serviceAccountToken'> & {
|
||||
export declare type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'maxSockets' | 'compression' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password' | 'serviceAccountToken'> & {
|
||||
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout'];
|
||||
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout'];
|
||||
ssl?: Partial<ElasticsearchConfig['ssl']>;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ElasticsearchConfig](./kibana-plugin-core-server.elasticsearchconfig.md) > [maxSockets](./kibana-plugin-core-server.elasticsearchconfig.maxsockets.md)
|
||||
|
||||
## ElasticsearchConfig.maxSockets property
|
||||
|
||||
The maximum number of sockets that can be used for communications with elasticsearch.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
readonly maxSockets: number;
|
||||
```
|
|
@ -28,6 +28,7 @@ export declare class ElasticsearchConfig
|
|||
| [healthCheckDelay](./kibana-plugin-core-server.elasticsearchconfig.healthcheckdelay.md) | | Duration | The interval between health check requests Kibana sends to the Elasticsearch. |
|
||||
| [hosts](./kibana-plugin-core-server.elasticsearchconfig.hosts.md) | | string\[\] | Hosts that the client will connect to. If sniffing is enabled, this list will be used as seeds to discover the rest of your cluster. |
|
||||
| [ignoreVersionMismatch](./kibana-plugin-core-server.elasticsearchconfig.ignoreversionmismatch.md) | | boolean | Whether to allow kibana to connect to a non-compatible elasticsearch node. |
|
||||
| [maxSockets](./kibana-plugin-core-server.elasticsearchconfig.maxsockets.md) | | number | The maximum number of sockets that can be used for communications with elasticsearch. |
|
||||
| [password?](./kibana-plugin-core-server.elasticsearchconfig.password.md) | | string | <i>(Optional)</i> If Elasticsearch is protected with basic authentication, this setting provides the password that the Kibana server uses to perform its administrative functions. |
|
||||
| [pingTimeout](./kibana-plugin-core-server.elasticsearchconfig.pingtimeout.md) | | Duration | Timeout after which PING HTTP request will be aborted and retried. |
|
||||
| [requestHeadersWhitelist](./kibana-plugin-core-server.elasticsearchconfig.requestheaderswhitelist.md) | | string\[\] | List of Kibana client-side headers to send to Elasticsearch when request scoped cluster client is used. If this is an empty array then \*no\* client-side will be sent. |
|
||||
|
|
|
@ -90,6 +90,10 @@ enforce even rudimentary CSP rules, though {kib} is still accessible. This
|
|||
configuration is effectively ignored when <<csp-strict, `csp.strict`>> is enabled.
|
||||
*Default: `true`*
|
||||
|
||||
|[[elasticsearch-maxSockets]] `elasticsearch.maxSockets`
|
||||
| The maximum number of sockets that can be used for communications with elasticsearch.
|
||||
*Default: `Infinity`*
|
||||
|
||||
| `elasticsearch.customHeaders:`
|
||||
| Header names and values to send to {es}. Any custom headers cannot be
|
||||
overwritten by client-side headers, regardless of the
|
||||
|
|
|
@ -16,6 +16,7 @@ const createConfig = (
|
|||
return {
|
||||
customHeaders: {},
|
||||
compression: false,
|
||||
maxSockets: Infinity,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
sniffInterval: false,
|
||||
|
@ -107,6 +108,18 @@ describe('parseClientOptions', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('`maxSockets` option', () => {
|
||||
it('uses the specified config value', () => {
|
||||
const options = parseClientOptions(createConfig({ maxSockets: 1024 }), false);
|
||||
expect(options.agent).toHaveProperty('maxSockets', 1024);
|
||||
});
|
||||
|
||||
it('defaults to `Infinity` if not specified by the config', () => {
|
||||
const options = parseClientOptions(createConfig({}), false);
|
||||
expect(options.agent).toHaveProperty('maxSockets', Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
describe('`compression` option', () => {
|
||||
it('`compression` is true', () => {
|
||||
const options = parseClientOptions(createConfig({ compression: true }), false);
|
||||
|
|
|
@ -22,6 +22,7 @@ import { DEFAULT_HEADERS } from '../default_headers';
|
|||
export type ElasticsearchClientConfig = Pick<
|
||||
ElasticsearchConfig,
|
||||
| 'customHeaders'
|
||||
| 'maxSockets'
|
||||
| 'compression'
|
||||
| 'sniffOnStart'
|
||||
| 'sniffOnConnectionFault'
|
||||
|
@ -61,7 +62,7 @@ export function parseClientOptions(
|
|||
// fixes https://github.com/elastic/kibana/issues/101944
|
||||
disablePrototypePoisoningProtection: true,
|
||||
agent: {
|
||||
maxSockets: Infinity,
|
||||
maxSockets: config.maxSockets,
|
||||
keepAlive: config.keepAlive ?? true,
|
||||
},
|
||||
compression: config.compression,
|
||||
|
|
|
@ -26,6 +26,7 @@ const createConfig = (
|
|||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
sniffInterval: false,
|
||||
maxSockets: Infinity,
|
||||
compression: false,
|
||||
requestHeadersWhitelist: ['authorization'],
|
||||
customHeaders: {},
|
||||
|
|
|
@ -36,6 +36,7 @@ test('set correct defaults', () => {
|
|||
"http://localhost:9200",
|
||||
],
|
||||
"ignoreVersionMismatch": false,
|
||||
"maxSockets": Infinity,
|
||||
"password": undefined,
|
||||
"pingTimeout": "PT30S",
|
||||
"requestHeadersWhitelist": Array [
|
||||
|
@ -80,6 +81,45 @@ test('#hosts accepts both string and array of strings', () => {
|
|||
expect(configValue.hosts).toEqual(['http://some.host:1234', 'https://some.another.host']);
|
||||
});
|
||||
|
||||
describe('#maxSockets', () => {
|
||||
test('accepts positive numeric values', () => {
|
||||
const configValue = new ElasticsearchConfig(config.schema.validate({ maxSockets: 512 }));
|
||||
expect(configValue.maxSockets).toEqual(512);
|
||||
});
|
||||
|
||||
test('throws if it does not contain a numeric value', () => {
|
||||
expect(() => {
|
||||
config.schema.validate({ maxSockets: 'foo' });
|
||||
}).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[maxSockets]: expected value of type [number] but got [string]"`
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
config.schema.validate({ maxSockets: true });
|
||||
}).toThrowErrorMatchingInlineSnapshot(
|
||||
`"[maxSockets]: expected value of type [number] but got [boolean]"`
|
||||
);
|
||||
});
|
||||
|
||||
test('throws if it does not contain a valid numeric value', () => {
|
||||
expect(() => {
|
||||
config.schema.validate({ maxSockets: -1 });
|
||||
}).toThrowErrorMatchingInlineSnapshot(
|
||||
'"[maxSockets]: Value must be equal to or greater than [1]."'
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
config.schema.validate({ maxSockets: 0 });
|
||||
}).toThrowErrorMatchingInlineSnapshot(
|
||||
'"[maxSockets]: Value must be equal to or greater than [1]."'
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
config.schema.validate({ maxSockets: Infinity });
|
||||
}).toThrowErrorMatchingInlineSnapshot('"[maxSockets]: \\"maxSockets\\" cannot be infinity"');
|
||||
});
|
||||
});
|
||||
|
||||
test('#requestHeadersWhitelist accepts both string and array of strings', () => {
|
||||
let configValue = new ElasticsearchConfig(
|
||||
config.schema.validate({ requestHeadersWhitelist: 'token' })
|
||||
|
|
|
@ -36,6 +36,7 @@ export const configSchema = schema.object({
|
|||
hosts: schema.oneOf([hostURISchema, schema.arrayOf(hostURISchema, { minSize: 1 })], {
|
||||
defaultValue: 'http://localhost:9200',
|
||||
}),
|
||||
maxSockets: schema.number({ defaultValue: Infinity, min: 1 }),
|
||||
compression: schema.boolean({ defaultValue: false }),
|
||||
username: schema.maybe(
|
||||
schema.string({
|
||||
|
@ -298,6 +299,11 @@ export class ElasticsearchConfig {
|
|||
*/
|
||||
public readonly apiVersion: string;
|
||||
|
||||
/**
|
||||
* The maximum number of sockets that can be used for communications with elasticsearch.
|
||||
*/
|
||||
public readonly maxSockets: number;
|
||||
|
||||
/**
|
||||
* Whether to use compression for communications with elasticsearch.
|
||||
*/
|
||||
|
@ -405,6 +411,7 @@ export class ElasticsearchConfig {
|
|||
this.password = rawConfig.password;
|
||||
this.serviceAccountToken = rawConfig.serviceAccountToken;
|
||||
this.customHeaders = rawConfig.customHeaders;
|
||||
this.maxSockets = rawConfig.maxSockets;
|
||||
this.compression = rawConfig.compression;
|
||||
this.skipStartupConnectionCheck = rawConfig.skipStartupConnectionCheck;
|
||||
|
||||
|
|
|
@ -231,6 +231,7 @@ export const config: {
|
|||
sniffInterval: Type<false | Duration>;
|
||||
sniffOnConnectionFault: Type<boolean>;
|
||||
hosts: Type<string | string[]>;
|
||||
maxSockets: Type<number>;
|
||||
compression: Type<boolean>;
|
||||
username: Type<string | undefined>;
|
||||
password: Type<string | undefined>;
|
||||
|
@ -889,7 +890,7 @@ export { EcsEventType }
|
|||
export type ElasticsearchClient = Omit<Client, 'connectionPool' | 'serializer' | 'extend' | 'close' | 'diagnostic'>;
|
||||
|
||||
// @public
|
||||
export type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'compression' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password' | 'serviceAccountToken'> & {
|
||||
export type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'maxSockets' | 'compression' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password' | 'serviceAccountToken'> & {
|
||||
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout'];
|
||||
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout'];
|
||||
ssl?: Partial<ElasticsearchConfig['ssl']>;
|
||||
|
@ -907,6 +908,7 @@ export class ElasticsearchConfig {
|
|||
readonly healthCheckDelay: Duration;
|
||||
readonly hosts: string[];
|
||||
readonly ignoreVersionMismatch: boolean;
|
||||
readonly maxSockets: number;
|
||||
readonly password?: string;
|
||||
readonly pingTimeout: Duration;
|
||||
readonly requestHeadersWhitelist: string[];
|
||||
|
|
|
@ -78,6 +78,7 @@ describe('config schema', () => {
|
|||
"ignoreVersionMismatch": false,
|
||||
"logFetchCount": 10,
|
||||
"logQueries": false,
|
||||
"maxSockets": Infinity,
|
||||
"pingTimeout": "PT30S",
|
||||
"requestHeadersWhitelist": Array [
|
||||
"authorization",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue