Skip to content

Commit ffacd65

Browse files
committed
load apm-agent-lazily
1 parent fdee5e5 commit ffacd65

File tree

2 files changed

+95
-45
lines changed

2 files changed

+95
-45
lines changed

src/core/public/apm_system.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
/**
21+
* This is the entry point used to boot the frontend when serving a application
22+
* that lives in the Kibana Platform.
23+
*
24+
* Any changes to this file should be kept in sync with
25+
* src/legacy/ui/ui_bundles/app_entry_template.js
26+
*/
27+
import type { InternalApplicationStart } from './application';
28+
29+
interface ApmConfig {
30+
// AgentConfigOptions is not exported from @elastic/apm-rum
31+
globalLabels?: Record<string, string>;
32+
}
33+
34+
interface StartDeps {
35+
application: InternalApplicationStart;
36+
}
37+
38+
export class ApmSystem {
39+
private readonly enabled: boolean;
40+
/**
41+
* `apmConfig` would be populated with relevant APM RUM agent
42+
* configuration if server is started with `ELASTIC_APM_ACTIVE=true`
43+
*/
44+
constructor(private readonly apmConfig?: ApmConfig) {
45+
this.enabled = process.env.IS_KIBANA_DISTRIBUTABLE !== 'true' && apmConfig != null;
46+
}
47+
48+
async setup() {
49+
if (!this.enabled) return;
50+
const { init, apm } = await import('@elastic/apm-rum');
51+
const { globalLabels, ...apmConfig } = this.apmConfig!;
52+
if (globalLabels) {
53+
apm.addLabels(globalLabels);
54+
}
55+
56+
init(apmConfig);
57+
}
58+
59+
async start(start?: StartDeps) {
60+
if (!this.enabled || !start) return;
61+
/**
62+
* Register listeners for navigation changes and capture them as
63+
* route-change transactions after Kibana app is bootstrapped
64+
*/
65+
start.application.currentAppId$.subscribe((appId) => {
66+
const apmInstance = (window as any).elasticApm;
67+
if (appId && apmInstance && typeof apmInstance.startTransaction === 'function') {
68+
apmInstance.startTransaction(`/app/${appId}`, 'route-change', {
69+
managed: true,
70+
canReuse: true,
71+
});
72+
}
73+
});
74+
}
75+
}

src/core/public/kbn_bootstrap.ts

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,60 +27,35 @@
2727

2828
import { i18n } from '@kbn/i18n';
2929
import { CoreSystem } from './core_system';
30+
import { ApmSystem } from './apm_system';
3031

3132
/** @internal */
32-
export function __kbnBootstrap__() {
33+
export async function __kbnBootstrap__() {
3334
const injectedMetadata = JSON.parse(
3435
document.querySelector('kbn-injected-metadata')!.getAttribute('data')!
3536
);
3637

37-
/**
38-
* `apmConfig` would be populated with relavant APM RUM agent
39-
* configuration if server is started with `ELASTIC_APM_ACTIVE=true`
40-
*/
41-
const apmConfig = injectedMetadata.vars.apmConfig;
42-
const APM_ENABLED = process.env.IS_KIBANA_DISTRIBUTABLE !== 'true' && apmConfig != null;
38+
const apmSystem = new ApmSystem(injectedMetadata.vars.apmConfig);
39+
await apmSystem.setup();
4340

44-
if (APM_ENABLED) {
45-
// eslint-disable-next-line @typescript-eslint/no-var-requires
46-
const { init, apm } = require('@elastic/apm-rum');
47-
if (apmConfig.globalLabels) {
48-
apm.addLabels(apmConfig.globalLabels);
49-
}
50-
init(apmConfig);
41+
let i18nError: Error | undefined;
42+
try {
43+
await i18n.load(injectedMetadata.i18n.translationsUrl);
44+
} catch (error) {
45+
i18nError = error;
5146
}
5247

53-
i18n
54-
.load(injectedMetadata.i18n.translationsUrl)
55-
.catch((e) => e)
56-
.then(async (i18nError) => {
57-
const coreSystem = new CoreSystem({
58-
injectedMetadata,
59-
rootDomElement: document.body,
60-
browserSupportsCsp: !(window as any).__kbnCspNotEnforced__,
61-
});
48+
const coreSystem = new CoreSystem({
49+
injectedMetadata,
50+
rootDomElement: document.body,
51+
browserSupportsCsp: !(window as any).__kbnCspNotEnforced__,
52+
});
6253

63-
const setup = await coreSystem.setup();
64-
if (i18nError && setup) {
65-
setup.fatalErrors.add(i18nError);
66-
}
67-
68-
const start = await coreSystem.start();
54+
const setup = await coreSystem.setup();
55+
if (i18nError && setup) {
56+
setup.fatalErrors.add(i18nError);
57+
}
6958

70-
if (APM_ENABLED && start) {
71-
/**
72-
* Register listeners for navigation changes and capture them as
73-
* route-change transactions after Kibana app is bootstrapped
74-
*/
75-
start.application.currentAppId$.subscribe((appId) => {
76-
const apmInstance = (window as any).elasticApm;
77-
if (appId && apmInstance && typeof apmInstance.startTransaction === 'function') {
78-
apmInstance.startTransaction(`/app/${appId}`, 'route-change', {
79-
managed: true,
80-
canReuse: true,
81-
});
82-
}
83-
});
84-
}
85-
});
59+
const start = await coreSystem.start();
60+
await apmSystem.start(start);
8661
}

0 commit comments

Comments
 (0)