Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
420906569e
commit
2a5f6797ce
|
@ -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' | 'logQueries' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password'> & {
|
||||
export declare type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password'> & {
|
||||
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout'];
|
||||
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout'];
|
||||
ssl?: Partial<ElasticsearchConfig['ssl']>;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<!-- 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) > [logQueries](./kibana-plugin-core-server.elasticsearchconfig.logqueries.md)
|
||||
|
||||
## ElasticsearchConfig.logQueries property
|
||||
|
||||
Specifies whether all queries to the client should be logged (status code, method, query etc.).
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
readonly logQueries: boolean;
|
||||
```
|
|
@ -27,7 +27,6 @@ export declare class ElasticsearchConfig
|
|||
| [healthCheckDelay](./kibana-plugin-core-server.elasticsearchconfig.healthcheckdelay.md) | | <code>Duration</code> | The interval between health check requests Kibana sends to the Elasticsearch. |
|
||||
| [hosts](./kibana-plugin-core-server.elasticsearchconfig.hosts.md) | | <code>string[]</code> | 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) | | <code>boolean</code> | Whether to allow kibana to connect to a non-compatible elasticsearch node. |
|
||||
| [logQueries](./kibana-plugin-core-server.elasticsearchconfig.logqueries.md) | | <code>boolean</code> | Specifies whether all queries to the client should be logged (status code, method, query etc.). |
|
||||
| [password](./kibana-plugin-core-server.elasticsearchconfig.password.md) | | <code>string</code> | 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) | | <code>Duration</code> | Timeout after which PING HTTP request will be aborted and retried. |
|
||||
| [requestHeadersWhitelist](./kibana-plugin-core-server.elasticsearchconfig.requestheaderswhitelist.md) | | <code>string[]</code> | 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. |
|
||||
|
|
|
@ -9,7 +9,7 @@ Constructs a new instance of the `LegacyClusterClient` class
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
constructor(config: LegacyElasticsearchClientConfig, log: Logger, getAuthHeaders?: GetAuthHeaders);
|
||||
constructor(config: LegacyElasticsearchClientConfig, log: Logger, type: string, getAuthHeaders?: GetAuthHeaders);
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
@ -18,5 +18,6 @@ constructor(config: LegacyElasticsearchClientConfig, log: Logger, getAuthHeaders
|
|||
| --- | --- | --- |
|
||||
| config | <code>LegacyElasticsearchClientConfig</code> | |
|
||||
| log | <code>Logger</code> | |
|
||||
| type | <code>string</code> | |
|
||||
| getAuthHeaders | <code>GetAuthHeaders</code> | |
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export declare class LegacyClusterClient implements ILegacyClusterClient
|
|||
|
||||
| Constructor | Modifiers | Description |
|
||||
| --- | --- | --- |
|
||||
| [(constructor)(config, log, getAuthHeaders)](./kibana-plugin-core-server.legacyclusterclient._constructor_.md) | | Constructs a new instance of the <code>LegacyClusterClient</code> class |
|
||||
| [(constructor)(config, log, type, getAuthHeaders)](./kibana-plugin-core-server.legacyclusterclient._constructor_.md) | | Constructs a new instance of the <code>LegacyClusterClient</code> class |
|
||||
|
||||
## Properties
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export declare type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' | 'log' | 'plugins'> & Pick<ElasticsearchConfig, 'apiVersion' | 'customHeaders' | 'logQueries' | 'requestHeadersWhitelist' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'hosts' | 'username' | 'password'> & {
|
||||
export declare type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' | 'log' | 'plugins'> & Pick<ElasticsearchConfig, 'apiVersion' | 'customHeaders' | 'requestHeadersWhitelist' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'hosts' | 'username' | 'password'> & {
|
||||
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout'];
|
||||
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ConfigOptions['requestTimeout'];
|
||||
sniffInterval?: ElasticsearchConfig['sniffInterval'] | ConfigOptions['sniffInterval'];
|
||||
|
|
|
@ -59,7 +59,7 @@ To enable SSL/TLS for outbound connections to {es}, use the `https` protocol
|
|||
in this setting.
|
||||
|
||||
| `elasticsearch.logQueries:`
|
||||
| Log queries sent to {es}. Requires <<logging-verbose, `logging.verbose`>> set to `true`.
|
||||
| *deprecated* This setting is no longer used and will get removed in Kibana 8.0. Instead, set <<logging-verbose, `logging.verbose`>> to `true`
|
||||
This is useful for seeing the query DSL generated by applications that
|
||||
currently do not have an inspector, for example Timelion and Monitoring.
|
||||
*Default: `false`*
|
||||
|
|
|
@ -15,7 +15,6 @@ const createConfig = (
|
|||
): ElasticsearchClientConfig => {
|
||||
return {
|
||||
customHeaders: {},
|
||||
logQueries: false,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
sniffInterval: false,
|
||||
|
|
|
@ -22,7 +22,6 @@ import { DEFAULT_HEADERS } from '../default_headers';
|
|||
export type ElasticsearchClientConfig = Pick<
|
||||
ElasticsearchConfig,
|
||||
| 'customHeaders'
|
||||
| 'logQueries'
|
||||
| 'sniffOnStart'
|
||||
| 'sniffOnConnectionFault'
|
||||
| 'requestHeadersWhitelist'
|
||||
|
|
|
@ -19,7 +19,6 @@ const createConfig = (
|
|||
parts: Partial<ElasticsearchClientConfig> = {}
|
||||
): ElasticsearchClientConfig => {
|
||||
return {
|
||||
logQueries: false,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
sniffInterval: false,
|
||||
|
@ -57,16 +56,25 @@ describe('ClusterClient', () => {
|
|||
it('creates a single internal and scoped client during initialization', () => {
|
||||
const config = createConfig();
|
||||
|
||||
new ClusterClient(config, logger, getAuthHeaders);
|
||||
new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
|
||||
expect(configureClientMock).toHaveBeenCalledTimes(2);
|
||||
expect(configureClientMock).toHaveBeenCalledWith(config, { logger });
|
||||
expect(configureClientMock).toHaveBeenCalledWith(config, { logger, scoped: true });
|
||||
expect(configureClientMock).toHaveBeenCalledWith(config, { logger, type: 'custom-type' });
|
||||
expect(configureClientMock).toHaveBeenCalledWith(config, {
|
||||
logger,
|
||||
type: 'custom-type',
|
||||
scoped: true,
|
||||
});
|
||||
});
|
||||
|
||||
describe('#asInternalUser', () => {
|
||||
it('returns the internal client', () => {
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
|
||||
expect(clusterClient.asInternalUser).toBe(internalClient);
|
||||
});
|
||||
|
@ -74,7 +82,12 @@ describe('ClusterClient', () => {
|
|||
|
||||
describe('#asScoped', () => {
|
||||
it('returns a scoped cluster client bound to the request', () => {
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
const request = httpServerMock.createKibanaRequest();
|
||||
|
||||
const scopedClusterClient = clusterClient.asScoped(request);
|
||||
|
@ -87,7 +100,12 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
|
||||
it('returns a distinct scoped cluster client on each call', () => {
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
const request = httpServerMock.createKibanaRequest();
|
||||
|
||||
const scopedClusterClient1 = clusterClient.asScoped(request);
|
||||
|
@ -105,7 +123,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
headers: {
|
||||
foo: 'bar',
|
||||
|
@ -130,7 +148,7 @@ describe('ClusterClient', () => {
|
|||
other: 'nope',
|
||||
});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({});
|
||||
|
||||
clusterClient.asScoped(request);
|
||||
|
@ -150,7 +168,7 @@ describe('ClusterClient', () => {
|
|||
other: 'nope',
|
||||
});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
headers: {
|
||||
authorization: 'override',
|
||||
|
@ -175,7 +193,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({});
|
||||
|
||||
clusterClient.asScoped(request);
|
||||
|
@ -195,7 +213,7 @@ describe('ClusterClient', () => {
|
|||
const config = createConfig();
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
kibanaRequestState: { requestId: 'my-fake-id', requestUuid: 'ignore-this-id' },
|
||||
});
|
||||
|
@ -223,7 +241,7 @@ describe('ClusterClient', () => {
|
|||
foo: 'auth',
|
||||
});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({});
|
||||
|
||||
clusterClient.asScoped(request);
|
||||
|
@ -249,7 +267,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
headers: { foo: 'request' },
|
||||
});
|
||||
|
@ -276,7 +294,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest();
|
||||
|
||||
clusterClient.asScoped(request);
|
||||
|
@ -297,7 +315,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
headers: { [headerKey]: 'foo' },
|
||||
});
|
||||
|
@ -321,7 +339,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = httpServerMock.createKibanaRequest({
|
||||
headers: { foo: 'request' },
|
||||
kibanaRequestState: { requestId: 'from request', requestUuid: 'ignore-this-id' },
|
||||
|
@ -344,7 +362,7 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
getAuthHeaders.mockReturnValue({});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = {
|
||||
headers: {
|
||||
authorization: 'auth',
|
||||
|
@ -368,7 +386,7 @@ describe('ClusterClient', () => {
|
|||
authorization: 'auth',
|
||||
});
|
||||
|
||||
const clusterClient = new ClusterClient(config, logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(config, logger, 'custom-type', getAuthHeaders);
|
||||
const request = {
|
||||
headers: {
|
||||
foo: 'bar',
|
||||
|
@ -387,7 +405,12 @@ describe('ClusterClient', () => {
|
|||
|
||||
describe('#close', () => {
|
||||
it('closes both underlying clients', async () => {
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
|
||||
await clusterClient.close();
|
||||
|
||||
|
@ -398,7 +421,12 @@ describe('ClusterClient', () => {
|
|||
it('waits for both clients to close', async (done) => {
|
||||
expect.assertions(4);
|
||||
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
|
||||
let internalClientClosed = false;
|
||||
let scopedClientClosed = false;
|
||||
|
@ -436,7 +464,12 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
|
||||
it('return a rejected promise is any client rejects', async () => {
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
|
||||
internalClient.close.mockRejectedValue(new Error('error closing client'));
|
||||
|
||||
|
@ -446,7 +479,12 @@ describe('ClusterClient', () => {
|
|||
});
|
||||
|
||||
it('does nothing after the first call', async () => {
|
||||
const clusterClient = new ClusterClient(createConfig(), logger, getAuthHeaders);
|
||||
const clusterClient = new ClusterClient(
|
||||
createConfig(),
|
||||
logger,
|
||||
'custom-type',
|
||||
getAuthHeaders
|
||||
);
|
||||
|
||||
await clusterClient.close();
|
||||
|
||||
|
|
|
@ -60,10 +60,11 @@ export class ClusterClient implements ICustomClusterClient {
|
|||
constructor(
|
||||
private readonly config: ElasticsearchClientConfig,
|
||||
logger: Logger,
|
||||
type: string,
|
||||
private readonly getAuthHeaders: GetAuthHeaders = noop
|
||||
) {
|
||||
this.asInternalUser = configureClient(config, { logger });
|
||||
this.rootScopedClient = configureClient(config, { logger, scoped: true });
|
||||
this.asInternalUser = configureClient(config, { logger, type });
|
||||
this.rootScopedClient = configureClient(config, { logger, type, scoped: true });
|
||||
}
|
||||
|
||||
asScoped(request: ScopeableRequest) {
|
||||
|
|
|
@ -76,14 +76,14 @@ describe('configureClient', () => {
|
|||
});
|
||||
|
||||
it('calls `parseClientOptions` with the correct parameters', () => {
|
||||
configureClient(config, { logger, scoped: false });
|
||||
configureClient(config, { logger, type: 'test', scoped: false });
|
||||
|
||||
expect(parseClientOptionsMock).toHaveBeenCalledTimes(1);
|
||||
expect(parseClientOptionsMock).toHaveBeenCalledWith(config, false);
|
||||
|
||||
parseClientOptionsMock.mockClear();
|
||||
|
||||
configureClient(config, { logger, scoped: true });
|
||||
configureClient(config, { logger, type: 'test', scoped: true });
|
||||
|
||||
expect(parseClientOptionsMock).toHaveBeenCalledTimes(1);
|
||||
expect(parseClientOptionsMock).toHaveBeenCalledWith(config, true);
|
||||
|
@ -95,7 +95,7 @@ describe('configureClient', () => {
|
|||
};
|
||||
parseClientOptionsMock.mockReturnValue(parsedOptions);
|
||||
|
||||
const client = configureClient(config, { logger, scoped: false });
|
||||
const client = configureClient(config, { logger, type: 'test', scoped: false });
|
||||
|
||||
expect(ClientMock).toHaveBeenCalledTimes(1);
|
||||
expect(ClientMock).toHaveBeenCalledWith(parsedOptions);
|
||||
|
@ -103,7 +103,7 @@ describe('configureClient', () => {
|
|||
});
|
||||
|
||||
it('listens to client on `response` events', () => {
|
||||
const client = configureClient(config, { logger, scoped: false });
|
||||
const client = configureClient(config, { logger, type: 'test', scoped: false });
|
||||
|
||||
expect(client.on).toHaveBeenCalledTimes(1);
|
||||
expect(client.on).toHaveBeenCalledWith('response', expect.any(Function));
|
||||
|
@ -122,38 +122,15 @@ describe('configureClient', () => {
|
|||
},
|
||||
});
|
||||
}
|
||||
describe('does not log whrn "logQueries: false"', () => {
|
||||
it('response', () => {
|
||||
const client = configureClient(config, { logger, scoped: false });
|
||||
const response = createResponseWithBody({
|
||||
seq_no_primary_term: true,
|
||||
query: {
|
||||
term: { user: 'kimchy' },
|
||||
},
|
||||
});
|
||||
|
||||
client.emit('response', null, response);
|
||||
expect(loggingSystemMock.collect(logger).debug).toHaveLength(0);
|
||||
describe('logs each query', () => {
|
||||
it('creates a query logger context based on the `type` parameter', () => {
|
||||
configureClient(createFakeConfig(), { logger, type: 'test123' });
|
||||
expect(logger.get).toHaveBeenCalledWith('query', 'test123');
|
||||
});
|
||||
|
||||
it('error', () => {
|
||||
const client = configureClient(config, { logger, scoped: false });
|
||||
|
||||
const response = createApiResponse({ body: {} });
|
||||
client.emit('response', new errors.TimeoutError('message', response), response);
|
||||
|
||||
expect(loggingSystemMock.collect(logger).error).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logs each queries if `logQueries` is true', () => {
|
||||
it('when request body is an object', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createResponseWithBody({
|
||||
seq_no_primary_term: true,
|
||||
|
@ -169,23 +146,13 @@ describe('configureClient', () => {
|
|||
"200
|
||||
GET /foo?hello=dolly
|
||||
{\\"seq_no_primary_term\\":true,\\"query\\":{\\"term\\":{\\"user\\":\\"kimchy\\"}}}",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('when request body is a string', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createResponseWithBody(
|
||||
JSON.stringify({
|
||||
|
@ -203,23 +170,13 @@ describe('configureClient', () => {
|
|||
"200
|
||||
GET /foo?hello=dolly
|
||||
{\\"seq_no_primary_term\\":true,\\"query\\":{\\"term\\":{\\"user\\":\\"kimchy\\"}}}",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('when request body is a buffer', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createResponseWithBody(
|
||||
Buffer.from(
|
||||
|
@ -239,23 +196,13 @@ describe('configureClient', () => {
|
|||
"200
|
||||
GET /foo?hello=dolly
|
||||
[buffer]",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('when request body is a readable stream', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createResponseWithBody(
|
||||
Readable.from(
|
||||
|
@ -275,23 +222,13 @@ describe('configureClient', () => {
|
|||
"200
|
||||
GET /foo?hello=dolly
|
||||
[stream]",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('when request body is not defined', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createResponseWithBody();
|
||||
|
||||
|
@ -301,23 +238,13 @@ describe('configureClient', () => {
|
|||
Array [
|
||||
"200
|
||||
GET /foo?hello=dolly",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('properly encode queries', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createApiResponse({
|
||||
body: {},
|
||||
|
@ -336,23 +263,13 @@ describe('configureClient', () => {
|
|||
Array [
|
||||
"200
|
||||
GET /foo?city=M%C3%BCnich",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('logs queries even in case of errors if `logQueries` is true', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
it('logs queries even in case of errors', () => {
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createApiResponse({
|
||||
statusCode: 500,
|
||||
|
@ -375,7 +292,7 @@ describe('configureClient', () => {
|
|||
});
|
||||
client.emit('response', new errors.ResponseError(response), response);
|
||||
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"500
|
||||
|
@ -386,40 +303,13 @@ describe('configureClient', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('does not log queries if `logQueries` is false', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: false,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
|
||||
const response = createApiResponse({
|
||||
body: {},
|
||||
statusCode: 200,
|
||||
params: {
|
||||
method: 'GET',
|
||||
path: '/foo',
|
||||
},
|
||||
});
|
||||
|
||||
client.emit('response', null, response);
|
||||
|
||||
expect(logger.debug).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('logs error when the client emits an @elastic/elasticsearch error', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
it('logs debug when the client emits an @elastic/elasticsearch error', () => {
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createApiResponse({ body: {} });
|
||||
client.emit('response', new errors.TimeoutError('message', response), response);
|
||||
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"[TimeoutError]: message",
|
||||
|
@ -428,13 +318,8 @@ describe('configureClient', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('logs error when the client emits an ResponseError returned by elasticsearch', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
it('logs debug when the client emits an ResponseError returned by elasticsearch', () => {
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
const response = createApiResponse({
|
||||
statusCode: 400,
|
||||
|
@ -453,7 +338,7 @@ describe('configureClient', () => {
|
|||
});
|
||||
client.emit('response', new errors.ResponseError(response), response);
|
||||
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"400
|
||||
|
@ -464,12 +349,7 @@ describe('configureClient', () => {
|
|||
});
|
||||
|
||||
it('logs default error info when the error response body is empty', () => {
|
||||
const client = configureClient(
|
||||
createFakeConfig({
|
||||
logQueries: true,
|
||||
}),
|
||||
{ logger, scoped: false }
|
||||
);
|
||||
const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false });
|
||||
|
||||
let response = createApiResponse({
|
||||
statusCode: 400,
|
||||
|
@ -484,7 +364,7 @@ describe('configureClient', () => {
|
|||
});
|
||||
client.emit('response', new errors.ResponseError(response), response);
|
||||
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"400
|
||||
|
@ -493,7 +373,7 @@ describe('configureClient', () => {
|
|||
]
|
||||
`);
|
||||
|
||||
logger.error.mockClear();
|
||||
logger.debug.mockClear();
|
||||
|
||||
response = createApiResponse({
|
||||
statusCode: 400,
|
||||
|
@ -506,7 +386,7 @@ describe('configureClient', () => {
|
|||
});
|
||||
client.emit('response', new errors.ResponseError(response), response);
|
||||
|
||||
expect(loggingSystemMock.collect(logger).error).toMatchInlineSnapshot(`
|
||||
expect(loggingSystemMock.collect(logger).debug).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"400
|
||||
|
|
|
@ -15,12 +15,12 @@ import { parseClientOptions, ElasticsearchClientConfig } from './client_config';
|
|||
|
||||
export const configureClient = (
|
||||
config: ElasticsearchClientConfig,
|
||||
{ logger, scoped = false }: { logger: Logger; scoped?: boolean }
|
||||
{ logger, type, scoped = false }: { logger: Logger; type: string; scoped?: boolean }
|
||||
): Client => {
|
||||
const clientOptions = parseClientOptions(config, scoped);
|
||||
|
||||
const client = new Client(clientOptions);
|
||||
addLogging(client, logger, config.logQueries);
|
||||
addLogging(client, logger.get('query', type));
|
||||
|
||||
return client;
|
||||
};
|
||||
|
@ -67,15 +67,13 @@ function getResponseMessage(event: RequestEvent): string {
|
|||
return `${event.statusCode}\n${params.method} ${url}${body}`;
|
||||
}
|
||||
|
||||
const addLogging = (client: Client, logger: Logger, logQueries: boolean) => {
|
||||
const addLogging = (client: Client, logger: Logger) => {
|
||||
client.on('response', (error, event) => {
|
||||
if (event && logQueries) {
|
||||
if (event) {
|
||||
if (error) {
|
||||
logger.error(getErrorMessage(error, event));
|
||||
logger.debug(getErrorMessage(error, event));
|
||||
} else {
|
||||
logger.debug(getResponseMessage(event), {
|
||||
tags: ['query'],
|
||||
});
|
||||
logger.debug(getResponseMessage(event));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ test('set correct defaults', () => {
|
|||
"http://localhost:9200",
|
||||
],
|
||||
"ignoreVersionMismatch": false,
|
||||
"logQueries": false,
|
||||
"password": undefined,
|
||||
"pingTimeout": "PT30S",
|
||||
"requestHeadersWhitelist": Array [
|
||||
|
|
|
@ -133,6 +133,10 @@ const deprecations: ConfigDeprecationProvider = () => [
|
|||
log(
|
||||
`Setting [${fromPath}.ssl.certificate] without [${fromPath}.ssl.key] is deprecated. This has no effect, you should use both settings to enable TLS client authentication to Elasticsearch.`
|
||||
);
|
||||
} else if (es.logQueries === true) {
|
||||
log(
|
||||
`Setting [${fromPath}.logQueries] is deprecated and no longer used. You should set the log level to "debug" for the "elasticsearch.queries" context in "logging.loggers" or use "logging.verbose: true".`
|
||||
);
|
||||
}
|
||||
return settings;
|
||||
},
|
||||
|
@ -164,12 +168,6 @@ export class ElasticsearchConfig {
|
|||
*/
|
||||
public readonly apiVersion: string;
|
||||
|
||||
/**
|
||||
* Specifies whether all queries to the client should be logged (status code,
|
||||
* method, query etc.).
|
||||
*/
|
||||
public readonly logQueries: boolean;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -248,7 +246,6 @@ export class ElasticsearchConfig {
|
|||
constructor(rawConfig: ElasticsearchConfigType) {
|
||||
this.ignoreVersionMismatch = rawConfig.ignoreVersionMismatch;
|
||||
this.apiVersion = rawConfig.apiVersion;
|
||||
this.logQueries = rawConfig.logQueries;
|
||||
this.hosts = Array.isArray(rawConfig.hosts) ? rawConfig.hosts : [rawConfig.hosts];
|
||||
this.requestHeadersWhitelist = Array.isArray(rawConfig.requestHeadersWhitelist)
|
||||
? rawConfig.requestHeadersWhitelist
|
||||
|
|
|
@ -92,14 +92,15 @@ describe('#setup', () => {
|
|||
// reset all mocks called during setup phase
|
||||
MockLegacyClusterClient.mockClear();
|
||||
|
||||
const customConfig = { logQueries: true };
|
||||
const customConfig = { keepAlive: true };
|
||||
const clusterClient = setupContract.legacy.createClient('some-custom-type', customConfig);
|
||||
|
||||
expect(clusterClient).toBe(mockLegacyClusterClientInstance);
|
||||
|
||||
expect(MockLegacyClusterClient).toHaveBeenCalledWith(
|
||||
expect.objectContaining(customConfig),
|
||||
expect.objectContaining({ context: ['elasticsearch', 'some-custom-type'] }),
|
||||
expect.objectContaining({ context: ['elasticsearch'] }),
|
||||
'some-custom-type',
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
@ -267,7 +268,7 @@ describe('#start', () => {
|
|||
// reset all mocks called during setup phase
|
||||
MockClusterClient.mockClear();
|
||||
|
||||
const customConfig = { logQueries: true };
|
||||
const customConfig = { keepAlive: true };
|
||||
const clusterClient = startContract.createClient('custom-type', customConfig);
|
||||
|
||||
expect(clusterClient).toBe(mockClusterClientInstance);
|
||||
|
@ -275,7 +276,8 @@ describe('#start', () => {
|
|||
expect(MockClusterClient).toHaveBeenCalledTimes(1);
|
||||
expect(MockClusterClient).toHaveBeenCalledWith(
|
||||
expect.objectContaining(customConfig),
|
||||
expect.objectContaining({ context: ['elasticsearch', 'custom-type'] }),
|
||||
expect.objectContaining({ context: ['elasticsearch'] }),
|
||||
'custom-type',
|
||||
expect.any(Function)
|
||||
);
|
||||
});
|
||||
|
@ -286,7 +288,7 @@ describe('#start', () => {
|
|||
// reset all mocks called during setup phase
|
||||
MockClusterClient.mockClear();
|
||||
|
||||
const customConfig = { logQueries: true };
|
||||
const customConfig = { keepAlive: true };
|
||||
|
||||
startContract.createClient('custom-type', customConfig);
|
||||
startContract.createClient('another-type', customConfig);
|
||||
|
|
|
@ -126,7 +126,8 @@ export class ElasticsearchService
|
|||
private createClusterClient(type: string, config: ElasticsearchClientConfig) {
|
||||
return new ClusterClient(
|
||||
config,
|
||||
this.coreContext.logger.get('elasticsearch', type),
|
||||
this.coreContext.logger.get('elasticsearch'),
|
||||
type,
|
||||
this.getAuthHeaders
|
||||
);
|
||||
}
|
||||
|
@ -134,7 +135,8 @@ export class ElasticsearchService
|
|||
private createLegacyClusterClient(type: string, config: LegacyElasticsearchClientConfig) {
|
||||
return new LegacyClusterClient(
|
||||
config,
|
||||
this.coreContext.logger.get('elasticsearch', type),
|
||||
this.coreContext.logger.get('elasticsearch'),
|
||||
type,
|
||||
this.getAuthHeaders
|
||||
);
|
||||
}
|
||||
|
|
|
@ -31,11 +31,15 @@ test('#constructor creates client with parsed config', () => {
|
|||
const mockEsConfig = { apiVersion: 'es-version' } as any;
|
||||
const mockLogger = logger.get();
|
||||
|
||||
const clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
const clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
expect(clusterClient).toBeDefined();
|
||||
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenCalledTimes(1);
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(mockEsConfig, mockLogger);
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(
|
||||
mockEsConfig,
|
||||
mockLogger,
|
||||
'custom-type'
|
||||
);
|
||||
|
||||
expect(MockClient).toHaveBeenCalledTimes(1);
|
||||
expect(MockClient).toHaveBeenCalledWith(mockEsClientConfig);
|
||||
|
@ -57,7 +61,11 @@ describe('#callAsInternalUser', () => {
|
|||
};
|
||||
MockClient.mockImplementation(() => mockEsClientInstance);
|
||||
|
||||
clusterClient = new LegacyClusterClient({ apiVersion: 'es-version' } as any, logger.get());
|
||||
clusterClient = new LegacyClusterClient(
|
||||
{ apiVersion: 'es-version' } as any,
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
});
|
||||
|
||||
test('fails if cluster client is closed', async () => {
|
||||
|
@ -226,7 +234,7 @@ describe('#asScoped', () => {
|
|||
requestHeadersWhitelist: ['one', 'two'],
|
||||
} as any;
|
||||
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
|
@ -237,10 +245,15 @@ describe('#asScoped', () => {
|
|||
|
||||
expect(firstScopedClusterClient).toBeDefined();
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenCalledTimes(1);
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(mockEsConfig, mockLogger, {
|
||||
auth: false,
|
||||
ignoreCertAndKey: true,
|
||||
});
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(
|
||||
mockEsConfig,
|
||||
mockLogger,
|
||||
'custom-type',
|
||||
{
|
||||
auth: false,
|
||||
ignoreCertAndKey: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(MockClient).toHaveBeenCalledTimes(1);
|
||||
expect(MockClient).toHaveBeenCalledWith(
|
||||
|
@ -261,42 +274,57 @@ describe('#asScoped', () => {
|
|||
|
||||
test('properly configures `ignoreCertAndKey` for various configurations', () => {
|
||||
// Config without SSL.
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
|
||||
mockParseElasticsearchClientConfig.mockClear();
|
||||
clusterClient.asScoped(httpServerMock.createRawRequest({ headers: { one: '1' } }));
|
||||
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenCalledTimes(1);
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(mockEsConfig, mockLogger, {
|
||||
auth: false,
|
||||
ignoreCertAndKey: true,
|
||||
});
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(
|
||||
mockEsConfig,
|
||||
mockLogger,
|
||||
'custom-type',
|
||||
{
|
||||
auth: false,
|
||||
ignoreCertAndKey: true,
|
||||
}
|
||||
);
|
||||
|
||||
// Config ssl.alwaysPresentCertificate === false
|
||||
mockEsConfig = { ...mockEsConfig, ssl: { alwaysPresentCertificate: false } } as any;
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
|
||||
mockParseElasticsearchClientConfig.mockClear();
|
||||
clusterClient.asScoped(httpServerMock.createRawRequest({ headers: { one: '1' } }));
|
||||
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenCalledTimes(1);
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(mockEsConfig, mockLogger, {
|
||||
auth: false,
|
||||
ignoreCertAndKey: true,
|
||||
});
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(
|
||||
mockEsConfig,
|
||||
mockLogger,
|
||||
'custom-type',
|
||||
{
|
||||
auth: false,
|
||||
ignoreCertAndKey: true,
|
||||
}
|
||||
);
|
||||
|
||||
// Config ssl.alwaysPresentCertificate === true
|
||||
mockEsConfig = { ...mockEsConfig, ssl: { alwaysPresentCertificate: true } } as any;
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
|
||||
mockParseElasticsearchClientConfig.mockClear();
|
||||
clusterClient.asScoped(httpServerMock.createRawRequest({ headers: { one: '1' } }));
|
||||
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenCalledTimes(1);
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(mockEsConfig, mockLogger, {
|
||||
auth: false,
|
||||
ignoreCertAndKey: false,
|
||||
});
|
||||
expect(mockParseElasticsearchClientConfig).toHaveBeenLastCalledWith(
|
||||
mockEsConfig,
|
||||
mockLogger,
|
||||
'custom-type',
|
||||
{
|
||||
auth: false,
|
||||
ignoreCertAndKey: false,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('passes only filtered headers to the scoped cluster client', () => {
|
||||
|
@ -345,7 +373,7 @@ describe('#asScoped', () => {
|
|||
});
|
||||
|
||||
test('does not fail when scope to not defined request', async () => {
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
clusterClient.asScoped();
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledTimes(1);
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledWith(
|
||||
|
@ -356,7 +384,7 @@ describe('#asScoped', () => {
|
|||
});
|
||||
|
||||
test('does not fail when scope to a request without headers', async () => {
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
clusterClient.asScoped({} as any);
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledTimes(1);
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledWith(
|
||||
|
@ -367,7 +395,7 @@ describe('#asScoped', () => {
|
|||
});
|
||||
|
||||
test('calls getAuthHeaders and filters results for a real request', async () => {
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, () => ({
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type', () => ({
|
||||
one: '1',
|
||||
three: '3',
|
||||
}));
|
||||
|
@ -381,7 +409,9 @@ describe('#asScoped', () => {
|
|||
});
|
||||
|
||||
test('getAuthHeaders results rewrite extends a request headers', async () => {
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, () => ({ one: 'foo' }));
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type', () => ({
|
||||
one: 'foo',
|
||||
}));
|
||||
clusterClient.asScoped(httpServerMock.createRawRequest({ headers: { one: '1', two: '2' } }));
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledTimes(1);
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledWith(
|
||||
|
@ -392,7 +422,7 @@ describe('#asScoped', () => {
|
|||
});
|
||||
|
||||
test("doesn't call getAuthHeaders for a fake request", async () => {
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, () => ({}));
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type', () => ({}));
|
||||
clusterClient.asScoped({ headers: { one: 'foo' } });
|
||||
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledTimes(1);
|
||||
|
@ -404,7 +434,7 @@ describe('#asScoped', () => {
|
|||
});
|
||||
|
||||
test('filters a fake request headers', async () => {
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger);
|
||||
clusterClient = new LegacyClusterClient(mockEsConfig, mockLogger, 'custom-type');
|
||||
clusterClient.asScoped({ headers: { one: '1', two: '2', three: '3' } });
|
||||
|
||||
expect(MockScopedClusterClient).toHaveBeenCalledTimes(1);
|
||||
|
@ -431,7 +461,8 @@ describe('#close', () => {
|
|||
|
||||
clusterClient = new LegacyClusterClient(
|
||||
{ apiVersion: 'es-version', requestHeadersWhitelist: [] } as any,
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -121,9 +121,10 @@ export class LegacyClusterClient implements ILegacyClusterClient {
|
|||
constructor(
|
||||
private readonly config: LegacyElasticsearchClientConfig,
|
||||
private readonly log: Logger,
|
||||
private readonly type: string,
|
||||
private readonly getAuthHeaders: GetAuthHeaders = noop
|
||||
) {
|
||||
this.client = new Client(parseElasticsearchClientConfig(config, log));
|
||||
this.client = new Client(parseElasticsearchClientConfig(config, log, type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,7 +187,7 @@ export class LegacyClusterClient implements ILegacyClusterClient {
|
|||
// between all scoped client instances.
|
||||
if (this.scopedClient === undefined) {
|
||||
this.scopedClient = new Client(
|
||||
parseElasticsearchClientConfig(this.config, this.log, {
|
||||
parseElasticsearchClientConfig(this.config, this.log, this.type, {
|
||||
auth: false,
|
||||
ignoreCertAndKey: !this.config.ssl || !this.config.ssl.alwaysPresentCertificate,
|
||||
})
|
||||
|
|
|
@ -22,13 +22,13 @@ test('parses minimally specified config', () => {
|
|||
{
|
||||
apiVersion: 'master',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: false,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
hosts: ['http://localhost/elasticsearch'],
|
||||
requestHeadersWhitelist: [],
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
|
@ -58,7 +58,6 @@ test('parses fully specified config', () => {
|
|||
const elasticsearchConfig: LegacyElasticsearchClientConfig = {
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: [
|
||||
|
@ -84,7 +83,8 @@ test('parses fully specified config', () => {
|
|||
|
||||
const elasticsearchClientConfig = parseElasticsearchClientConfig(
|
||||
elasticsearchConfig,
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
|
||||
// Check that original references aren't used.
|
||||
|
@ -163,7 +163,6 @@ test('parses config timeouts of moment.Duration type', () => {
|
|||
{
|
||||
apiVersion: 'master',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: false,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
pingTimeout: duration(100, 'ms'),
|
||||
|
@ -172,7 +171,8 @@ test('parses config timeouts of moment.Duration type', () => {
|
|||
hosts: ['http://localhost:9200/elasticsearch'],
|
||||
requestHeadersWhitelist: [],
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
|
@ -208,7 +208,6 @@ describe('#auth', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['http://user:password@localhost/elasticsearch', 'https://es.local'],
|
||||
|
@ -217,6 +216,7 @@ describe('#auth', () => {
|
|||
requestHeadersWhitelist: [],
|
||||
},
|
||||
logger.get(),
|
||||
'custom-type',
|
||||
{ auth: false }
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
|
@ -260,7 +260,6 @@ describe('#auth', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
|
@ -268,6 +267,7 @@ describe('#auth', () => {
|
|||
password: 'changeme',
|
||||
},
|
||||
logger.get(),
|
||||
'custom-type',
|
||||
{ auth: true }
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
|
@ -300,7 +300,6 @@ describe('#auth', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
|
@ -308,6 +307,7 @@ describe('#auth', () => {
|
|||
username: 'elastic',
|
||||
},
|
||||
logger.get(),
|
||||
'custom-type',
|
||||
{ auth: true }
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
|
@ -342,13 +342,13 @@ describe('#customHeaders', () => {
|
|||
{
|
||||
apiVersion: 'master',
|
||||
customHeaders: { [headerKey]: 'foo' },
|
||||
logQueries: false,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
hosts: ['http://localhost/elasticsearch'],
|
||||
requestHeadersWhitelist: [],
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
expect(parsedConfig.hosts[0].headers).toEqual({
|
||||
[headerKey]: 'foo',
|
||||
|
@ -357,62 +357,18 @@ describe('#customHeaders', () => {
|
|||
});
|
||||
|
||||
describe('#log', () => {
|
||||
test('default logger with #logQueries = false', () => {
|
||||
test('default logger', () => {
|
||||
const parsedConfig = parseElasticsearchClientConfig(
|
||||
{
|
||||
apiVersion: 'master',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: false,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
hosts: ['http://localhost/elasticsearch'],
|
||||
requestHeadersWhitelist: [],
|
||||
},
|
||||
logger.get()
|
||||
);
|
||||
|
||||
const esLogger = new parsedConfig.log();
|
||||
esLogger.error('some-error');
|
||||
esLogger.warning('some-warning');
|
||||
esLogger.trace('some-trace');
|
||||
esLogger.info('some-info');
|
||||
esLogger.debug('some-debug');
|
||||
|
||||
expect(typeof esLogger.close).toBe('function');
|
||||
|
||||
expect(loggingSystemMock.collect(logger)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"debug": Array [],
|
||||
"error": Array [
|
||||
Array [
|
||||
"some-error",
|
||||
],
|
||||
],
|
||||
"fatal": Array [],
|
||||
"info": Array [],
|
||||
"log": Array [],
|
||||
"trace": Array [],
|
||||
"warn": Array [
|
||||
Array [
|
||||
"some-warning",
|
||||
],
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test('default logger with #logQueries = true', () => {
|
||||
const parsedConfig = parseElasticsearchClientConfig(
|
||||
{
|
||||
apiVersion: 'master',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: true,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
hosts: ['http://localhost/elasticsearch'],
|
||||
requestHeadersWhitelist: [],
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
|
||||
const esLogger = new parsedConfig.log();
|
||||
|
@ -433,11 +389,6 @@ describe('#log', () => {
|
|||
"304
|
||||
METHOD /some-path
|
||||
?query=2",
|
||||
Object {
|
||||
"tags": Array [
|
||||
"query",
|
||||
],
|
||||
},
|
||||
],
|
||||
],
|
||||
"error": Array [
|
||||
|
@ -465,14 +416,14 @@ describe('#log', () => {
|
|||
{
|
||||
apiVersion: 'master',
|
||||
customHeaders: { xsrf: 'something' },
|
||||
logQueries: true,
|
||||
sniffOnStart: false,
|
||||
sniffOnConnectionFault: false,
|
||||
hosts: ['http://localhost/elasticsearch'],
|
||||
requestHeadersWhitelist: [],
|
||||
log: customLogger,
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
|
||||
expect(parsedConfig.log).toBe(customLogger);
|
||||
|
@ -486,14 +437,14 @@ describe('#ssl', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: {},
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
requestHeadersWhitelist: [],
|
||||
ssl: { verificationMode: 'none' },
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
|
@ -527,14 +478,14 @@ describe('#ssl', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: {},
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
requestHeadersWhitelist: [],
|
||||
ssl: { verificationMode: 'certificate' },
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
);
|
||||
|
||||
// `checkServerIdentity` shouldn't check hostname when verificationMode is certificate.
|
||||
|
@ -576,14 +527,14 @@ describe('#ssl', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: {},
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
requestHeadersWhitelist: [],
|
||||
ssl: { verificationMode: 'full' },
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
|
@ -618,14 +569,14 @@ describe('#ssl', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: {},
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
requestHeadersWhitelist: [],
|
||||
ssl: { verificationMode: 'misspelled' as any },
|
||||
},
|
||||
logger.get()
|
||||
logger.get(),
|
||||
'custom-type'
|
||||
)
|
||||
).toThrowErrorMatchingInlineSnapshot(`"Unknown ssl verificationMode: misspelled"`);
|
||||
});
|
||||
|
@ -636,7 +587,6 @@ describe('#ssl', () => {
|
|||
{
|
||||
apiVersion: 'v7.0.0',
|
||||
customHeaders: {},
|
||||
logQueries: true,
|
||||
sniffOnStart: true,
|
||||
sniffOnConnectionFault: true,
|
||||
hosts: ['https://es.local'],
|
||||
|
@ -651,6 +601,7 @@ describe('#ssl', () => {
|
|||
},
|
||||
},
|
||||
logger.get(),
|
||||
'custom-type',
|
||||
{ ignoreCertAndKey: true }
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
|
|
|
@ -29,7 +29,6 @@ export type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' |
|
|||
ElasticsearchConfig,
|
||||
| 'apiVersion'
|
||||
| 'customHeaders'
|
||||
| 'logQueries'
|
||||
| 'requestHeadersWhitelist'
|
||||
| 'sniffOnStart'
|
||||
| 'sniffOnConnectionFault'
|
||||
|
@ -76,6 +75,7 @@ type ExtendedConfigOptions = ConfigOptions &
|
|||
export function parseElasticsearchClientConfig(
|
||||
config: LegacyElasticsearchClientConfig,
|
||||
log: Logger,
|
||||
type: string,
|
||||
{ ignoreCertAndKey = false, auth = true }: LegacyElasticsearchClientConfigOverrides = {}
|
||||
) {
|
||||
const esClientConfig: ExtendedConfigOptions = {
|
||||
|
@ -91,7 +91,7 @@ export function parseElasticsearchClientConfig(
|
|||
};
|
||||
|
||||
if (esClientConfig.log == null) {
|
||||
esClientConfig.log = getLoggerClass(log, config.logQueries);
|
||||
esClientConfig.log = getLoggerClass(log, type);
|
||||
}
|
||||
|
||||
if (config.pingTimeout != null) {
|
||||
|
@ -180,7 +180,9 @@ function getDurationAsMs(duration: number | Duration) {
|
|||
return duration.asMilliseconds();
|
||||
}
|
||||
|
||||
function getLoggerClass(log: Logger, logQueries = false) {
|
||||
function getLoggerClass(log: Logger, type: string) {
|
||||
const queryLogger = log.get('query', type);
|
||||
|
||||
return class ElasticsearchClientLogging {
|
||||
public error(err: string | Error) {
|
||||
log.error(err);
|
||||
|
@ -197,11 +199,7 @@ function getLoggerClass(log: Logger, logQueries = false) {
|
|||
_: unknown,
|
||||
statusCode: string
|
||||
) {
|
||||
if (logQueries) {
|
||||
log.debug(`${statusCode}\n${method} ${options.path}\n${query ? query.trim() : ''}`, {
|
||||
tags: ['query'],
|
||||
});
|
||||
}
|
||||
queryLogger.debug(`${statusCode}\n${method} ${options.path}\n${query ? query.trim() : ''}`);
|
||||
}
|
||||
|
||||
// elasticsearch-js expects the following functions to exist
|
||||
|
|
|
@ -843,7 +843,7 @@ export type ElasticsearchClient = Omit<KibanaClient, 'connectionPool' | 'transpo
|
|||
};
|
||||
|
||||
// @public
|
||||
export type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'logQueries' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password'> & {
|
||||
export type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password'> & {
|
||||
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout'];
|
||||
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout'];
|
||||
ssl?: Partial<ElasticsearchConfig['ssl']>;
|
||||
|
@ -859,7 +859,6 @@ export class ElasticsearchConfig {
|
|||
readonly healthCheckDelay: Duration;
|
||||
readonly hosts: string[];
|
||||
readonly ignoreVersionMismatch: boolean;
|
||||
readonly logQueries: boolean;
|
||||
readonly password?: string;
|
||||
readonly pingTimeout: Duration;
|
||||
readonly requestHeadersWhitelist: string[];
|
||||
|
@ -1531,7 +1530,7 @@ export interface LegacyCallAPIOptions {
|
|||
|
||||
// @public @deprecated
|
||||
export class LegacyClusterClient implements ILegacyClusterClient {
|
||||
constructor(config: LegacyElasticsearchClientConfig, log: Logger, getAuthHeaders?: GetAuthHeaders);
|
||||
constructor(config: LegacyElasticsearchClientConfig, log: Logger, type: string, getAuthHeaders?: GetAuthHeaders);
|
||||
asScoped(request?: ScopeableRequest): ILegacyScopedClusterClient;
|
||||
// @deprecated
|
||||
callAsInternalUser: LegacyAPICaller;
|
||||
|
@ -1553,7 +1552,7 @@ export interface LegacyConfig {
|
|||
}
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' | 'log' | 'plugins'> & Pick<ElasticsearchConfig, 'apiVersion' | 'customHeaders' | 'logQueries' | 'requestHeadersWhitelist' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'hosts' | 'username' | 'password'> & {
|
||||
export type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' | 'log' | 'plugins'> & Pick<ElasticsearchConfig, 'apiVersion' | 'customHeaders' | 'requestHeadersWhitelist' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'hosts' | 'username' | 'password'> & {
|
||||
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout'];
|
||||
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ConfigOptions['requestTimeout'];
|
||||
sniffInterval?: ElasticsearchConfig['sniffInterval'] | ConfigOptions['sniffInterval'];
|
||||
|
|
|
@ -30,7 +30,6 @@ export function instantiateClient(
|
|||
const cluster = createClient('monitoring', {
|
||||
...(isMonitoringCluster ? elasticsearchConfig : {}),
|
||||
plugins: [monitoringBulk, monitoringEndpointDisableWatches],
|
||||
logQueries: Boolean(elasticsearchConfig.logQueries),
|
||||
} as ESClusterConfig);
|
||||
|
||||
const configSource = isMonitoringCluster ? 'monitoring' : 'production';
|
||||
|
|
Loading…
Reference in a new issue