diff --git a/packages/kbn-apm-config-loader/src/config.test.ts b/packages/kbn-apm-config-loader/src/config.test.ts index e955b175de129..01f83d43f160d 100644 --- a/packages/kbn-apm-config-loader/src/config.test.ts +++ b/packages/kbn-apm-config-loader/src/config.test.ts @@ -146,6 +146,35 @@ describe('ApmConfiguration', () => { ); }); + it('flattens the `globalLabels` object', () => { + const kibanaConfig = { + elastic: { + apm: { + globalLabels: { + keyOne: 'k1', + objectOne: { + objectOneKeyOne: 'o1k1', + objectOneKeyTwo: { + objectOneKeyTwoSubkeyOne: 'o1k2s1', + }, + }, + }, + }, + }, + }; + const config = new ApmConfiguration(mockedRootDir, kibanaConfig, true); + expect(config.getConfig('serviceName')).toEqual( + expect.objectContaining({ + globalLabels: { + git_rev: 'sha', + keyOne: 'k1', + 'objectOne.objectOneKeyOne': 'o1k1', + 'objectOne.objectOneKeyTwo.objectOneKeyTwoSubkeyOne': 'o1k2s1', + }, + }) + ); + }); + describe('env vars', () => { beforeEach(() => { delete process.env.ELASTIC_APM_ENVIRONMENT; diff --git a/packages/kbn-apm-config-loader/src/config.ts b/packages/kbn-apm-config-loader/src/config.ts index 8771eb042dc75..ef5f41bb8398e 100644 --- a/packages/kbn-apm-config-loader/src/config.ts +++ b/packages/kbn-apm-config-loader/src/config.ts @@ -13,6 +13,7 @@ import { getDataPath } from '@kbn/utils'; import { readFileSync } from 'fs'; import type { AgentConfigOptions } from 'elastic-apm-node'; import type { AgentConfigOptions as RUMAgentConfigOptions } from '@elastic/apm-rum'; +import { getFlattenedObject } from '@kbn/std'; import type { ApmConfigSchema } from './apm_config'; // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html @@ -129,6 +130,15 @@ export class ApmConfiguration { ) { this.baseConfig = merge(this.baseConfig, centralizedConfig); } + + if (this.baseConfig?.globalLabels) { + // Global Labels need to be a key/value pair... + // Dotted names will be renamed to underscored ones by the agent, but we need to provide key/value pairs + // https://github.com/elastic/apm-agent-nodejs/issues/4096#issuecomment-2181621221 + this.baseConfig.globalLabels = getFlattenedObject( + this.baseConfig.globalLabels as Record + ); + } } return this.baseConfig;