[APM] Shim new platform (#34531)
This commit is contained in:
parent
fcfd6e5a8d
commit
93549e6b60
|
@ -7,13 +7,9 @@
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { Server } from 'hapi';
|
import { Server } from 'hapi';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
import { CoreSetup, PluginInitializerContext } from 'src/core/server/index.js';
|
||||||
import mappings from './mappings.json';
|
import mappings from './mappings.json';
|
||||||
import { makeApmUsageCollector } from './server/lib/apm_telemetry';
|
import { plugin } from './server/new-platform/index';
|
||||||
import { initErrorsApi } from './server/routes/errors';
|
|
||||||
import { initMetricsApi } from './server/routes/metrics';
|
|
||||||
import { initServicesApi } from './server/routes/services';
|
|
||||||
import { initTracesApi } from './server/routes/traces';
|
|
||||||
import { initTransactionGroupsApi } from './server/routes/transaction_groups';
|
|
||||||
|
|
||||||
// TODO: get proper types
|
// TODO: get proper types
|
||||||
export function apm(kibana: any) {
|
export function apm(kibana: any) {
|
||||||
|
@ -73,13 +69,14 @@ export function apm(kibana: any) {
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: get proper types
|
// TODO: get proper types
|
||||||
init(server: any) {
|
init(server: Server) {
|
||||||
initTransactionGroupsApi(server);
|
const initializerContext = {} as PluginInitializerContext;
|
||||||
initTracesApi(server);
|
const core = {
|
||||||
initServicesApi(server);
|
http: {
|
||||||
initErrorsApi(server);
|
server
|
||||||
initMetricsApi(server);
|
}
|
||||||
makeApmUsageCollector(server);
|
} as CoreSetup;
|
||||||
|
plugin(initializerContext).setup(core);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,8 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import { Router } from 'react-router-dom';
|
|
||||||
import 'react-vis/dist/style.css';
|
import 'react-vis/dist/style.css';
|
||||||
|
import { CoreSetup } from 'src/core/public';
|
||||||
import 'ui/autoload/all';
|
import 'ui/autoload/all';
|
||||||
import 'ui/autoload/styles';
|
import 'ui/autoload/styles';
|
||||||
import chrome from 'ui/chrome';
|
import chrome from 'ui/chrome';
|
||||||
|
@ -17,11 +16,10 @@ import { I18nContext } from 'ui/i18n';
|
||||||
import { uiModules } from 'ui/modules';
|
import { uiModules } from 'ui/modules';
|
||||||
import 'uiExports/autocompleteProviders';
|
import 'uiExports/autocompleteProviders';
|
||||||
import { GlobalHelpExtension } from './components/app/GlobalHelpExtension';
|
import { GlobalHelpExtension } from './components/app/GlobalHelpExtension';
|
||||||
import { Main } from './components/app/Main';
|
|
||||||
import { history } from './components/shared/Links/url_helpers';
|
|
||||||
import { LocationProvider } from './context/LocationContext';
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import configureStore from './store/config/configureStore';
|
import configureStore from './store/config/configureStore';
|
||||||
|
import { plugin } from './new-platform';
|
||||||
|
import { REACT_APP_ROOT_ID } from './new-platform/plugin';
|
||||||
import './style/global_overrides.css';
|
import './style/global_overrides.css';
|
||||||
import template from './templates/index.html';
|
import template from './templates/index.html';
|
||||||
|
|
||||||
|
@ -32,34 +30,26 @@ chrome.helpExtension.set(domElement => {
|
||||||
ReactDOM.unmountComponentAtNode(domElement);
|
ReactDOM.unmountComponentAtNode(domElement);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const REACT_APP_ROOT_ID = 'react-apm-root';
|
|
||||||
|
|
||||||
type PromiseResolver = (value?: {} | PromiseLike<{}> | undefined) => void;
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
chrome.setRootTemplate(template);
|
chrome.setRootTemplate(template);
|
||||||
const store = configureStore();
|
|
||||||
const checkForRoot = (resolve: PromiseResolver) => {
|
|
||||||
const ready = !!document.getElementById(REACT_APP_ROOT_ID);
|
|
||||||
if (ready) {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
setTimeout(() => checkForRoot(resolve), 10);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const waitForRoot = new Promise(resolve => checkForRoot(resolve));
|
|
||||||
|
|
||||||
waitForRoot.then(() => {
|
const checkForRoot = () => {
|
||||||
ReactDOM.render(
|
return new Promise(resolve => {
|
||||||
<I18nContext>
|
const ready = !!document.getElementById(REACT_APP_ROOT_ID);
|
||||||
<Provider store={store}>
|
if (ready) {
|
||||||
<Router history={history}>
|
resolve();
|
||||||
<LocationProvider history={history}>
|
} else {
|
||||||
<Main />
|
setTimeout(() => resolve(checkForRoot()), 10);
|
||||||
</LocationProvider>
|
}
|
||||||
</Router>
|
});
|
||||||
</Provider>
|
};
|
||||||
</I18nContext>,
|
|
||||||
document.getElementById(REACT_APP_ROOT_ID)
|
checkForRoot().then(() => {
|
||||||
);
|
const core = {
|
||||||
|
i18n: {
|
||||||
|
Context: I18nContext
|
||||||
|
}
|
||||||
|
} as CoreSetup;
|
||||||
|
plugin().setup(core);
|
||||||
});
|
});
|
||||||
|
|
11
x-pack/plugins/apm/public/new-platform/index.tsx
Normal file
11
x-pack/plugins/apm/public/new-platform/index.tsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Plugin } from './plugin';
|
||||||
|
|
||||||
|
export function plugin() {
|
||||||
|
return new Plugin();
|
||||||
|
}
|
37
x-pack/plugins/apm/public/new-platform/plugin.tsx
Normal file
37
x-pack/plugins/apm/public/new-platform/plugin.tsx
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { Router } from 'react-router-dom';
|
||||||
|
import { CoreSetup } from 'src/core/public';
|
||||||
|
import { Main } from '../components/app/Main';
|
||||||
|
import { history } from '../components/shared/Links/url_helpers';
|
||||||
|
import { LocationProvider } from '../context/LocationContext';
|
||||||
|
// @ts-ignore
|
||||||
|
import configureStore from '../store/config/configureStore';
|
||||||
|
|
||||||
|
export const REACT_APP_ROOT_ID = 'react-apm-root';
|
||||||
|
|
||||||
|
export class Plugin {
|
||||||
|
public setup(core: CoreSetup) {
|
||||||
|
const { i18n } = core;
|
||||||
|
const store = configureStore();
|
||||||
|
ReactDOM.render(
|
||||||
|
<i18n.Context>
|
||||||
|
<Provider store={store}>
|
||||||
|
<Router history={history}>
|
||||||
|
<LocationProvider history={history}>
|
||||||
|
<Main />
|
||||||
|
</LocationProvider>
|
||||||
|
</Router>
|
||||||
|
</Provider>
|
||||||
|
</i18n.Context>,
|
||||||
|
document.getElementById(REACT_APP_ROOT_ID)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Server } from 'hapi';
|
import { CoreSetup } from 'src/core/server';
|
||||||
import {
|
import {
|
||||||
APM_TELEMETRY_DOC_ID,
|
APM_TELEMETRY_DOC_ID,
|
||||||
createApmTelementry,
|
createApmTelementry,
|
||||||
|
@ -12,16 +12,22 @@ import {
|
||||||
} from './apm_telemetry';
|
} from './apm_telemetry';
|
||||||
|
|
||||||
// TODO this type should be defined by the platform
|
// TODO this type should be defined by the platform
|
||||||
interface KibanaHapiServer extends Server {
|
export interface CoreSetupWithUsageCollector extends CoreSetup {
|
||||||
usage: {
|
http: CoreSetup['http'] & {
|
||||||
collectorSet: {
|
server: {
|
||||||
makeUsageCollector: (options: unknown) => unknown;
|
usage: {
|
||||||
register: (options: unknown) => unknown;
|
collectorSet: {
|
||||||
|
makeUsageCollector: (options: unknown) => unknown;
|
||||||
|
register: (options: unknown) => unknown;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeApmUsageCollector(server: KibanaHapiServer): void {
|
export function makeApmUsageCollector(core: CoreSetupWithUsageCollector) {
|
||||||
|
const { server } = core.http;
|
||||||
|
|
||||||
const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({
|
const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({
|
||||||
type: 'apm',
|
type: 'apm',
|
||||||
fetch: async () => {
|
fetch: async () => {
|
||||||
|
|
12
x-pack/plugins/apm/server/new-platform/index.ts
Normal file
12
x-pack/plugins/apm/server/new-platform/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { PluginInitializerContext } from 'src/core/server';
|
||||||
|
import { Plugin } from './plugin';
|
||||||
|
|
||||||
|
export function plugin(initializerContext: PluginInitializerContext) {
|
||||||
|
return new Plugin();
|
||||||
|
}
|
25
x-pack/plugins/apm/server/new-platform/plugin.ts
Normal file
25
x-pack/plugins/apm/server/new-platform/plugin.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { CoreSetup } from 'src/core/server';
|
||||||
|
import { makeApmUsageCollector } from '../lib/apm_telemetry';
|
||||||
|
import { CoreSetupWithUsageCollector } from '../lib/apm_telemetry/make_apm_usage_collector';
|
||||||
|
import { initErrorsApi } from '../routes/errors';
|
||||||
|
import { initMetricsApi } from '../routes/metrics';
|
||||||
|
import { initServicesApi } from '../routes/services';
|
||||||
|
import { initTracesApi } from '../routes/traces';
|
||||||
|
import { initTransactionGroupsApi } from '../routes/transaction_groups';
|
||||||
|
|
||||||
|
export class Plugin {
|
||||||
|
public setup(core: CoreSetup) {
|
||||||
|
initTransactionGroupsApi(core);
|
||||||
|
initTracesApi(core);
|
||||||
|
initServicesApi(core);
|
||||||
|
initErrorsApi(core);
|
||||||
|
initMetricsApi(core);
|
||||||
|
makeApmUsageCollector(core as CoreSetupWithUsageCollector);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,8 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Server } from 'hapi';
|
|
||||||
import { flatten } from 'lodash';
|
import { flatten } from 'lodash';
|
||||||
|
import { CoreSetup } from 'src/core/server';
|
||||||
import { initErrorsApi } from '../errors';
|
import { initErrorsApi } from '../errors';
|
||||||
import { initServicesApi } from '../services';
|
import { initServicesApi } from '../services';
|
||||||
import { initTracesApi } from '../traces';
|
import { initTracesApi } from '../traces';
|
||||||
|
@ -13,9 +13,14 @@ import { initTracesApi } from '../traces';
|
||||||
describe('route handlers should fail with a Boom error', () => {
|
describe('route handlers should fail with a Boom error', () => {
|
||||||
let consoleErrorSpy: any;
|
let consoleErrorSpy: any;
|
||||||
|
|
||||||
async function testRouteFailures(init: (server: Server) => void) {
|
async function testRouteFailures(init: (core: CoreSetup) => void) {
|
||||||
const mockServer = { route: jest.fn() };
|
const mockServer = { route: jest.fn() };
|
||||||
init((mockServer as unknown) as Server);
|
const mockCore = ({
|
||||||
|
http: {
|
||||||
|
server: mockServer
|
||||||
|
}
|
||||||
|
} as unknown) as CoreSetup;
|
||||||
|
init(mockCore);
|
||||||
expect(mockServer.route).toHaveBeenCalled();
|
expect(mockServer.route).toHaveBeenCalled();
|
||||||
|
|
||||||
const mockCluster = {
|
const mockCluster = {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Boom from 'boom';
|
import Boom from 'boom';
|
||||||
import { Server } from 'hapi';
|
|
||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
import { Legacy } from 'kibana';
|
import { Legacy } from 'kibana';
|
||||||
|
import { CoreSetup } from 'src/core/server';
|
||||||
import { getDistribution } from '../lib/errors/distribution/get_distribution';
|
import { getDistribution } from '../lib/errors/distribution/get_distribution';
|
||||||
import { getErrorGroup } from '../lib/errors/get_error_group';
|
import { getErrorGroup } from '../lib/errors/get_error_group';
|
||||||
import { getErrorGroups } from '../lib/errors/get_error_groups';
|
import { getErrorGroups } from '../lib/errors/get_error_groups';
|
||||||
|
@ -21,7 +21,8 @@ const defaultErrorHandler = (err: Error) => {
|
||||||
throw Boom.boomify(err, { statusCode: 400 });
|
throw Boom.boomify(err, { statusCode: 400 });
|
||||||
};
|
};
|
||||||
|
|
||||||
export function initErrorsApi(server: Server) {
|
export function initErrorsApi(core: CoreSetup) {
|
||||||
|
const { server } = core.http;
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: ROOT,
|
path: ROOT,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Boom from 'boom';
|
import Boom from 'boom';
|
||||||
import { Server } from 'hapi';
|
import { CoreSetup } from 'src/core/server';
|
||||||
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
||||||
import { setupRequest } from '../lib/helpers/setup_request';
|
import { setupRequest } from '../lib/helpers/setup_request';
|
||||||
import { getAllMetricsChartData } from '../lib/metrics/get_all_metrics_chart_data';
|
import { getAllMetricsChartData } from '../lib/metrics/get_all_metrics_chart_data';
|
||||||
|
@ -16,7 +16,8 @@ const defaultErrorHandler = (err: Error) => {
|
||||||
throw Boom.boomify(err, { statusCode: 400 });
|
throw Boom.boomify(err, { statusCode: 400 });
|
||||||
};
|
};
|
||||||
|
|
||||||
export function initMetricsApi(server: Server) {
|
export function initMetricsApi(core: CoreSetup) {
|
||||||
|
const { server } = core.http;
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: `/api/apm/services/{serviceName}/metrics/charts`,
|
path: `/api/apm/services/{serviceName}/metrics/charts`,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Boom from 'boom';
|
import Boom from 'boom';
|
||||||
import { Server } from 'hapi';
|
import { CoreSetup } from 'src/core/server';
|
||||||
import { AgentName } from '../../typings/es_schemas/ui/fields/Agent';
|
import { AgentName } from '../../typings/es_schemas/ui/fields/Agent';
|
||||||
import { createApmTelementry, storeApmTelemetry } from '../lib/apm_telemetry';
|
import { createApmTelementry, storeApmTelemetry } from '../lib/apm_telemetry';
|
||||||
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
||||||
|
@ -20,7 +20,8 @@ const defaultErrorHandler = (err: Error) => {
|
||||||
throw Boom.boomify(err, { statusCode: 400 });
|
throw Boom.boomify(err, { statusCode: 400 });
|
||||||
};
|
};
|
||||||
|
|
||||||
export function initServicesApi(server: Server) {
|
export function initServicesApi(core: CoreSetup) {
|
||||||
|
const { server } = core.http;
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: ROOT,
|
path: ROOT,
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Boom from 'boom';
|
import Boom from 'boom';
|
||||||
import { Server } from 'hapi';
|
|
||||||
|
import { CoreSetup } from 'src/core/server';
|
||||||
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
||||||
import { setupRequest } from '../lib/helpers/setup_request';
|
import { setupRequest } from '../lib/helpers/setup_request';
|
||||||
import { getTopTraces } from '../lib/traces/get_top_traces';
|
import { getTopTraces } from '../lib/traces/get_top_traces';
|
||||||
|
@ -18,7 +19,9 @@ const defaultErrorHandler = (err: Error) => {
|
||||||
throw Boom.boomify(err, { statusCode: 400 });
|
throw Boom.boomify(err, { statusCode: 400 });
|
||||||
};
|
};
|
||||||
|
|
||||||
export function initTracesApi(server: Server) {
|
export function initTracesApi(core: CoreSetup) {
|
||||||
|
const { server } = core.http;
|
||||||
|
|
||||||
// Get trace list
|
// Get trace list
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Boom from 'boom';
|
import Boom from 'boom';
|
||||||
import { Server } from 'hapi';
|
|
||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
|
import { CoreSetup } from 'src/core/server';
|
||||||
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
import { withDefaultValidators } from '../lib/helpers/input_validation';
|
||||||
import { setupRequest } from '../lib/helpers/setup_request';
|
import { setupRequest } from '../lib/helpers/setup_request';
|
||||||
import { getChartsData } from '../lib/transactions/charts';
|
import { getChartsData } from '../lib/transactions/charts';
|
||||||
|
@ -19,7 +19,9 @@ const defaultErrorHandler = (err: Error) => {
|
||||||
throw Boom.boomify(err, { statusCode: 400 });
|
throw Boom.boomify(err, { statusCode: 400 });
|
||||||
};
|
};
|
||||||
|
|
||||||
export function initTransactionGroupsApi(server: Server) {
|
export function initTransactionGroupsApi(core: CoreSetup) {
|
||||||
|
const { server } = core.http;
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path:
|
path:
|
||||||
|
|
Loading…
Reference in a new issue