mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[APM Tracing config] Allow per-service overrides (#166184)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
ab073a6d3d
commit
639d9547a6
3 changed files with 82 additions and 7 deletions
|
@ -6,14 +6,22 @@
|
||||||
* Side Public License, v 1.
|
* Side Public License, v 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { schema } from '@kbn/config-schema';
|
import { schema, TypeOf } from '@kbn/config-schema';
|
||||||
|
|
||||||
export const apmConfigSchema = schema.object(
|
export type ApmConfigSchema = TypeOf<typeof apmConfigSchema>;
|
||||||
|
|
||||||
|
const apmReusableConfigSchema = schema.object(
|
||||||
{
|
{
|
||||||
active: schema.maybe(schema.boolean()),
|
active: schema.maybe(schema.boolean()),
|
||||||
serverUrl: schema.maybe(schema.uri()),
|
serverUrl: schema.maybe(schema.uri()),
|
||||||
secretToken: schema.maybe(schema.string()),
|
secretToken: schema.maybe(schema.string()),
|
||||||
globalLabels: schema.object({}, { unknowns: 'allow' }),
|
apiKey: schema.maybe(schema.string()),
|
||||||
|
environment: schema.maybe(schema.string()),
|
||||||
|
globalLabels: schema.maybe(schema.object({}, { unknowns: 'allow' })),
|
||||||
},
|
},
|
||||||
{ unknowns: 'allow' }
|
{ unknowns: 'allow' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const apmConfigSchema = apmReusableConfigSchema.extends({
|
||||||
|
servicesOverrides: schema.maybe(schema.recordOf(schema.string(), apmReusableConfigSchema)),
|
||||||
|
});
|
||||||
|
|
|
@ -359,5 +359,50 @@ describe('ApmConfiguration', () => {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allows overriding some services settings', () => {
|
||||||
|
const kibanaConfig = {
|
||||||
|
elastic: {
|
||||||
|
apm: {
|
||||||
|
active: true,
|
||||||
|
serverUrl: 'http://an.internal.apm.server:port/',
|
||||||
|
transactionSampleRate: 0.1,
|
||||||
|
servicesOverrides: {
|
||||||
|
externalServiceName: {
|
||||||
|
active: false,
|
||||||
|
serverUrl: 'http://a.public.apm.server:port/',
|
||||||
|
disableSend: true, // just adding an extra field to prove merging works
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const internalService = new ApmConfiguration(mockedRootDir, kibanaConfig, true).getConfig(
|
||||||
|
'internalServiceName'
|
||||||
|
);
|
||||||
|
expect(internalService).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
active: true,
|
||||||
|
serverUrl: 'http://an.internal.apm.server:port/',
|
||||||
|
transactionSampleRate: 0.1,
|
||||||
|
serviceName: 'internalServiceName',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(internalService).not.toHaveProperty('disableSend');
|
||||||
|
expect(internalService).not.toHaveProperty('servicesOverrides'); // We don't want to leak this to the client's config
|
||||||
|
|
||||||
|
expect(
|
||||||
|
new ApmConfiguration(mockedRootDir, kibanaConfig, true).getConfig('externalServiceName')
|
||||||
|
).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
active: false,
|
||||||
|
serverUrl: 'http://a.public.apm.server:port/',
|
||||||
|
transactionSampleRate: 0.1,
|
||||||
|
disableSend: true,
|
||||||
|
serviceName: 'externalServiceName',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { getDataPath } from '@kbn/utils';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import type { AgentConfigOptions } from 'elastic-apm-node';
|
import type { AgentConfigOptions } from 'elastic-apm-node';
|
||||||
import type { AgentConfigOptions as RUMAgentConfigOptions } from '@elastic/apm-rum';
|
import type { AgentConfigOptions as RUMAgentConfigOptions } from '@elastic/apm-rum';
|
||||||
|
import type { ApmConfigSchema } from './apm_config';
|
||||||
|
|
||||||
// https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html
|
// https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html
|
||||||
const DEFAULT_CONFIG: AgentConfigOptions = {
|
const DEFAULT_CONFIG: AgentConfigOptions = {
|
||||||
|
@ -49,6 +50,18 @@ const CENTRALIZED_SERVICE_DIST_CONFIG: AgentConfigOptions = {
|
||||||
transactionSampleRate: 0.1,
|
transactionSampleRate: 0.1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface KibanaRawConfig {
|
||||||
|
elastic?: {
|
||||||
|
apm?: ApmConfigSchema;
|
||||||
|
};
|
||||||
|
path?: {
|
||||||
|
data?: string;
|
||||||
|
};
|
||||||
|
server?: {
|
||||||
|
uuid?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export class ApmConfiguration {
|
export class ApmConfiguration {
|
||||||
private baseConfig?: AgentConfigOptions;
|
private baseConfig?: AgentConfigOptions;
|
||||||
private kibanaVersion: string;
|
private kibanaVersion: string;
|
||||||
|
@ -56,7 +69,7 @@ export class ApmConfiguration {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly rootDir: string,
|
private readonly rootDir: string,
|
||||||
private readonly rawKibanaConfig: Record<string, any>,
|
private readonly rawKibanaConfig: KibanaRawConfig,
|
||||||
private readonly isDistributable: boolean
|
private readonly isDistributable: boolean
|
||||||
) {
|
) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
@ -66,10 +79,19 @@ export class ApmConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getConfig(serviceName: string): AgentConfigOptions {
|
public getConfig(serviceName: string): AgentConfigOptions {
|
||||||
return {
|
const { servicesOverrides = {} } = this.getConfigFromKibanaConfig();
|
||||||
|
|
||||||
|
let baseConfig = {
|
||||||
...this.getBaseConfig(),
|
...this.getBaseConfig(),
|
||||||
serviceName,
|
serviceName,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const serviceOverride = servicesOverrides[serviceName];
|
||||||
|
if (serviceOverride) {
|
||||||
|
baseConfig = merge({}, baseConfig, serviceOverride);
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getBaseConfig() {
|
private getBaseConfig() {
|
||||||
|
@ -166,7 +188,7 @@ export class ApmConfiguration {
|
||||||
* Get the elastic.apm configuration from the --config file, supersedes the
|
* Get the elastic.apm configuration from the --config file, supersedes the
|
||||||
* default config.
|
* default config.
|
||||||
*/
|
*/
|
||||||
private getConfigFromKibanaConfig(): AgentConfigOptions {
|
private getConfigFromKibanaConfig(): ApmConfigSchema {
|
||||||
return this.rawKibanaConfig?.elastic?.apm ?? {};
|
return this.rawKibanaConfig?.elastic?.apm ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +288,7 @@ export class ApmConfiguration {
|
||||||
* Reads APM configuration from different sources and merges them together.
|
* Reads APM configuration from different sources and merges them together.
|
||||||
*/
|
*/
|
||||||
private getConfigFromAllSources(): AgentConfigOptions {
|
private getConfigFromAllSources(): AgentConfigOptions {
|
||||||
const configFromKibanaConfig = this.getConfigFromKibanaConfig();
|
const { servicesOverrides, ...configFromKibanaConfig } = this.getConfigFromKibanaConfig();
|
||||||
const configFromEnv = this.getConfigFromEnv(configFromKibanaConfig);
|
const configFromEnv = this.getConfigFromEnv(configFromKibanaConfig);
|
||||||
const config = merge({}, configFromKibanaConfig, configFromEnv);
|
const config = merge({}, configFromKibanaConfig, configFromEnv);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue