Skip to content

Commit

Permalink
[APM] Explicitly set environment for cross-service links (elastic#87481)
Browse files Browse the repository at this point in the history
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
2 people authored and JasonStoltz committed Jan 19, 2021
1 parent 728c6ea commit 07caf19
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 29 deletions.
24 changes: 24 additions & 0 deletions x-pack/plugins/apm/common/environment_filter_values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,27 @@ export const ENVIRONMENT_NOT_DEFINED = {
export function getEnvironmentLabel(environment: string) {
return environmentLabels[environment] || environment;
}

// returns the environment url param that should be used
// based on the requested environment. If the requested
// environment is different from the URL parameter, we'll
// return ENVIRONMENT_ALL. If it's not, we'll just return
// the current environment URL param
export function getNextEnvironmentUrlParam({
requestedEnvironment,
currentEnvironmentUrlParam,
}: {
requestedEnvironment?: string;
currentEnvironmentUrlParam?: string;
}) {
const normalizedRequestedEnvironment =
requestedEnvironment || ENVIRONMENT_NOT_DEFINED.value;
const normalizedQueryEnvironment =
currentEnvironmentUrlParam || ENVIRONMENT_ALL.value;

if (normalizedRequestedEnvironment === normalizedQueryEnvironment) {
return currentEnvironmentUrlParam;
}

return ENVIRONMENT_ALL.value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { EuiButton, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { getNextEnvironmentUrlParam } from '../../../../../common/environment_filter_values';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { Transaction as ITransaction } from '../../../../../typings/es_schemas/ui/transaction';
import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link';
Expand All @@ -20,8 +21,9 @@ export const MaybeViewTraceLink = ({
waterfall: IWaterfall;
}) => {
const {
urlParams: { latencyAggregationType },
urlParams: { environment, latencyAggregationType },
} = useUrlParams();

const viewFullTraceButtonLabel = i18n.translate(
'xpack.apm.transactionDetails.viewFullTraceButtonLabel',
{
Expand Down Expand Up @@ -73,6 +75,11 @@ export const MaybeViewTraceLink = ({

// the user is viewing a zoomed in version of the trace. Link to the full trace
} else {
const nextEnvironment = getNextEnvironmentUrlParam({
requestedEnvironment: rootTransaction?.service.environment,
currentEnvironmentUrlParam: environment,
});

return (
<EuiFlexItem grow={false}>
<TransactionDetailLink
Expand All @@ -81,6 +88,7 @@ export const MaybeViewTraceLink = ({
traceId={rootTransaction.trace.id}
transactionName={rootTransaction.transaction.name}
transactionType={rootTransaction.transaction.type}
environment={nextEnvironment}
latencyAggregationType={latencyAggregationType}
>
<EuiButton iconType="apmTrace">{viewFullTraceButtonLabel}</EuiButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useUrlParams } from '../../../../../../context/url_params_context/use_url_params';
import { getNextEnvironmentUrlParam } from '../../../../../../../common/environment_filter_values';
import {
SERVICE_NAME,
TRANSACTION_NAME,
Expand All @@ -22,13 +23,18 @@ interface Props {

export function FlyoutTopLevelProperties({ transaction }: Props) {
const {
urlParams: { latencyAggregationType },
urlParams: { environment, latencyAggregationType },
} = useUrlParams();

if (!transaction) {
return null;
}

const nextEnvironment = getNextEnvironmentUrlParam({
requestedEnvironment: transaction.service.environment,
currentEnvironmentUrlParam: environment,
});

const stickyProperties = [
{
label: i18n.translate('xpack.apm.transactionDetails.serviceLabel', {
Expand All @@ -38,6 +44,7 @@ export function FlyoutTopLevelProperties({ transaction }: Props) {
val: (
<ServiceOrTransactionsOverviewLink
serviceName={transaction.service.name}
environment={nextEnvironment}
>
{transaction.service.name}
</ServiceOrTransactionsOverviewLink>
Expand All @@ -56,6 +63,7 @@ export function FlyoutTopLevelProperties({ transaction }: Props) {
traceId={transaction.trace.id}
transactionName={transaction.transaction.name}
transactionType={transaction.transaction.type}
environment={nextEnvironment}
latencyAggregationType={latencyAggregationType}
>
{transaction.transaction.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useUrlParams } from '../../../../../../../context/url_params_context/use_url_params';
import { getNextEnvironmentUrlParam } from '../../../../../../../../common/environment_filter_values';
import {
SERVICE_NAME,
SPAN_NAME,
Expand All @@ -26,8 +27,14 @@ interface Props {

export function StickySpanProperties({ span, transaction }: Props) {
const {
urlParams: { latencyAggregationType },
urlParams: { environment, latencyAggregationType },
} = useUrlParams();

const nextEnvironment = getNextEnvironmentUrlParam({
requestedEnvironment: transaction?.service.environment,
currentEnvironmentUrlParam: environment,
});

const spanName = span.span.name;
const transactionStickyProperties = transaction
? [
Expand All @@ -39,6 +46,7 @@ export function StickySpanProperties({ span, transaction }: Props) {
val: (
<ServiceOrTransactionsOverviewLink
serviceName={transaction.service.name}
environment={nextEnvironment}
>
{transaction.service.name}
</ServiceOrTransactionsOverviewLink>
Expand All @@ -60,6 +68,7 @@ export function StickySpanProperties({ span, transaction }: Props) {
traceId={transaction.trace.id}
transactionName={transaction.transaction.name}
transactionType={transaction.transaction.type}
environment={nextEnvironment}
latencyAggregationType={latencyAggregationType}
>
{transaction.transaction.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { ENVIRONMENT_ALL } from '../../../../../common/environment_filter_values';
import {
ENVIRONMENT_ALL,
getNextEnvironmentUrlParam,
} from '../../../../../common/environment_filter_values';
import {
asMillisecondDuration,
asPercent,
Expand All @@ -40,6 +43,10 @@ interface Props {
}

export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
const {
urlParams: { start, end, environment },
} = useUrlParams();

const columns: Array<EuiBasicTableColumn<ServiceDependencyItem>> = [
{
field: 'name',
Expand All @@ -64,7 +71,13 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
</EuiFlexItem>
<EuiFlexItem>
{item.type === 'service' ? (
<ServiceOverviewLink serviceName={item.serviceName}>
<ServiceOverviewLink
serviceName={item.serviceName}
environment={getNextEnvironmentUrlParam({
requestedEnvironment: item.environment,
currentEnvironmentUrlParam: environment,
})}
>
{item.name}
</ServiceOverviewLink>
) : (
Expand Down Expand Up @@ -154,10 +167,6 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
},
];

const {
urlParams: { start, end, environment },
} = useUrlParams();

const { data = [], status } = useFetcher(() => {
if (!start || !end) {
return;
Expand Down
20 changes: 14 additions & 6 deletions x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,24 @@ export const PERSISTENT_APM_PARAMS: Array<keyof APMQueryParams> = [
/**
* Hook to get a link for a path with persisted filters
*/
export function useAPMHref(
path: string,
persistentFilters: Array<keyof APMQueryParams> = []
) {
export function useAPMHref({
path,
persistedFilters,
query,
}: {
path: string;
persistedFilters?: Array<keyof APMQueryParams>;
query?: APMQueryParams;
}) {
const { urlParams } = useUrlParams();
const { basePath } = useApmPluginContext().core.http;
const { search } = useLocation();
const query = pickKeys(urlParams as APMQueryParams, ...persistentFilters);
const nextQuery = {
...pickKeys(urlParams as APMQueryParams, ...(persistedFilters ?? [])),
...query,
};

return getAPMHref({ basePath, path, query, search });
return getAPMHref({ basePath, path, query: nextQuery, search });
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const persistedFilters: Array<keyof APMQueryParams> = [
];

export function useErrorOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/errors`, persistedFilters);
return useAPMHref({
path: `/services/${serviceName}/errors`,
persistedFilters,
});
}

interface Props extends APMLinkExtendProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ const persistedFilters: Array<keyof APMQueryParams> = [
];

export function useMetricOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/metrics`, persistedFilters);
return useAPMHref({
path: `/services/${serviceName}/metrics`,
persistedFilters,
});
}

interface Props extends APMLinkExtendProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import React from 'react';
import { APMLinkExtendProps, useAPMHref } from './APMLink';

export function useServiceMapHref(serviceName?: string) {
const pathFor = serviceName
const path = serviceName
? `/services/${serviceName}/service-map`
: '/service-map';
return useAPMHref(pathFor);
return useAPMHref({ path });
}

interface ServiceMapLinkProps extends APMLinkExtendProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ const persistedFilters: Array<keyof APMQueryParams> = [
];

export function useServiceNodeOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/nodes`, persistedFilters);
return useAPMHref({
path: `/services/${serviceName}/nodes`,
persistedFilters,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ const persistedFilters: Array<keyof APMQueryParams> = [
];

export function useTraceOverviewHref() {
return useAPMHref('/traces', persistedFilters);
return useAPMHref({ path: '/traces', persistedFilters });
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ import { useAPMHref } from './APMLink';
const persistedFilters: Array<keyof APMQueryParams> = ['host', 'agentName'];

export function useServiceInventoryHref() {
return useAPMHref('/services', persistedFilters);
return useAPMHref({ path: '/services', persistedFilters });
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,34 @@ import { APMLinkExtendProps, useAPMHref } from './APMLink';

interface ServiceOverviewLinkProps extends APMLinkExtendProps {
serviceName: string;
environment?: string;
}

const persistedFilters: Array<keyof APMQueryParams> = [
'latencyAggregationType',
];

export function useServiceOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}/overview`, persistedFilters);
export function useServiceOverviewHref(
serviceName: string,
environment?: string
) {
const query = environment
? {
environment,
}
: {};
return useAPMHref({
path: `/services/${serviceName}/overview`,
persistedFilters,
query,
});
}

export function ServiceOverviewLink({
serviceName,
environment,
...rest
}: ServiceOverviewLinkProps) {
const href = useServiceOverviewHref(serviceName);
const href = useServiceOverviewHref(serviceName, environment);
return <EuiLink href={href} {...rest} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,28 @@ const persistedFilters: Array<keyof APMQueryParams> = [
'latencyAggregationType',
];

export function useServiceOrTransactionsOverviewHref(serviceName: string) {
return useAPMHref(`/services/${serviceName}`, persistedFilters);
export function useServiceOrTransactionsOverviewHref(
serviceName: string,
environment?: string
) {
const query = environment ? { environment } : {};
return useAPMHref({
path: `/services/${serviceName}`,
persistedFilters,
query,
});
}

interface Props extends APMLinkExtendProps {
serviceName: string;
environment?: string;
}

export function ServiceOrTransactionsOverviewLink({
serviceName,
environment,
...rest
}: Props) {
const href = useServiceOrTransactionsOverviewHref(serviceName);
const href = useServiceOrTransactionsOverviewHref(serviceName, environment);
return <EuiLink href={href} {...rest} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
import { EuiLink } from '@elastic/eui';
import { pickBy, identity } from 'lodash';
import { getAPMHref, APMLinkExtendProps } from './APMLink';
import { useUrlParams } from '../../../../context/url_params_context/use_url_params';
import { pickKeys } from '../../../../../common/utils/pick_keys';
Expand All @@ -20,6 +21,7 @@ interface Props extends APMLinkExtendProps {
transactionName: string;
transactionType: string;
latencyAggregationType?: string;
environment?: string;
}

const persistedFilters: Array<keyof APMQueryParams> = [
Expand All @@ -34,6 +36,7 @@ export function TransactionDetailLink({
transactionName,
transactionType,
latencyAggregationType,
environment,
...rest
}: Props) {
const { urlParams } = useUrlParams();
Expand All @@ -47,8 +50,8 @@ export function TransactionDetailLink({
transactionId,
transactionName,
transactionType,
...(latencyAggregationType ? { latencyAggregationType } : {}),
...pickKeys(urlParams as APMQueryParams, ...persistedFilters),
...pickBy({ latencyAggregationType, environment }, identity),
},
search: location.search,
});
Expand Down
Loading

0 comments on commit 07caf19

Please sign in to comment.