Skip to content

Commit

Permalink
Instrument CLI with APM
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Smalley <[email protected]>
  • Loading branch information
Tyler Smalley committed Sep 1, 2020
1 parent 9a27beb commit cd8dfd9
Show file tree
Hide file tree
Showing 32 changed files with 53,096 additions and 19,949 deletions.
34 changes: 34 additions & 0 deletions packages/kbn-apm/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import Agent from 'elastic-apm-node';

export const isKibanaDistributable: boolean;

export function start(options?: any): typeof Agent;

export function active(): boolean;

export function addSystemLabels(): undefined;

export function getConfig(options?: any): any;

export function flush(): Promise<undefined>;

export { Agent };
91 changes: 91 additions & 0 deletions packages/kbn-apm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

const os = require('os');
const { resolve } = require('path');
const { readFileSync } = require('fs');
const { execSync } = require('child_process');

const Agent = require('elastic-apm-node');
const { REPO_ROOT, readKibanaPackageJSON } = require('@kbn/utils');

const { version, build } = readKibanaPackageJSON();

function gitRev() {
try {
return execSync('git rev-parse --short HEAD', {
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'ignore'],
})
.toString()
.trim();
} catch (e) {
return null;
}
}

const config = {
secretToken: 'VCRNqoV777Vs3mJ1VF',
serverUrl: 'https://b60e8f2199cf4713b3a11b3fce770101.apm.us-west1.gcp.cloud.es.io:443',
environment: process.env.ELASTIC_APM_ENVIRONMENT,
serviceName: 'kibana',
serviceVersion: version,
globalLabels: {
os_kernel: os.release(),
system_cpu_cores: os.cpus().length,
system_cpu_name: os.cpus()[0].model,
system_cpu_speed: os.cpus()[0].speed,
},
centralConfig: false,
logUncaughtExceptions: true,
active: process.env.ELASTIC_APM_ACTIVE || 'false',
};

function active() {
return config.active;
}

try {
const filename = resolve(REPO_ROOT, 'data', 'uuid');
config.globalLabels.kibana_uuid = readFileSync(filename, 'utf-8');
} catch (e) {} // eslint-disable-line no-empty

const rev = gitRev();
if (rev !== null) config.globalLabels.git_rev = rev;

module.exports.config = config;

module.exports.isKibanaDistributable = Boolean(build && build.distributable === true);

module.exports.active = active;

module.exports.start = function start(options = {}) {
if (process.env.kbnWorkerType === 'optmzr') return;

Agent.start({ ...config, ...options });
return Agent;
};

module.exports.flush = function flush() {
return new Promise((resolve) => {
active() ? Agent.flush(resolve) : resolve();
});
};

module.exports.Agent = Agent;
13 changes: 13 additions & 0 deletions packages/kbn-apm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@kbn/apm",
"private": true,
"version": "1.0.0",
"description": "Kibana APM profiling",
"main": "index.js",
"types": "index.d.ts",
"license": "Apache-2.0",
"dependencies": {
"@kbn/utils": "1.0.0",
"elastic-apm-node": "^3.7.0"
}
}
6 changes: 6 additions & 0 deletions packages/kbn-apm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.json",
"include": [
"index.d.ts"
],
}
1 change: 1 addition & 0 deletions packages/kbn-apm/yarn.lock
1 change: 1 addition & 0 deletions packages/kbn-dev-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@babel/core": "^7.11.1",
"@kbn/utils": "1.0.0",
"axios": "^0.19.0",
"chalk": "^4.1.0",
"cheerio": "0.22.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-dev-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

export { REPO_ROOT } from '@kbn/utils';
export { withProcRunner, ProcRunner } from './proc_runner';
export * from './tooling_log';
export * from './serializers';
Expand All @@ -33,7 +34,6 @@ export {
KBN_P12_PATH,
KBN_P12_PASSWORD,
} from './certs';
export { REPO_ROOT } from './repo_root';
export { KbnClient } from './kbn_client';
export * from './run';
export * from './axios';
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-dev-utils/src/plugin_list/discover_plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import Fs from 'fs';

import MarkdownIt from 'markdown-it';
import cheerio from 'cheerio';
import { REPO_ROOT } from '@kbn/utils';

import { REPO_ROOT } from '../repo_root';
import { simpleKibanaPlatformPluginDiscovery } from '../simple_kibana_platform_plugin_discovery';
import { extractAsciidocInfo } from './extract_asciidoc_info';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import Path from 'path';

import normalizePath from 'normalize-path';
import { REPO_ROOT } from '@kbn/utils';

import { REPO_ROOT } from '../repo_root';
import { Plugins } from './discover_plugins';

function* printPlugins(plugins: Plugins, includes: string[]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@

import Path from 'path';
import Fs from 'fs';
import { REPO_ROOT } from '@kbn/utils';

import { run } from '../run';
import { REPO_ROOT } from '../repo_root';

import { discoverPlugins } from './discover_plugins';
import { generatePluginList } from './generate_plugin_list';

Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-dev-utils/src/precommit_hook/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import Path from 'path';
import { chmod, writeFile } from 'fs';
import { promisify } from 'util';
import { REPO_ROOT } from '@kbn/utils';

import { run } from '../run';
import { REPO_ROOT } from '../repo_root';
import { SCRIPT_SOURCE } from './script_source';
import { getGitDir } from './get_git_dir';

Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-dev-utils/src/precommit_hook/get_git_dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import execa from 'execa';

import { REPO_ROOT } from '../repo_root';
import { REPO_ROOT } from '@kbn/utils';

// Retrieves the correct location for the .git dir for
// every git setup (including git worktree)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { REPO_ROOT } from '../repo_root';
import { REPO_ROOT } from '@kbn/utils';

export function createAbsolutePathSerializer(
rootPath: string = REPO_ROOT,
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-optimizer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@babel/cli": "^7.10.5",
"@kbn/apm": "1.0.0",
"@kbn/babel-preset": "1.0.0",
"@kbn/dev-utils": "1.0.0",
"@kbn/ui-shared-deps": "1.0.0",
Expand Down
84 changes: 84 additions & 0 deletions packages/kbn-optimizer/src/apm_optimizer_stats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { Agent } from '@kbn/apm';
import { tap } from 'rxjs/operators';

import { OptimizerConfig } from './optimizer';
import { OptimizerUpdate$ } from './run_optimizer';
import { pipeClosure } from './common';

export function apmOptimizerStats(config: OptimizerConfig) {
return pipeClosure((update$: OptimizerUpdate$) => {
let loggedInit = false;
let trans: any;

return update$.pipe(
tap(async (update) => {
const { state } = update;

if (state.phase === 'initialized') {
if (!loggedInit) {
loggedInit = true;

trans = Agent.startTransaction('@kbn/optimizer', 'cli');

const bundlesCount = state.onlineBundles.length + state.offlineBundles.length;
Agent.addLabels({
optimizer_bundle_count: bundlesCount,
optimizer_bundle_cache_count: state.offlineBundles.length,
optimizer_bundle_cache_pct: Math.round(
(state.offlineBundles.length / bundlesCount) * 100
),
optimizer_watch: config.watch,
optimizer_production: config.dist,
optimizer_profile_webpack: config.profileWebpack,
optimizer_bundle_theme_tags_count: config.themeTags.length,
optimizer_cache: config.cache,
optimizer_max_worker_count: config.maxWorkerCount,
});
}

return;
}

if (state.phase === 'issue') {
for (const b of state.compilerStates) {
if (b.type === 'compiler issue') {
Agent.captureError(b.failure, {
custom: {
optimizer_bundle_id: b.bundleId,
},
});
}
}
return;
}

if (state.phase === 'success') {
if (trans) {
trans.end();
}

return;
}
})
);
});
}
14 changes: 14 additions & 0 deletions packages/kbn-optimizer/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@
* under the License.
*/

import apm from '@kbn/apm';

apm.start({
metricsInterval: 1,
metricsLimit: 1,
});

import 'source-map-support/register';

import Path from 'path';

import { run, REPO_ROOT, createFlagError, CiStatsReporter } from '@kbn/dev-utils';

import { logOptimizerState } from './log_optimizer_state';
import { apmOptimizerStats } from './apm_optimizer_stats';
import { OptimizerConfig } from './optimizer';
import { reportOptimizerStats } from './report_optimizer_stats';
import { runOptimizer } from './run_optimizer';
Expand Down Expand Up @@ -119,7 +127,13 @@ run(
update$ = update$.pipe(reportOptimizerStats(reporter, config, log));
}

update$ = update$.pipe(apmOptimizerStats(config));

await update$.pipe(logOptimizerState(log, config)).toPromise();
await apm.flush();

// TODO: It appears the cb is called BEFORE the API request in flush
await new Promise((resolve) => setTimeout(resolve, 1000));
},
{
flags: {
Expand Down
Loading

0 comments on commit cd8dfd9

Please sign in to comment.