Skip to content

Commit

Permalink
[Monitoring] Usage collection (#75878) (#78537)
Browse files Browse the repository at this point in the history
* First stab at some internal telemetry

* Add missing files

* mbCount telemetry

* Include more data

* Remove unused field

* This file isn't used

* Mock in tests

* Add schema

* Store schema

* Use sample cluster instead

* Fix telemetry schema

* Fix type issues

* Updates

* Fix schema and tests

* Add tests

* Add tests

* Go back to using an array

* Fix schema

* Add page view data

* Remove debug

* Handle loading scenario here

* Add delay tracking too

* Add clicks for setup mode

* Add clicks for setup mode

* Fix beats/apm page views

* Fix typings
# Conflicts:
#	x-pack/plugins/monitoring/common/constants.ts
  • Loading branch information
chrisronline authored Sep 25, 2020
1 parent bc3e3e7 commit ee7f104
Show file tree
Hide file tree
Showing 48 changed files with 1,287 additions and 119 deletions.
7 changes: 7 additions & 0 deletions x-pack/plugins/monitoring/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,10 @@ export const ALERT_EMAIL_SERVICES = ['gmail', 'hotmail', 'icloud', 'outlook365',

export const MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS = 'monitoring:alertingEmailAddress';
export const XPACK_DEFAULT_ADMIN_EMAIL_UI_SETTING = 'xPack:defaultAdminEmail';

/**
* The saved object type for various monitoring data
*/
export const SAVED_OBJECT_TELEMETRY = 'monitoring-telemetry';

export const TELEMETRY_METRIC_BUTTON_CLICK = 'btnclick__';
3 changes: 2 additions & 1 deletion x-pack/plugins/monitoring/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"triggers_actions_ui",
"alerts",
"actions",
"encryptedSavedObjects"
"encryptedSavedObjects",
"observability"
],
"optionalPlugins": ["infra", "telemetryCollectionManager", "usageCollection", "home", "cloud"],
"server": true,
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/monitoring/public/angular/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export class AngularApp {
pluginInitializerContext,
externalConfig,
triggersActionsUi,
usageCollection,
kibanaLegacy,
} = deps;
const app: IModule = localAppModule(deps);
Expand All @@ -42,6 +43,7 @@ export class AngularApp {
externalConfig,
kibanaLegacy,
triggersActionsUi,
usageCollection,
},
this.injector
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import './page_loading.scss';
import { useTrackPageview } from '../../../../observability/public';

export function PageLoading() {
function PageLoadingUI() {
return (
<EuiPage style={{ height: 'calc(100vh - 50px)' }}>
<EuiPageBody>
Expand Down Expand Up @@ -45,3 +46,18 @@ export function PageLoading() {
</EuiPage>
);
}

function PageLoadingTracking({ pageViewTitle }) {
const path = pageViewTitle.toLowerCase().replace(/-/g, '').replace(/\s+/g, '_');
useTrackPageview({ app: 'stack_monitoring', path });
useTrackPageview({ app: 'stack_monitoring', path, delay: 15000 });
return <PageLoadingUI />;
}

export function PageLoading({ pageViewTitle }) {
if (pageViewTitle) {
return <PageLoadingTracking pageViewTitle={pageViewTitle} />;
}

return <PageLoadingUI />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import React from 'react';
import { EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import './enter_button.scss';
import { METRIC_TYPE, useUiTracker } from '../../../../observability/public';
import { TELEMETRY_METRIC_BUTTON_CLICK } from '../../../common/constants';

export interface SetupModeEnterButtonProps {
enabled: boolean;
Expand All @@ -18,6 +20,7 @@ export const SetupModeEnterButton: React.FC<SetupModeEnterButtonProps> = (
props: SetupModeEnterButtonProps
) => {
const [isLoading, setIsLoading] = React.useState(false);
const trackStat = useUiTracker({ app: 'stack_monitoring' });

if (!props.enabled) {
return null;
Expand All @@ -26,6 +29,10 @@ export const SetupModeEnterButton: React.FC<SetupModeEnterButtonProps> = (
async function enterSetupMode() {
setIsLoading(true);
await props.toggleSetupMode(true);
trackStat({
metric: `${TELEMETRY_METRIC_BUTTON_CLICK}setupmode_enter`,
metricType: METRIC_TYPE.CLICK,
});
setIsLoading(false);
}

Expand Down
5 changes: 4 additions & 1 deletion x-pack/plugins/monitoring/public/legacy_shims.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TriggersAndActionsUIPublicPluginSetup } from '../../triggers_actions_ui
import { TypeRegistry } from '../../triggers_actions_ui/public/application/type_registry';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { ActionTypeModel, AlertTypeModel } from '../../triggers_actions_ui/public/types';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';

interface BreadcrumbItem {
['data-test-subj']?: string;
Expand Down Expand Up @@ -59,13 +60,14 @@ export interface IShims {
) => Promise<any>;
isCloud: boolean;
triggersActionsUi: TriggersAndActionsUIPublicPluginSetup;
usageCollection: UsageCollectionSetup;
}

export class Legacy {
private static _shims: IShims;

public static init(
{ core, data, isCloud, triggersActionsUi }: MonitoringStartPluginDependencies,
{ core, data, isCloud, triggersActionsUi, usageCollection }: MonitoringStartPluginDependencies,
ngInjector: angular.auto.IInjectorService
) {
this._shims = {
Expand Down Expand Up @@ -119,6 +121,7 @@ export class Legacy {
}),
isCloud,
triggersActionsUi,
usageCollection,
};
}

Expand Down
12 changes: 11 additions & 1 deletion x-pack/plugins/monitoring/public/lib/setup_mode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import React from 'react';
import { render } from 'react-dom';
import { get, includes } from 'lodash';
import { i18n } from '@kbn/i18n';
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
import { Legacy } from '../legacy_shims';
import { ajaxErrorHandlersProvider } from './ajax_error_handler';
import { SetupModeEnterButton } from '../components/setup_mode/enter_button';
Expand Down Expand Up @@ -179,8 +180,17 @@ export const setSetupModeMenuItem = () => {
const globalState = angularState.injector.get('globalState');
const enabled = !globalState.inSetupMode;

const services = {
usageCollection: Legacy.shims.usageCollection,
};
const I18nContext = Legacy.shims.I18nContext;

render(
<SetupModeEnterButton enabled={enabled} toggleSetupMode={toggleSetupMode} />,
<KibanaContextProvider services={services}>
<I18nContext>
<SetupModeEnterButton enabled={enabled} toggleSetupMode={toggleSetupMode} />
</I18nContext>
</KibanaContextProvider>,
document.getElementById('setupModeNav')
);
};
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/monitoring/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
Plugin,
PluginInitializerContext,
} from 'kibana/public';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
import {
FeatureCatalogueCategory,
HomePublicPluginSetup,
Expand All @@ -28,6 +29,7 @@ interface MonitoringSetupPluginDependencies {
home?: HomePublicPluginSetup;
cloud?: { isCloudEnabled: boolean };
triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
usageCollection: UsageCollectionSetup;
}

export class MonitoringPlugin
Expand Down Expand Up @@ -93,6 +95,7 @@ export class MonitoringPlugin
pluginInitializerContext: this.initializerContext,
externalConfig: this.getExternalConfig(),
triggersActionsUi: plugins.triggers_actions_ui,
usageCollection: plugins.usageCollection,
};

pluginsStart.kibanaLegacy.loadFontAwesome();
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/monitoring/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { NavigationPublicPluginStart as NavigationStart } from '../../../../src/
import { DataPublicPluginStart } from '../../../../src/plugins/data/public';
import { TriggersAndActionsUIPublicPluginSetup } from '../../triggers_actions_ui/public';
import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
export { MonitoringConfig } from '../server';
Expand All @@ -23,4 +24,5 @@ export interface MonitoringStartPluginDependencies {
pluginInitializerContext: PluginInitializerContext;
externalConfig: Array<Array<string | number> | Array<string | boolean>>;
triggersActionsUi: TriggersAndActionsUIPublicPluginSetup;
usageCollection: UsageCollectionSetup;
}
22 changes: 9 additions & 13 deletions x-pack/plugins/monitoring/public/views/apm/instance/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ uiRoutes.when('/apm/instances/:uuid', {
apm: 'APM server',
},
}),
telemetryPageViewTitle: 'apm_server_instance',
api: `../api/monitoring/v1/clusters/${globalState.cluster_uuid}/apm/${$route.current.params.uuid}`,
defaultData: {},
reactNodeId: 'apmInstanceReact',
Expand All @@ -63,21 +64,16 @@ uiRoutes.when('/apm/instances/:uuid', {
})
);
title($scope.cluster, `APM server - ${get(data, 'apmSummary.name')}`);
this.renderReact(data);
this.renderReact(
<ApmServerInstance
summary={data.apmSummary || {}}
metrics={data.metrics || {}}
onBrush={this.onBrush}
zoomInfo={this.zoomInfo}
/>
);
}
);
}

renderReact(data) {
const component = (
<ApmServerInstance
summary={data.apmSummary || {}}
metrics={data.metrics || {}}
onBrush={this.onBrush}
zoomInfo={this.zoomInfo}
/>
);
super.renderReact(component);
}
},
});
54 changes: 25 additions & 29 deletions x-pack/plugins/monitoring/public/views/apm/instances/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,33 @@ uiRoutes.when('/apm/instances', {
$scope.$watch(
() => this.data,
(data) => {
this.renderReact(data);
}
);
}
const { pagination, sorting, onTableChange } = this;

renderReact(data) {
const { pagination, sorting, onTableChange } = this;

const component = (
<SetupModeRenderer
scope={this.scope}
injector={this.injector}
productName={APM_SYSTEM_ID}
render={({ setupMode, flyoutComponent, bottomBarComponent }) => (
<Fragment>
{flyoutComponent}
<ApmServerInstances
setupMode={setupMode}
apms={{
pagination,
sorting,
onTableChange,
data,
}}
/>
{bottomBarComponent}
</Fragment>
)}
/>
const component = (
<SetupModeRenderer
scope={this.scope}
injector={this.injector}
productName={APM_SYSTEM_ID}
render={({ setupMode, flyoutComponent, bottomBarComponent }) => (
<Fragment>
{flyoutComponent}
<ApmServerInstances
setupMode={setupMode}
apms={{
pagination,
sorting,
onTableChange,
data,
}}
/>
{bottomBarComponent}
</Fragment>
)}
/>
);
this.renderReact(component);
}
);
super.renderReact(component);
}
},
});
9 changes: 3 additions & 6 deletions x-pack/plugins/monitoring/public/views/apm/overview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,11 @@ uiRoutes.when('/apm', {
$scope.$watch(
() => this.data,
(data) => {
this.renderReact(data);
this.renderReact(
<ApmOverview {...data} onBrush={this.onBrush} zoomInfo={this.zoomInfo} />
);
}
);
}

renderReact(data) {
const component = <ApmOverview {...data} onBrush={this.onBrush} zoomInfo={this.zoomInfo} />;
super.renderReact(component);
}
},
});
20 changes: 18 additions & 2 deletions x-pack/plugins/monitoring/public/views/base_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Legacy } from '../legacy_shims';
import { PromiseWithCancel } from '../../common/cancel_promise';
import { SetupModeFeature } from '../../common/enums';
import { updateSetupModeData, isSetupModeFeatureEnabled } from '../lib/setup_mode';
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';

/**
* Given a timezone, this function will calculate the offset in milliseconds
Expand Down Expand Up @@ -89,6 +90,7 @@ export class MonitoringViewBaseController {
options = {},
alerts = { shouldFetch: false, options: {} },
fetchDataImmediately = true,
telemetryPageViewTitle = '',
}) {
const titleService = $injector.get('title');
const $executor = $injector.get('$executor');
Expand All @@ -102,6 +104,7 @@ export class MonitoringViewBaseController {
$scope.pageData = this.data = { ...defaultData };
this._isDataInitialized = false;
this.reactNodeId = reactNodeId;
this.telemetryPageViewTitle = telemetryPageViewTitle || title;

let deferTimer;
let zoomInLevel = 0;
Expand Down Expand Up @@ -207,6 +210,8 @@ export class MonitoringViewBaseController {
deferTimer = setTimeout(() => addPopstateHandler(), 10);
};

// Render loading state
this.renderReact(null, true);
fetchDataImmediately && this.updateData();
});

Expand All @@ -228,15 +233,26 @@ export class MonitoringViewBaseController {
this.setTitle = (title) => titleService($scope.cluster, title);
}

renderReact(component) {
renderReact(component, trackPageView = false) {
const renderElement = document.getElementById(this.reactNodeId);
if (!renderElement) {
console.warn(`"#${this.reactNodeId}" element has not been added to the DOM yet`);
return;
}
const services = {
usageCollection: Legacy.shims.usageCollection,
};
const I18nContext = Legacy.shims.I18nContext;
const wrappedComponent = (
<I18nContext>{!this._isDataInitialized ? <PageLoading /> : component}</I18nContext>
<KibanaContextProvider services={services}>
<I18nContext>
{!this._isDataInitialized ? (
<PageLoading pageViewTitle={trackPageView ? this.telemetryPageViewTitle : null} />
) : (
component
)}
</I18nContext>
</KibanaContextProvider>
);
render(wrappedComponent, renderElement);
}
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/monitoring/public/views/beats/beat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ uiRoutes.when('/beats/beat/:beatUuid', {
beatName: pageData.summary.name,
},
}),
telemetryPageViewTitle: 'beats_instance',
getPageData,
$scope,
$injector,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ uiRoutes.when('/beats/beats', {
pageTitle: i18n.translate('xpack.monitoring.beats.listing.pageTitle', {
defaultMessage: 'Beats listing',
}),
telemetryPageViewTitle: 'beats_listing',
storageKey: 'beats.beats',
getPageData,
reactNodeId: 'monitoringBeatsInstancesApp',
Expand All @@ -51,9 +52,6 @@ uiRoutes.when('/beats/beats', {
this.scope = $scope;
this.injector = $injector;

//Bypassing super.updateData, since this controller loads its own data
this._isDataInitialized = true;

$scope.$watch(
() => this.data,
() => this.renderComponent()
Expand Down
Loading

0 comments on commit ee7f104

Please sign in to comment.