diff --git a/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature b/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature
index bc807d596a272..c98e3f81b2bc6 100644
--- a/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature
+++ b/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature
@@ -37,3 +37,6 @@ Feature: RUM Dashboard
When the user selected the breakdown
Then breakdown series should appear in chart
+ Scenario: Service name filter
+ When a user changes the selected service name
+ Then it displays relevant client metrics
diff --git a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js
index acccd86f3e4d7..ac09e575a46ae 100644
--- a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js
+++ b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js
@@ -9,17 +9,17 @@ module.exports = {
},
"RUM Dashboard": {
"Client metrics": {
- "1": "62 ",
- "2": "0.07 sec",
+ "1": "55 ",
+ "2": "0.08 sec",
"3": "0.01 sec"
},
"Rum page filters (example #1)": {
- "1": "15 ",
- "2": "0.07 sec",
+ "1": "8 ",
+ "2": "0.08 sec",
"3": "0.01 sec"
},
"Rum page filters (example #2)": {
- "1": "35 ",
+ "1": "28 ",
"2": "0.07 sec",
"3": "0.01 sec"
},
@@ -31,6 +31,11 @@ module.exports = {
},
"Page load distribution chart legends": {
"1": "Overall"
+ },
+ "Service name filter": {
+ "1": "7 ",
+ "2": "0.07 sec",
+ "3": "0.01 sec"
}
}
}
diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/page_load_dist.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/page_load_dist.ts
index 809b22490abd6..89dc3437c3e69 100644
--- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/page_load_dist.ts
+++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/page_load_dist.ts
@@ -18,7 +18,9 @@ Given(`a user click page load breakdown filter`, () => {
});
When(`the user selected the breakdown`, () => {
- cy.get('[data-cy=filter-breakdown-item_Browser]').click();
+ cy.get('[data-cy=filter-breakdown-item_Browser]', {
+ timeout: DEFAULT_TIMEOUT,
+ }).click();
// click outside popover to close it
cy.get('[data-cy=pageLoadDist]').click();
});
diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/rum_filters.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/rum_filters.ts
index 8654895539b39..074e08e6f52b7 100644
--- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/rum_filters.ts
+++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/rum_filters.ts
@@ -5,6 +5,7 @@
*/
import { When, Then } from 'cypress-cucumber-preprocessor/steps';
+import { DEFAULT_TIMEOUT } from './rum_dashboard';
import { DEFAULT_TIMEOUT } from '../apm';
diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/service_name_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/service_name_filter.ts
new file mode 100644
index 0000000000000..9a3d7b52674b7
--- /dev/null
+++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum/service_name_filter.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { When, Then } from 'cypress-cucumber-preprocessor/steps';
+import { DEFAULT_TIMEOUT } from '../apm';
+
+When('a user changes the selected service name', (filterName) => {
+ // wait for all loading to finish
+ cy.get('kbnLoadingIndicator').should('not.be.visible');
+ cy.get(`[data-cy=serviceNameFilter]`, { timeout: DEFAULT_TIMEOUT }).select(
+ 'opbean-client-rum'
+ );
+});
+
+Then(`it displays relevant client metrics`, () => {
+ const clientMetrics = '[data-cy=client-metrics] .euiStat__title';
+
+ // wait for all loading to finish
+ cy.get('kbnLoadingIndicator').should('not.be.visible');
+ cy.get('.euiStat__title-isLoading').should('not.be.visible');
+
+ cy.get(clientMetrics).eq(2).invoke('text').snapshot();
+
+ cy.get(clientMetrics).eq(1).invoke('text').snapshot();
+
+ cy.get(clientMetrics).eq(0).invoke('text').snapshot();
+});
diff --git a/x-pack/plugins/apm/e2e/ingest-data/replay.js b/x-pack/plugins/apm/e2e/ingest-data/replay.js
index 483cc99df7470..6bab95635f558 100644
--- a/x-pack/plugins/apm/e2e/ingest-data/replay.js
+++ b/x-pack/plugins/apm/e2e/ingest-data/replay.js
@@ -69,6 +69,14 @@ function incrementSpinnerCount({ success }) {
spinner.text = `Remaining: ${remaining}. Succeeded: ${requestProgress.succeeded}. Failed: ${requestProgress.failed}.`;
}
let iterIndex = 0;
+
+function setRumAgent(item) {
+ item.body = item.body.replace(
+ '"name":"client"',
+ '"name":"opbean-client-rum"'
+ );
+}
+
async function insertItem(item) {
try {
const url = `${APM_SERVER_URL}${item.url}`;
@@ -78,6 +86,8 @@ async function insertItem(item) {
if (item.url === '/intake/v2/rum/events') {
if (iterIndex === userAgents.length) {
+ // set some event agent to opbean
+ setRumAgent(item);
iterIndex = 0;
}
headers['User-Agent'] = userAgents[iterIndex];
diff --git a/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx b/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx
index 295f343b411a9..1625fb4c1409e 100644
--- a/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/Main/route_config/index.tsx
@@ -259,4 +259,13 @@ export const routes: BreadcrumbRoute[] = [
}),
name: RouteName.RUM_OVERVIEW,
},
+ {
+ exact: true,
+ path: '/services/:serviceName/rum-overview',
+ component: () => ,
+ breadcrumb: i18n.translate('xpack.apm.home.rumOverview.title', {
+ defaultMessage: 'Real User Monitoring',
+ }),
+ name: RouteName.RUM_OVERVIEW,
+ },
];
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx
index c9e475ef15316..3ddaa66b8de5e 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx
@@ -11,6 +11,7 @@ import {
EuiSpacer,
} from '@elastic/eui';
import React, { useMemo } from 'react';
+import { useRouteMatch } from 'react-router-dom';
import { useTrackPageview } from '../../../../../observability/public';
import { LocalUIFilters } from '../../shared/LocalUIFilters';
import { PROJECTION } from '../../../../common/projections/typings';
@@ -37,6 +38,10 @@ export function RumOverview() {
urlParams: { start, end },
} = useUrlParams();
+ const isRumServiceRoute = useRouteMatch(
+ '/services/:serviceName/rum-overview'
+ );
+
const { data } = useFetcher(
(callApmApi) => {
if (start && end) {
@@ -61,13 +66,17 @@ export function RumOverview() {
- service.serviceName) ?? []
- }
- />
-
-
+ {!isRumServiceRoute && (
+ <>
+ service.serviceName) ?? []
+ }
+ />
+
+ {' '}
+ >
+ )}
diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx
index 81bdbdad805d6..ce60ffa4ba4e3 100644
--- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx
+++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx
@@ -22,11 +22,17 @@ import { ServiceMap } from '../ServiceMap';
import { ServiceMetrics } from '../ServiceMetrics';
import { ServiceNodeOverview } from '../ServiceNodeOverview';
import { TransactionOverview } from '../TransactionOverview';
-import { RumOverviewLink } from '../../shared/Links/apm/RumOverviewLink';
import { RumOverview } from '../RumDashboard';
+import { RumOverviewLink } from '../../shared/Links/apm/RumOverviewLink';
interface Props {
- tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map';
+ tab:
+ | 'transactions'
+ | 'errors'
+ | 'metrics'
+ | 'nodes'
+ | 'service-map'
+ | 'rum-overview';
}
export function ServiceDetailTabs({ tab }: Props) {
@@ -115,7 +121,7 @@ export function ServiceDetailTabs({ tab }: Props) {
if (isRumAgentName(agentName)) {
tabs.push({
link: (
-
+
{i18n.translate('xpack.apm.home.rumTabLabel', {
defaultMessage: 'Real User Monitoring',
})}
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx
index abca9817bd69d..729ed9b10f827 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/Links/apm/RumOverviewLink.tsx
@@ -11,21 +11,17 @@
*/
import React from 'react';
import { APMLink, APMLinkExtendProps } from './APMLink';
-import { useUrlParams } from '../../../../hooks/useUrlParams';
-import { pickKeys } from '../../../../../common/utils/pick_keys';
-const RumOverviewLink = (props: APMLinkExtendProps) => {
- const { urlParams } = useUrlParams();
+interface RumOverviewLinkProps extends APMLinkExtendProps {
+ serviceName?: string;
+}
+export function RumOverviewLink({
+ serviceName,
+ ...rest
+}: RumOverviewLinkProps) {
+ const path = serviceName
+ ? `/services/${serviceName}/rum-overview`
+ : '/rum-overview';
- const persistedFilters = pickKeys(
- urlParams,
- 'transactionResult',
- 'host',
- 'containerId',
- 'podName'
- );
-
- return ;
-};
-
-export { RumOverviewLink };
+ return ;
+}
diff --git a/x-pack/plugins/apm/public/components/shared/LocalUIFilters/ServiceNameFilter/index.tsx b/x-pack/plugins/apm/public/components/shared/LocalUIFilters/ServiceNameFilter/index.tsx
index e12a4a4831e17..0bb62bd8efcff 100644
--- a/x-pack/plugins/apm/public/components/shared/LocalUIFilters/ServiceNameFilter/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/LocalUIFilters/ServiceNameFilter/index.tsx
@@ -60,6 +60,7 @@ const ServiceNameFilter = ({ serviceNames }: Props) => {