[Observability] Collect UI telemetry (#78258)

* adding telemetry to obs pages

* adding telemetry to obs pages

* increasing delay
This commit is contained in:
Cauê Marcondes 2020-09-23 14:44:40 +01:00 committed by GitHub
parent 8d4b5a599a
commit 0cf3bf2731
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 64 additions and 46 deletions

View file

@ -2,19 +2,9 @@
"id": "observability",
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": [
"xpack",
"observability"
],
"optionalPlugins": [
"licensing",
"home"
],
"configPath": ["xpack", "observability"],
"optionalPlugins": ["licensing", "home", "usageCollection"],
"ui": true,
"server": true,
"requiredBundles": [
"data",
"kibanaReact",
"kibanaUtils"
]
"requiredBundles": ["data", "kibanaReact", "kibanaUtils"]
}

View file

@ -3,15 +3,18 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { createMemoryHistory } from 'history';
import React from 'react';
import { Observable } from 'rxjs';
import { AppMountParameters, CoreStart } from 'src/core/public';
import { ObservabilityPluginSetupDeps } from '../plugin';
import { renderApp } from './';
describe('renderApp', () => {
it('renders', () => {
it('renders', async () => {
const plugins = ({
usageCollection: { reportUiStats: () => {} },
} as unknown) as ObservabilityPluginSetupDeps;
const core = ({
application: { currentAppId$: new Observable(), navigateToUrl: () => {} },
chrome: { docTitle: { change: () => {} }, setBreadcrumbs: () => {} },
@ -24,7 +27,7 @@ describe('renderApp', () => {
} as unknown) as AppMountParameters;
expect(() => {
const unmount = renderApp(core, params);
const unmount = renderApp(core, plugins, params);
unmount();
}).not.toThrowError();
});

View file

@ -8,12 +8,16 @@ import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Route, Router, Switch } from 'react-router-dom';
import { AppMountParameters, CoreStart } from '../../../../../src/core/public';
import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public';
import {
KibanaContextProvider,
RedirectAppLinks,
} from '../../../../../src/plugins/kibana_react/public';
import { EuiThemeProvider } from '../../../xpack_legacy/common';
import { PluginContext } from '../context/plugin_context';
import { usePluginContext } from '../hooks/use_plugin_context';
import { useRouteParams } from '../hooks/use_route_params';
import { Breadcrumbs, routes } from '../routes';
import { ObservabilityPluginSetupDeps } from '../plugin';
const observabilityLabelBreadcrumb = {
text: i18n.translate('xpack.observability.observability.breadcrumb.', {
@ -51,22 +55,28 @@ function App() {
);
}
export const renderApp = (core: CoreStart, { element, history }: AppMountParameters) => {
export const renderApp = (
core: CoreStart,
plugins: ObservabilityPluginSetupDeps,
{ element, history }: AppMountParameters
) => {
const i18nCore = core.i18n;
const isDarkMode = core.uiSettings.get('theme:darkMode');
ReactDOM.render(
<PluginContext.Provider value={{ core }}>
<Router history={history}>
<EuiThemeProvider darkMode={isDarkMode}>
<i18nCore.Context>
<RedirectAppLinks application={core.application}>
<App />
</RedirectAppLinks>
</i18nCore.Context>
</EuiThemeProvider>
</Router>
</PluginContext.Provider>,
<KibanaContextProvider services={{ ...core, ...plugins }}>
<PluginContext.Provider value={{ core }}>
<Router history={history}>
<EuiThemeProvider darkMode={isDarkMode}>
<i18nCore.Context>
<RedirectAppLinks application={core.application}>
<App />
</RedirectAppLinks>
</i18nCore.Context>
</EuiThemeProvider>
</Router>
</PluginContext.Provider>
</KibanaContextProvider>,
element
);
return () => {

View file

@ -4,12 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { DataHandler } from './typings/fetch_overview_data';
import { ObservabilityApp } from '../typings/common';
import { DataHandler, ObservabilityFetchDataPlugins } from './typings/fetch_overview_data';
const dataHandlers: Partial<Record<ObservabilityApp, DataHandler>> = {};
const dataHandlers: Partial<Record<ObservabilityFetchDataPlugins, DataHandler>> = {};
export function registerDataHandler<T extends ObservabilityApp>({
export function registerDataHandler<T extends ObservabilityFetchDataPlugins>({
appName,
fetchData,
hasData,
@ -17,19 +16,23 @@ export function registerDataHandler<T extends ObservabilityApp>({
dataHandlers[appName] = { fetchData, hasData };
}
export function unregisterDataHandler<T extends ObservabilityApp>({ appName }: { appName: T }) {
export function unregisterDataHandler<T extends ObservabilityFetchDataPlugins>({
appName,
}: {
appName: T;
}) {
delete dataHandlers[appName];
}
export function getDataHandler<T extends ObservabilityApp>(appName: T) {
export function getDataHandler<T extends ObservabilityFetchDataPlugins>(appName: T) {
const dataHandler = dataHandlers[appName];
if (dataHandler) {
return dataHandler as DataHandler<T>;
}
}
export async function fetchHasData(): Promise<Record<ObservabilityApp, boolean>> {
const apps: ObservabilityApp[] = ['apm', 'uptime', 'infra_logs', 'infra_metrics'];
export async function fetchHasData(): Promise<Record<ObservabilityFetchDataPlugins, boolean>> {
const apps: ObservabilityFetchDataPlugins[] = ['apm', 'uptime', 'infra_logs', 'infra_metrics'];
const promises = apps.map(async (app) => getDataHandler(app)?.hasData() || false);

View file

@ -21,6 +21,7 @@ import styled, { ThemeContext } from 'styled-components';
import { IngestManagerPanel } from '../../components/app/ingest_manager_panel';
import { WithHeaderLayout } from '../../components/app/layout/with_header';
import { usePluginContext } from '../../hooks/use_plugin_context';
import { useTrackPageview } from '../../hooks/use_track_metric';
import { appsSection } from '../home/section';
const EuiCardWithoutPadding = styled(EuiCard)`
@ -28,6 +29,9 @@ const EuiCardWithoutPadding = styled(EuiCard)`
`;
export function LandingPage() {
useTrackPageview({ app: 'observability', path: 'landing' });
useTrackPageview({ app: 'observability', path: 'landing', delay: 15000 });
const { core } = usePluginContext();
const theme = useContext(ThemeContext);

View file

@ -8,6 +8,7 @@ import React, { useContext } from 'react';
import { ThemeContext } from 'styled-components';
import { EmptySection } from '../../components/app/empty_section';
import { WithHeaderLayout } from '../../components/app/layout/with_header';
import { NewsFeed } from '../../components/app/news_feed';
import { Resources } from '../../components/app/resources';
import { AlertsSection } from '../../components/app/section/alerts';
import { APMSection } from '../../components/app/section/apm';
@ -15,18 +16,18 @@ import { LogsSection } from '../../components/app/section/logs';
import { MetricsSection } from '../../components/app/section/metrics';
import { UptimeSection } from '../../components/app/section/uptime';
import { DatePicker, TimePickerTime } from '../../components/shared/data_picker';
import { NewsFeed } from '../../components/app/news_feed';
import { fetchHasData } from '../../data_handler';
import { FETCH_STATUS, useFetcher } from '../../hooks/use_fetcher';
import { UI_SETTINGS, useKibanaUISettings } from '../../hooks/use_kibana_ui_settings';
import { usePluginContext } from '../../hooks/use_plugin_context';
import { useTrackPageview } from '../../hooks/use_track_metric';
import { RouteParams } from '../../routes';
import { getNewsFeed } from '../../services/get_news_feed';
import { getObservabilityAlerts } from '../../services/get_observability_alerts';
import { getAbsoluteTime } from '../../utils/date';
import { getBucketSize } from '../../utils/get_bucket_size';
import { getEmptySections } from './empty_section';
import { LoadingObservability } from './loading_observability';
import { getNewsFeed } from '../../services/get_news_feed';
interface Props {
routeParams: RouteParams<'/overview'>;
@ -41,6 +42,9 @@ function calculatetBucketSize({ start, end }: { start?: number; end?: number })
export function OverviewPage({ routeParams }: Props) {
const { core } = usePluginContext();
useTrackPageview({ app: 'observability', path: 'overview' });
useTrackPageview({ app: 'observability', path: 'overview', delay: 15000 });
const { data: alerts = [], status: alertStatus } = useFetcher(() => {
return getObservabilityAlerts({ core });
}, [core]);

View file

@ -23,7 +23,7 @@ export interface ObservabilityPluginSetup {
dashboard: { register: typeof registerDataHandler };
}
interface SetupPlugins {
export interface ObservabilityPluginSetupDeps {
home?: HomePublicPluginSetup;
}
@ -34,7 +34,7 @@ export class Plugin implements PluginClass<ObservabilityPluginSetup, Observabili
constructor(context: PluginInitializerContext) {}
public setup(core: CoreSetup, plugins: SetupPlugins) {
public setup(core: CoreSetup, plugins: ObservabilityPluginSetupDeps) {
core.application.register({
id: 'observability-overview',
title: 'Overview',
@ -50,7 +50,7 @@ export class Plugin implements PluginClass<ObservabilityPluginSetup, Observabili
// Get start services
const [coreStart] = await core.getStartServices();
return renderApp(coreStart, params);
return renderApp(coreStart, plugins, params);
},
});

View file

@ -32,7 +32,11 @@ export type FetchData<T extends FetchDataResponse = FetchDataResponse> = (
export type HasData = () => Promise<boolean>;
export interface DataHandler<T extends ObservabilityApp = ObservabilityApp> {
export type ObservabilityFetchDataPlugins = Exclude<ObservabilityApp, 'observability'>;
export interface DataHandler<
T extends ObservabilityFetchDataPlugins = ObservabilityFetchDataPlugins
> {
fetchData: FetchData<ObservabilityFetchDataResponse[T]>;
hasData: HasData;
}

View file

@ -4,10 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ObservabilityApp } from '../../../typings/common';
import { ObservabilityFetchDataPlugins } from '../fetch_overview_data';
export interface ISection {
id: ObservabilityApp | 'alert';
id: ObservabilityFetchDataPlugins | 'alert';
title: string;
icon: string;
description: string;

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
export type ObservabilityApp = 'infra_metrics' | 'infra_logs' | 'apm' | 'uptime';
export type ObservabilityApp = 'infra_metrics' | 'infra_logs' | 'apm' | 'uptime' | 'observability';
export type PromiseReturnType<Func> = Func extends (...args: any[]) => Promise<infer Value>
? Value