Skip to content

Commit

Permalink
addressing pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cauemarcondes committed Nov 21, 2023
1 parent 8d9771a commit ea67898
Show file tree
Hide file tree
Showing 18 changed files with 273 additions and 164 deletions.
Expand Up @@ -17,38 +17,36 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import React, { useMemo, useState } from 'react';
import { ProfilingSearchBarFilter } from '@kbn/observability-shared-plugin/public';
import { EmbeddableProfilingSearchBar } from '@kbn/observability-shared-plugin/public';
import React, { useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { ApmDocumentType } from '../../../../common/document_type';
import { useApmParams } from '../../../hooks/use_apm_params';
import { useLocalStorage } from '../../../hooks/use_local_storage';
import { usePreferredDataSourceAndBucketSize } from '../../../hooks/use_preferred_data_source_and_bucket_size';
import { useProfilingPlugin } from '../../../hooks/use_profiling_plugin';
import { useTimeRange } from '../../../hooks/use_time_range';
import { ApmPluginStartDeps } from '../../../plugin';
import { push } from '../../shared/links/url_helpers';
import { ProfilingFlamegraph } from './profiling_flamegraph';
import { ProfilingTopNFunctions } from './profiling_top_functions';

export function ProfilingOverview() {
const history = useHistory();
const { services } = useKibana<ApmPluginStartDeps>();
const {
path: { serviceName },
query: { rangeFrom, rangeTo, environment, kuery },
} = useApmParams('/services/{serviceName}/profiling');
const { isProfilingAvailable } = useProfilingPlugin();
const { start, end } = useTimeRange({ rangeFrom, rangeTo });
const { start, end, refreshTimeRange } = useTimeRange({ rangeFrom, rangeTo });
const preferred = usePreferredDataSourceAndBucketSize({
start,
end,
kuery,
type: ApmDocumentType.TransactionMetric,
numBuckets: 20,
});
const [searchBarFilter, setSearchBarFilter] =
useState<ProfilingSearchBarFilter>({
id: '',
filters: '',
});

const [
apmUniversalProfilingShowCallout,
Expand All @@ -74,8 +72,7 @@ export function ProfilingOverview() {
end={end}
environment={environment}
dataSource={preferred?.source}
searchBarFilter={searchBarFilter}
onSearchBarFilterChange={setSearchBarFilter}
kuery={kuery}
/>
</>
),
Expand All @@ -96,21 +93,13 @@ export function ProfilingOverview() {
startIndex={0}
endIndex={10}
dataSource={preferred?.source}
searchBarFilter={searchBarFilter}
onSearchBarFilterChange={setSearchBarFilter}
kuery={kuery}
/>
</>
),
},
];
}, [
end,
environment,
preferred?.source,
searchBarFilter,
serviceName,
start,
]);
}, [end, environment, kuery, preferred?.source, serviceName, start]);

if (!isProfilingAvailable) {
return null;
Expand Down Expand Up @@ -165,6 +154,22 @@ export function ProfilingOverview() {
<EuiSpacer />
</>
)}
<EmbeddableProfilingSearchBar
kuery={kuery}
rangeFrom={rangeFrom}
rangeTo={rangeTo}
onQuerySubmit={(next) => {
push(history, {
query: {
kuery: next.query,
rangeFrom: next.dateRange.from,
rangeTo: next.dateRange.to,
},
});
}}
onRefresh={refreshTimeRange}
/>
<EuiSpacer />
<EuiTabbedContent
tabs={tabs}
initialSelectedTab={tabs[0]}
Expand Down
Expand Up @@ -13,10 +13,7 @@ import {
EuiSpacer,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import {
EmbeddableFlamegraph,
ProfilingSearchBarFilter,
} from '@kbn/observability-shared-plugin/public';
import { EmbeddableFlamegraph } from '@kbn/observability-shared-plugin/public';
import { isEmpty } from 'lodash';
import React from 'react';
import { ApmDataSourceWithSummary } from '../../../../common/data_source';
Expand All @@ -42,8 +39,7 @@ interface Props {
dataSource?: ApmDataSourceWithSummary<
ApmDocumentType.TransactionMetric | ApmDocumentType.TransactionEvent
>;
searchBarFilter: ProfilingSearchBarFilter;
onSearchBarFilterChange: (next: ProfilingSearchBarFilter) => void;
kuery: string;
}

export function ProfilingFlamegraph({
Expand All @@ -52,8 +48,7 @@ export function ProfilingFlamegraph({
serviceName,
environment,
dataSource,
searchBarFilter,
onSearchBarFilterChange,
kuery,
}: Props) {
const { profilingLocators } = useProfilingPlugin();

Expand All @@ -71,14 +66,14 @@ export function ProfilingFlamegraph({
environment,
documentType: dataSource.documentType,
rollupInterval: dataSource.rollupInterval,
kuery: searchBarFilter.filters,
kuery,
},
},
}
);
}
},
[dataSource, serviceName, start, end, environment, searchBarFilter]
[dataSource, serviceName, start, end, environment, kuery]
);

const hostNamesKueryFormat = toKueryFilterFormat(
Expand All @@ -97,10 +92,7 @@ export function ProfilingFlamegraph({
<EuiLink
data-test-subj="apmProfilingFlamegraphGoToFlamegraphLink"
href={profilingLocators?.flamegraphLocator.getRedirectUrl({
kuery: mergeKueries([
`(${hostNamesKueryFormat})`,
searchBarFilter.filters,
]),
kuery: mergeKueries([`(${hostNamesKueryFormat})`, kuery]),
})}
>
{i18n.translate('xpack.apm.profiling.flamegraph.link', {
Expand All @@ -127,8 +119,6 @@ export function ProfilingFlamegraph({
data={data?.flamegraph}
isLoading={isPending(status)}
height="60vh"
onSearchBarFilterChange={onSearchBarFilterChange}
searchBarFilter={searchBarFilter}
/>
)}
</>
Expand Down
Expand Up @@ -7,10 +7,7 @@

import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import {
EmbeddableFunctions,
ProfilingSearchBarFilter,
} from '@kbn/observability-shared-plugin/public';
import { EmbeddableFunctions } from '@kbn/observability-shared-plugin/public';
import React from 'react';
import { ApmDataSourceWithSummary } from '../../../../common/data_source';
import { ApmDocumentType } from '../../../../common/document_type';
Expand All @@ -33,8 +30,7 @@ interface Props {
dataSource?: ApmDataSourceWithSummary<
ApmDocumentType.TransactionMetric | ApmDocumentType.TransactionEvent
>;
searchBarFilter: ProfilingSearchBarFilter;
onSearchBarFilterChange: (next: ProfilingSearchBarFilter) => void;
kuery: string;
}

export function ProfilingTopNFunctions({
Expand All @@ -45,8 +41,7 @@ export function ProfilingTopNFunctions({
startIndex,
endIndex,
dataSource,
searchBarFilter,
onSearchBarFilterChange,
kuery,
}: Props) {
const { profilingLocators } = useProfilingPlugin();

Expand All @@ -66,7 +61,7 @@ export function ProfilingTopNFunctions({
endIndex,
documentType: dataSource.documentType,
rollupInterval: dataSource.rollupInterval,
kuery: searchBarFilter.filters,
kuery,
},
},
}
Expand All @@ -81,7 +76,7 @@ export function ProfilingTopNFunctions({
environment,
startIndex,
endIndex,
searchBarFilter,
kuery,
]
);

Expand All @@ -101,10 +96,7 @@ export function ProfilingTopNFunctions({
<EuiLink
data-test-subj="apmProfilingTopNFunctionsGoToUniversalProfilingFlamegraphLink"
href={profilingLocators?.topNFunctionsLocator.getRedirectUrl({
kuery: mergeKueries([
`(${hostNamesKueryFormat})`,
searchBarFilter.filters,
]),
kuery: mergeKueries([`(${hostNamesKueryFormat})`, kuery]),
})}
>
{i18n.translate('xpack.apm.profiling.topnFunctions.link', {
Expand All @@ -120,8 +112,6 @@ export function ProfilingTopNFunctions({
isLoading={isPending(status)}
rangeFrom={new Date(start).valueOf()}
rangeTo={new Date(end).valueOf()}
onSearchBarFilterChange={onSearchBarFilterChange}
searchBarFilter={searchBarFilter}
/>
</>
);
Expand Down
Expand Up @@ -371,9 +371,7 @@ export const serviceDetailRoute = {
}),
element: <ProfilingOverview />,
searchBarOptions: {
showTimeComparison: false,
showTransactionTypeSelector: false,
showQueryInput: false,
hidden: true,
},
}),
},
Expand Down
@@ -0,0 +1,71 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { css } from '@emotion/react';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { default as React, useEffect, useRef, useState } from 'react';
import { EMBEDDABLE_PROFILING_SEARCH_BAR } from '.';
import { ObservabilitySharedStart } from '../../../plugin';

export interface EmbeddableProfilingSearchBarProps {
kuery: string;
showDatePicker?: boolean;
onQuerySubmit: (params: {
dateRange: { from: string; to: string; mode?: 'absolute' | 'relative' };
query: string;
}) => void;
onRefresh: () => void;
rangeFrom: string;
rangeTo: string;
}

export function EmbeddableProfilingSearchBar(props: EmbeddableProfilingSearchBarProps) {
const { embeddable: embeddablePlugin } = useKibana<ObservabilitySharedStart>().services;
const [embeddable, setEmbeddable] = useState<any>();
const embeddableRoot: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(null);

useEffect(() => {
async function createEmbeddable() {
const factory = embeddablePlugin?.getEmbeddableFactory(EMBEDDABLE_PROFILING_SEARCH_BAR);
const input = {
id: 'embeddable_profiling',
};
const embeddableObject = await factory?.create(input);
setEmbeddable(embeddableObject);
}
createEmbeddable();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (embeddableRoot.current && embeddable) {
embeddable.render(embeddableRoot.current);
}
}, [embeddable, embeddableRoot]);

useEffect(() => {
if (embeddable) {
embeddable.updateInput({
...props,
});
embeddable.reload();
}
}, [embeddable, props]);

return (
<div
css={css`
width: 100%;
display: flex;
flex: 1 1 100%;
z-index: 1;
min-height: 0;
`}
ref={embeddableRoot}
/>
);
}
Expand Up @@ -14,5 +14,11 @@ export { EmbeddableFlamegraph } from './embeddable_flamegraph';
export const EMBEDDABLE_FUNCTIONS = 'EMBEDDABLE_FUNCTIONS';
/** Profiling functions embeddable */
export { EmbeddableFunctions } from './embeddable_functions';
/** Profiling Search bar params */
export type { ProfilingSearchBarFilter } from './profiling_embeddable';

/** Profiling search bar embeddable key */
export const EMBEDDABLE_PROFILING_SEARCH_BAR = 'EMBEDDABLE_PROFILING_SEARCH_BAR';
/** Profiling search bar embeddable */
export {
EmbeddableProfilingSearchBar,
type EmbeddableProfilingSearchBarProps,
} from './embeddable_profiling_search_bar';
Expand Up @@ -10,28 +10,18 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
import React, { useEffect, useRef, useState } from 'react';
import { ObservabilitySharedStart } from '../../../plugin';

export interface ProfilingSearchBarFilter {
filters: string;
/** Is used to force a new api call when refresh button is clicked without any changes in the query value */
id: string;
}

export interface ProfilingEmbeddableProps<T> {
data?: T;
embeddableFactoryId: string;
isLoading: boolean;
height?: string;
searchBarFilter?: ProfilingSearchBarFilter;
onSearchBarFilterChange?: (params: ProfilingSearchBarFilter) => void;
}

export function ProfilingEmbeddable<T>({
embeddableFactoryId,
data,
isLoading,
onSearchBarFilterChange,
height,
searchBarFilter,
...props
}: ProfilingEmbeddableProps<T>) {
const { embeddable: embeddablePlugin } = useKibana<ObservabilitySharedStart>().services;
Expand All @@ -45,8 +35,6 @@ export function ProfilingEmbeddable<T>({
id: 'embeddable_profiling',
data,
isLoading,
onSearchBarFilterChange,
searchBarFilter,
};
const embeddableObject = await factory?.create(input);
setEmbeddable(embeddableObject);
Expand All @@ -66,13 +54,11 @@ export function ProfilingEmbeddable<T>({
embeddable.updateInput({
data,
isLoading,
onSearchBarFilterChange,
searchBarFilter,
...props,
});
embeddable.reload();
}
}, [data, embeddable, isLoading, onSearchBarFilterChange, searchBarFilter, props]);
}, [data, embeddable, isLoading, props]);

return (
<div
Expand Down

0 comments on commit ea67898

Please sign in to comment.