Skip to content

Commit

Permalink
[ObsUX] Use Profiling locators instead of hardcoded URL (elastic#173246)
Browse files Browse the repository at this point in the history
Closes elastic#173158
Closes elastic#173152

## Summary

Switches from a hardcoded URL in `<ProfilingLinks>` to Profiling
locators exposed by `observability_shared`. Also made `<ProfilingLinks>`
a bit more generic pure visual component.

Had to add locators to `observability_shared` plugin start interface as
Infra currently does not expose plugins setup interfaces to components.

https://github.com/elastic/kibana/assets/793851/5a4df5e2-4305-4439-a831-c9ddc9b82a71
(cherry picked from commit 2865931)
  • Loading branch information
mykolaharmash committed Dec 14, 2023
1 parent 7b3e657 commit 288d9e7
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import React, { useMemo } from 'react';
import { EuiSpacer } from '@elastic/eui';
import { EmbeddableFlamegraph } from '@kbn/observability-shared-plugin/public';
import { i18n } from '@kbn/i18n';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { useAssetDetailsRenderPropsContext } from '../../hooks/use_asset_details_render_props';
import { useDatePickerContext } from '../../hooks/use_date_picker';
import { useProfilingFlamegraphData } from '../../hooks/use_profiling_flamegraph_data';
Expand All @@ -17,11 +19,17 @@ import { ErrorPrompt } from './error_prompt';
import { ProfilingLinks } from './profiling_links';

export function Flamegraph() {
const { services } = useKibanaContextForPlugin();
const { asset } = useAssetDetailsRenderPropsContext();
const { activeTabId } = useTabSwitcherContext();
const { getDateRangeInTimestamp } = useDatePickerContext();
const { dateRange, getDateRangeInTimestamp } = useDatePickerContext();
const { from, to } = getDateRangeInTimestamp();

const profilingLinkLocator = services.observabilityShared.locators.profiling.flamegraphLocator;
const profilingLinkLabel = i18n.translate('xpack.infra.flamegraph.profilingAppFlamegraphLink', {
defaultMessage: 'Go to Universal Profiling Flamegraph',
});

const params = useMemo(
() => ({
hostname: asset.name,
Expand All @@ -41,7 +49,13 @@ export function Flamegraph() {

return (
<>
<ProfilingLinks profilingPath="flamegraphs" hostname={asset.name} />
<ProfilingLinks
hostname={asset.name}
from={dateRange.from}
to={dateRange.to}
profilingLinkLocator={profilingLinkLocator}
profilingLinkLabel={profilingLinkLabel}
/>
<EuiSpacer />
<EmbeddableFlamegraph data={response ?? undefined} isLoading={loading} height="60vh" />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import React, { useMemo } from 'react';
import { EmbeddableFunctions } from '@kbn/observability-shared-plugin/public';
import { EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { useAssetDetailsRenderPropsContext } from '../../hooks/use_asset_details_render_props';
import { useDatePickerContext } from '../../hooks/use_date_picker';
import { useProfilingFunctionsData } from '../../hooks/use_profiling_functions_data';
Expand All @@ -17,11 +19,17 @@ import { ErrorPrompt } from './error_prompt';
import { ProfilingLinks } from './profiling_links';

export function Functions() {
const { services } = useKibanaContextForPlugin();
const { asset } = useAssetDetailsRenderPropsContext();
const { activeTabId } = useTabSwitcherContext();
const { getDateRangeInTimestamp } = useDatePickerContext();
const { dateRange, getDateRangeInTimestamp } = useDatePickerContext();
const { from, to } = getDateRangeInTimestamp();

const profilingLinkLocator = services.observabilityShared.locators.profiling.topNFunctionsLocator;
const profilingLinkLabel = i18n.translate('xpack.infra.flamegraph.profilingAppTopFunctionsLink', {
defaultMessage: 'Go to Universal Profiling Functions',
});

const params = useMemo(
() => ({
hostname: asset.name,
Expand All @@ -44,7 +52,13 @@ export function Functions() {

return (
<>
<ProfilingLinks profilingPath="functions" hostname={asset.name} />
<ProfilingLinks
hostname={asset.name}
from={dateRange.from}
to={dateRange.to}
profilingLinkLocator={profilingLinkLocator}
profilingLinkLabel={profilingLinkLabel}
/>
<EuiSpacer />
<EmbeddableFunctions
data={response ?? undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,34 @@
*/

import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui';
import { FlamegraphLocator } from '@kbn/observability-shared-plugin/public/locators/profiling/flamegraph_locator';
import { TopNFunctionsLocator } from '@kbn/observability-shared-plugin/public/locators/profiling/topn_functions_locator';
import { HOST_FIELD } from '../../../../../common/constants';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';

const PROFILING_FEEDBACK_URL = 'https://ela.st/profiling-feedback';

export type ProfilingPath = 'flamegraphs' | 'functions';

interface Props {
hostname: string;
profilingPath: ProfilingPath;
from: string;
to: string;
profilingLinkLocator: FlamegraphLocator | TopNFunctionsLocator;
profilingLinkLabel: string;
}

export function ProfilingLinks({ hostname, profilingPath }: Props) {
const { services } = useKibanaContextForPlugin();
const queryParams = new URLSearchParams({
export function ProfilingLinks({
hostname,
from,
to,
profilingLinkLocator,
profilingLinkLabel,
}: Props) {
const profilingLinkURL = profilingLinkLocator.getRedirectUrl({
kuery: `${HOST_FIELD}:"${hostname}"`,
rangeFrom: from,
rangeTo: to,
});
const profilingLinkURL = services.http.basePath.prepend(
`/app/profiling/${profilingPath}?${queryParams}`
);
const profilingLinkLabel =
profilingPath === 'flamegraphs'
? i18n.translate('xpack.infra.flamegraph.profilingAppFlamegraphLink', {
defaultMessage: 'Go to Universal Profiling Flamegraph',
})
: i18n.translate('xpack.infra.flamegraph.profilingAppFunctionsLink', {
defaultMessage: 'Go to Universal Profiling Functions',
});

return (
<EuiFlexGroup justifyContent="flexEnd">
Expand Down
64 changes: 42 additions & 22 deletions x-pack/plugins/observability_shared/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,32 @@
* 2.0.
*/

import { BehaviorSubject } from 'rxjs';
import type { CoreStart, Plugin, CoreSetup } from '@kbn/core/public';
import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public';
import { CasesUiStart } from '@kbn/cases-plugin/public';
import { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
import type { EmbeddableStart } from '@kbn/embeddable-plugin/public';
import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public';
import { createNavigationRegistry } from './components/page_template/helpers/navigation_registry';
import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public';
import type {
BrowserUrlService,
SharePluginSetup,
SharePluginStart,
} from '@kbn/share-plugin/public';
import { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import { BehaviorSubject } from 'rxjs';
import { createLazyObservabilityPageTemplate } from './components/page_template';
import { createNavigationRegistry } from './components/page_template/helpers/navigation_registry';
import {
type FlamegraphLocator,
FlamegraphLocatorDefinition,
} from './locators/profiling/flamegraph_locator';
import {
type StacktracesLocator,
StacktracesLocatorDefinition,
} from './locators/profiling/stacktraces_locator';
import {
type TopNFunctionsLocator,
TopNFunctionsLocatorDefinition,
} from './locators/profiling/topn_functions_locator';
import { updateGlobalNavigation } from './services/update_global_navigation';
import { FlamegraphLocatorDefinition } from './locators/profiling/flamegraph_locator';
import { TopNFunctionsLocatorDefinition } from './locators/profiling/topn_functions_locator';
import { StacktracesLocatorDefinition } from './locators/profiling/stacktraces_locator';

export interface ObservabilitySharedSetup {
share: SharePluginSetup;
Expand All @@ -36,6 +49,14 @@ export type ObservabilitySharedPluginSetup = ReturnType<ObservabilitySharedPlugi
export type ObservabilitySharedPluginStart = ReturnType<ObservabilitySharedPlugin['start']>;
export type ProfilingLocators = ObservabilitySharedPluginSetup['locators']['profiling'];

interface ObservabilitySharedLocators {
profiling: {
flamegraphLocator: FlamegraphLocator;
topNFunctionsLocator: TopNFunctionsLocator;
stacktracesLocator: StacktracesLocator;
};
}

export class ObservabilitySharedPlugin implements Plugin {
private readonly navigationRegistry = createNavigationRegistry();
private isSidebarEnabled$: BehaviorSubject<boolean>;
Expand All @@ -46,19 +67,7 @@ export class ObservabilitySharedPlugin implements Plugin {

public setup(coreSetup: CoreSetup, pluginsSetup: ObservabilitySharedSetup) {
return {
locators: {
profiling: {
flamegraphLocator: pluginsSetup.share.url.locators.create(
new FlamegraphLocatorDefinition()
),
topNFunctionsLocator: pluginsSetup.share.url.locators.create(
new TopNFunctionsLocatorDefinition()
),
stacktracesLocator: pluginsSetup.share.url.locators.create(
new StacktracesLocatorDefinition()
),
},
},
locators: this.createLocators(pluginsSetup.share.url),
navigation: {
registerSections: this.navigationRegistry.registerSections,
},
Expand All @@ -79,6 +88,7 @@ export class ObservabilitySharedPlugin implements Plugin {
});

return {
locators: this.createLocators(plugins.share.url),
navigation: {
PageTemplate,
registerSections: this.navigationRegistry.registerSections,
Expand All @@ -89,4 +99,14 @@ export class ObservabilitySharedPlugin implements Plugin {
}

public stop() {}

private createLocators(urlService: BrowserUrlService): ObservabilitySharedLocators {
return {
profiling: {
flamegraphLocator: urlService.locators.create(new FlamegraphLocatorDefinition()),
topNFunctionsLocator: urlService.locators.create(new TopNFunctionsLocatorDefinition()),
stacktracesLocator: urlService.locators.create(new StacktracesLocatorDefinition()),
},
};
}
}

0 comments on commit 288d9e7

Please sign in to comment.