From 1a3f542522dbe731483f9a17da8fb45628056d4e Mon Sep 17 00:00:00 2001 From: "opensearch-trigger-bot[bot]" <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:45:40 -0400 Subject: [PATCH] trace analytics collapse dashboard queries, align naming to industry conventions (#514) (#961) * trace analytics v2 first remove expensive dashboard page * get trace groups request working and mapping correctly * get trace group filter fully working * try some service map adjustments * change to up down to fully show labels * put dashboard in accordian at bottom of services and only make calls if it is open * some changes to support dashboard content in accordian * demo code * fix tests * remove dashboard from app analytics * fix up with tests * fix test * revert only and extract to constant * add auth const * address self-PR review * remove unecessary code * change timeout to 25 seconds * change to row in accordian * update labels and tests * update cypress test * verify cypress tests work with changes * remove accidental only * address PR review comments * make missing configuration more clear * update snapshots * update snapshot --------- (cherry picked from commit d9cb4764f3e031cfbc455ac647a46cf3516505da) Signed-off-by: Derek Ho Signed-off-by: github-actions[bot] Co-authored-by: github-actions[bot] --- .../4_trace_analytics_dashboard.spec.js | 41 +- .../5_trace_analytics_services.spec.js | 24 +- .../6_trace_analytics_traces.spec.js | 4 +- .cypress/integration/7_app_analytics.spec.js | 12 +- .cypress/utils/constants.js | 1 + .../__snapshots__/create.test.tsx.snap | 288 +- .../service_config.test.tsx.snap | 108 +- .../components/application.tsx | 24 - .../components/common/helper_functions.tsx | 24 +- .../__snapshots__/service_map.test.tsx.snap | 6 +- .../service_map_scale.test.tsx.snap | 4 +- .../components/common/plots/service_map.tsx | 17 +- .../common/plots/service_map_scale.tsx | 10 +- .../__snapshots__/dashboard.test.tsx.snap | 3772 +---------------- .../dashboard_table.test.tsx.snap | 48 +- .../top_error_rates_table.test.tsx.snap | 16 +- .../top_latency_table.test.tsx.snap | 34 +- .../dashboard/dashboard_content.tsx | 44 +- .../components/dashboard/dashboard_table.tsx | 6 +- .../dashboard/top_error_rates_table.tsx | 2 +- .../components/dashboard/top_groups_page.tsx | 4 +- .../dashboard/top_latency_table.tsx | 4 +- .../__snapshots__/service_view.test.tsx.snap | 4 +- .../__snapshots__/services.test.tsx.snap | 472 ++- .../services_table.test.tsx.snap | 64 +- .../components/services/service_view.tsx | 6 +- .../components/services/services.tsx | 7 +- .../components/services/services_content.tsx | 32 +- .../components/services/services_table.tsx | 4 +- .../__snapshots__/traces.test.tsx.snap | 42 - .../__snapshots__/traces_table.test.tsx.snap | 16 +- .../components/traces/traces.tsx | 5 +- .../components/traces/traces_table.tsx | 2 +- public/components/trace_analytics/home.tsx | 29 +- .../requests/dashboard_request_handler.ts | 13 +- .../requests/request_handler.ts | 20 +- .../trace_analytics/trace_side_nav.tsx | 20 +- test/constants.ts | 16 +- 38 files changed, 942 insertions(+), 4303 deletions(-) diff --git a/.cypress/integration/4_trace_analytics_dashboard.spec.js b/.cypress/integration/4_trace_analytics_dashboard.spec.js index 656ac7e98..be31f2183 100644 --- a/.cypress/integration/4_trace_analytics_dashboard.spec.js +++ b/.cypress/integration/4_trace_analytics_dashboard.spec.js @@ -6,6 +6,9 @@ /// import { testDataSet, delay, setTimeFilter, jaegerTestDataSet } from '../utils/constants'; +import { suppressResizeObserverIssue } from '../utils/constants'; + +suppressResizeObserverIssue();//needs to be in file once describe('Dump test data', () => { it('Indexes test data', () => { @@ -88,6 +91,7 @@ describe('Testing dashboard table', () => { }, }); setTimeFilter(); + cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click(); }); it('Renders the dashboard table', () => { @@ -97,15 +101,6 @@ describe('Testing dashboard table', () => { cy.contains('7.14%').should('exist'); }); - it('Has working breadcrumbs', () => { - cy.get('.euiBreadcrumb').contains('Dashboard').click(); - cy.get('.euiTitle').contains('Dashboard').should('exist'); - cy.get('.euiBreadcrumb').contains('Trace analytics').click(); - cy.get('.euiTitle').contains('Dashboard').should('exist'); - cy.get('.euiBreadcrumb').contains('Observability').click(); - cy.get('.euiTitle').contains('Logs').should('exist'); - }); - it('Adds the percentile filters', () => { cy.contains(' >= 95 percentile').click({ force: true }); cy.contains(' >= 95 percentile').click({ force: true }); @@ -131,7 +126,6 @@ describe('Testing dashboard table', () => { it('Redirects to traces table with filter', () => { cy.get('.euiLink').contains('13').click(); - cy.get('h2.euiTitle').contains('Traces').should('exist'); cy.contains(' (13)').should('exist'); cy.contains('client_create_order').should('exist'); @@ -149,20 +143,20 @@ describe('Testing plots', () => { }, }); setTimeFilter(); + cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click(); }); it('Renders service map', () => { // plotly scale texts are in attribute "data-unformatted" - cy.get('text.ytitle[data-unformatted="Latency (ms)"]').should('exist'); + cy.get('text.ytitle[data-unformatted="Average duration (ms)"]').should('exist'); cy.get('text[data-unformatted="200"]').should('exist'); cy.get('.vis-network').should('exist'); - cy.get('.euiButton__text[title="Error rate"]').click(); - cy.get('text.ytitle[data-unformatted="Error rate"]').should('exist'); - cy.get('text[data-unformatted="10%"]').should('exist'); + cy.get('.euiButton__text[title="Errors"]').click(); + cy.get('text.ytitle[data-unformatted="Error rate (%)"]').should('exist'); - cy.get('.euiButton__text[title="Throughput"]').click(); - cy.get('text.ytitle[data-unformatted="Throughput"]').should('exist'); + cy.get('.euiButton__text[title="Request Rate"]').click(); + cy.get('text.ytitle[data-unformatted="Request rate (spans)"]').should('exist'); cy.get('text[data-unformatted="50"]').should('exist'); cy.get('input[type="search"]').eq(1).focus().type('payment{enter}'); @@ -184,6 +178,7 @@ describe('Latency by trace group table', () =>{ }, }); setTimeFilter(); + cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click(); }); it('Verify columns in Latency by trace group table along with pagination functionality', () => { @@ -194,9 +189,9 @@ describe('Latency by trace group table', () =>{ cy.get('[data-test-subj="tableHeaderCell_24_hour_latency_trend_3"]').should('exist'); cy.get('[data-test-subj="tableHeaderCell_dashboard_error_rate_4"]').should('exist'); cy.get('[data-test-subj="tableHeaderCell_dashboard_traces_5"]').should('exist'); - cy.get('[data-test-subj="tablePaginationPopoverButton"]').click(); + cy.get('[data-test-subj="tablePaginationPopoverButton"]').eq(1).click(); cy.get('.euiIcon.euiIcon--medium.euiIcon--inherit.euiContextMenu__icon').eq(0).should('exist').click(); - cy.get('[data-test-subj="pagination-button-next"]').should('exist').click(); + cy.get('[data-test-subj="pagination-button-next"]').eq(1).should('exist').click(); cy.get('button[data-test-subj="dashboard-table-trace-group-name-button"]').contains('mysql').should('exist'); }); @@ -225,7 +220,7 @@ describe('Latency by trace group table', () =>{ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').click(); cy.wait(delay);//Fails without cy.get('.euiTableCellContent.euiTableCellContent--alignRight.euiTableCellContent--overflowingContent').contains('211.04').should('exist'); - cy.get('button[data-test-subj="dashboard-table-trace-group-name-button"]').click(); + cy.get('button[data-test-subj="dashboard-table-trace-group-name-button"]').eq(0).click(); cy.get('.euiBadge.euiBadge--hollow.euiBadge--iconRight.globalFilterItem').click(); cy.get('.euiIcon.euiIcon--medium.euiContextMenu__arrow').click(); cy.get('.euiContextMenuPanelTitle').contains('Edit filter').should('exist'); @@ -350,6 +345,7 @@ describe('Testing switch mode to jaeger', () => { setTimeFilter(); cy.get("[data-test-subj='indexPattern-switch-link']").click(); cy.get("[data-test-subj='jaeger-mode']").click(); + cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click(); }); it('Verifies errors mode columns and data', () => { @@ -358,15 +354,14 @@ describe('Testing switch mode to jaeger', () => { cy.contains('100%').should('exist'); cy.contains('7').should('exist'); cy.contains('Service and Operation Name').should('exist'); - cy.contains('Average latency (ms)').should('exist'); + cy.contains('Average duration (ms)').should('exist'); cy.contains('Error rate').should('exist'); cy.contains('Traces').should('exist'); }); it('Verifies traces links to traces page', () => { - cy.get('.euiLink').contains('7').click(); + cy.get('[data-test-subj="dashboard-table-traces-button"]').contains('7').click(); - cy.get('h2.euiTitle').contains('Traces').should('exist'); cy.contains(' (7)').should('exist'); cy.get("[data-test-subj='filterBadge']").eq(0).contains('process.serviceName: redis') cy.get("[data-test-subj='filterBadge']").eq(1).contains('operationName: GetDriver'); @@ -379,7 +374,7 @@ describe('Testing switch mode to jaeger', () => { cy.contains('0%').should('exist'); cy.contains('8').should('exist'); cy.contains('Service and Operation Name').should('exist'); - cy.contains('Average latency (ms)').should('exist'); + cy.contains('Average duration (ms)').should('exist'); cy.contains('Error rate').should('exist'); cy.contains('Traces').should('exist'); }); diff --git a/.cypress/integration/5_trace_analytics_services.spec.js b/.cypress/integration/5_trace_analytics_services.spec.js index de6456649..7f7351382 100644 --- a/.cypress/integration/5_trace_analytics_services.spec.js +++ b/.cypress/integration/5_trace_analytics_services.spec.js @@ -5,7 +5,10 @@ /// -import { delay, SERVICE_NAME, SERVICE_SPAN_ID, setTimeFilter, verify_traces_spans_data_grid_cols_exists, count_table_row } from '../utils/constants'; +import { delay, SERVICE_NAME, SERVICE_SPAN_ID, setTimeFilter, verify_traces_spans_data_grid_cols_exists, count_table_row, AUTH_SERVICE_SPAN_ID } from '../utils/constants'; +import { suppressResizeObserverIssue } from '../utils/constants'; + +suppressResizeObserverIssue();//needs to be in file once describe('Testing services table empty state', () => { beforeEach(() => { @@ -49,9 +52,9 @@ describe('Testing services table', () => { it('Verify columns in Services table', () => { cy.get('.euiFlexItem.euiFlexItem--flexGrow10 .panel-title').contains('Services').should('exist'); cy.get('.euiTableCellContent__text[title="Name"]').should('exist'); - cy.get('.euiTableCellContent__text[title="Average latency (ms)"]').should('exist'); + cy.get('.euiTableCellContent__text[title="Average duration (ms)"]').should('exist'); cy.get('.euiTableCellContent__text[title="Error rate"]').should('exist'); - cy.get('.euiTableCellContent__text[title="Throughput"]').should('exist'); + cy.get('.euiTableCellContent__text[title="Request rate"]').should('exist'); cy.get('.euiTableCellContent__text[title="No. of connected services"]').should('exist'); cy.get('.euiTableCellContent__text[title="Connected services"]').should('exist'); cy.get('.euiTableCellContent__text[title="Traces"]').should('exist'); @@ -110,9 +113,7 @@ describe('Testing service view', () => { cy.get('.euiBreadcrumb').contains(SERVICE_NAME).click(); cy.get('h2.euiTitle').contains(SERVICE_NAME).should('exist'); cy.get('.euiBreadcrumb').contains('Services').click(); - cy.get('.euiTitle').contains('Services').should('exist'); cy.get('.euiBreadcrumb').contains('Trace analytics').click(); - cy.get('.euiTitle').contains('Dashboard').should('exist'); cy.get('.euiBreadcrumb').contains('Observability').click(); cy.get('.euiTitle').contains('Logs').should('exist'); }); @@ -143,10 +144,10 @@ describe('Testing Service map', () => { it('Render Service map', () => { cy.get('.euiText.euiText--medium .panel-title').contains('Service map'); cy.get('[data-test-subj="latency"]').should('exist'); - cy.get('.ytitle').contains('Latency (ms)'); - cy.get('[data-text = "Error rate"]').click(); + cy.get('.ytitle').contains('Average duration (ms)'); + cy.get('[data-text = "Errors"]').click(); cy.contains('60%'); - cy.get('[data-text = "Throughput"]').click(); + cy.get('[data-text = "Duration"]').click(); cy.contains('100'); cy.get('.euiText.euiText--medium').contains('Focus on').should('exist'); cy.get('[placeholder="Service name"]').focus().type('database{enter}'); @@ -238,7 +239,7 @@ describe('Testing traces Spans table and verify columns functionality', () => { it('Renders the spans table and click on first span to verify details', () => { cy.get('.euiLink.euiLink--primary').contains('authentication').should('exist').click(); verify_traces_spans_data_grid_cols_exists(); - cy.get('.euiLink--primary').eq(4).click(); + cy.contains(AUTH_SERVICE_SPAN_ID).click(); cy.get('[data-test-subj="spanDetailFlyout"] .euiTitle.euiTitle--medium').contains('Span detail').should('exist'); cy.get('.euiFlyoutBody .panel-title').contains('Overview').should('exist'); cy.get('.euiTextColor.euiTextColor--subdued').contains('Span ID').should('exist'); @@ -283,16 +284,15 @@ describe('Testing switch mode to jaeger', () => { cy.contains('310.29').should('exist'); cy.contains('0%').should('exist'); cy.contains('Name').should('exist'); - cy.contains('Average latency (ms)').should('exist'); + cy.contains('Average duration (ms)').should('exist'); cy.contains('Error rate').should('exist'); - cy.contains('Throughput').should('exist'); + cy.contains('Request rate').should('exist'); cy.contains('Traces').should('exist'); }); it('Verifies traces links to traces page with filter applied', () => { cy.get('.euiTableRow').should('have.length.lessThan', 7);//Replaces Wait cy.get('.euiLink').contains('7').click(); - cy.get('h2.euiTitle').contains('Traces').should('exist'); cy.contains(' (7)').should('exist'); cy.get("[data-test-subj='filterBadge']").eq(0).contains('process.serviceName: customer') }) diff --git a/.cypress/integration/6_trace_analytics_traces.spec.js b/.cypress/integration/6_trace_analytics_traces.spec.js index c3ca6f339..336f5b6ff 100644 --- a/.cypress/integration/6_trace_analytics_traces.spec.js +++ b/.cypress/integration/6_trace_analytics_traces.spec.js @@ -87,9 +87,7 @@ describe('Testing trace view', () => { cy.get(`.euiBreadcrumb[href="#/traces/${TRACE_ID}"]`).click(); cy.get('h2.euiTitle').contains(TRACE_ID).should('exist'); cy.get('.euiBreadcrumb[href="#/traces"]').click(); - cy.get('.euiTitle').contains('Traces').should('exist'); cy.get('.euiBreadcrumb[href="#/"]').click(); - cy.get('.euiTitle').contains('Dashboard').should('exist'); cy.get('.euiBreadcrumb[href="observability-logs#/"]').click(); cy.get('.euiTitle').contains('Logs').should('exist'); }); @@ -125,7 +123,7 @@ describe('Testing traces table', () => { it('Renders the traces table and verify Table Column, Pagination and Rows Data ', () => { cy.get('.euiTableCellContent__text').contains('Trace ID').should('exist'); cy.get('.euiTableCellContent__text').contains('Trace group').should('exist'); - cy.get('.euiTableCellContent__text').contains('Latency (ms)').should('exist'); + cy.get('.euiTableCellContent__text').contains('Duration (ms)').should('exist'); cy.get('.euiTableCellContent__text').contains('Percentile in trace group').should('exist'); cy.get('.euiTableCellContent__text').contains('Errors').should('exist'); cy.get('.euiTableCellContent__text').contains('Last updated').should('exist'); diff --git a/.cypress/integration/7_app_analytics.spec.js b/.cypress/integration/7_app_analytics.spec.js index 8cf5b223b..064c8c57a 100644 --- a/.cypress/integration/7_app_analytics.spec.js +++ b/.cypress/integration/7_app_analytics.spec.js @@ -253,7 +253,8 @@ describe('Viewing application', () => { }); it('Shows latency variance in dashboards table', () => { - changeTimeTo24('months'); + changeTimeTo24('years'); + cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click(); cy.get('[data-test-subj="dashboardTable"]').first().within(($table) => { cy.get('.plot-container').should('have.length.at.least', 1); }) @@ -261,11 +262,10 @@ describe('Viewing application', () => { it('Adds filter when Trace group name is clicked', () => { cy.wait(delay);//List not loading without - cy.get('[data-test-subj="app-analytics-overviewTab"]').click(); + cy.get('[data-test-subj="trace-groups-service-operation-accordian"]').click(); cy.get('[data-test-subj="dashboard-table-trace-group-name-button"]').contains('client_create_order').click(); - cy.get('.euiTableRow').should('have.length', 1, { timeout: timeoutDelay }); cy.get('[data-test-subj="client_create_orderFilterBadge"]').should('exist'); - cy.get('[data-test-subj="filterBadge"]').click(); + cy.get('[data-test-subj="filterBadge"]').eq(1).click(); cy.get('[data-test-subj="deleteFilterIcon"]').click(); cy.get('[data-test-subj="client_create_orderFilterBadge"]').should('not.exist'); }); @@ -276,7 +276,7 @@ describe('Viewing application', () => { cy.get('[data-test-subj="serviceDetailFlyoutTitle"]').should('be.visible'); cy.get('[data-test-subj="serviceDetailFlyout"]').within(($flyout) => { cy.get('[data-test-subj="Number of connected servicesDescriptionList"]').should('contain', '3'); - cy.get('[data-text="Error rate"]').click(); + cy.get('[data-text="Errors"]').click(); cy.get('.ytitle').contains('Error rate').should('exist'); }); cy.get('[data-test-subj="dataGridRowCell"] button').contains('718dc32a693c8a17').click(); @@ -307,6 +307,7 @@ describe('Viewing application', () => { it('Opens span detail flyout when Span ID is clicked', () => { cy.get('[data-test-subj="app-analytics-traceTab"]').click(); cy.wait(delay); + cy.get('input[type="search"]').focus().type(`5ff3516909562c60`); cy.get('[data-test-subj="dataGridRowCell"]').contains('5ff3516909562c60').click(); cy.get('[data-test-subj="spanDetailFlyout"]').should('be.visible'); cy.get('[data-test-subj="spanDetailFlyout"]').within(($flyout) => { @@ -543,6 +544,7 @@ describe('Editing application', () => { }); }); + describe('Application Analytics home page', () => { beforeEach(() => { moveToHomePage(); diff --git a/.cypress/utils/constants.js b/.cypress/utils/constants.js index d5f782529..826f8d2a0 100644 --- a/.cypress/utils/constants.js +++ b/.cypress/utils/constants.js @@ -11,6 +11,7 @@ export const TRACE_ID = '8832ed6abbb2a83516461960c89af49d'; export const SPAN_ID = 'a673bc074b438374'; export const SERVICE_NAME = 'frontend-client'; export const SERVICE_SPAN_ID = '7df5609a6d104736'; +export const AUTH_SERVICE_SPAN_ID = '277a5934acf55dcf'; export const testDataSet = [ { diff --git a/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap b/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap index fd2d3f4e4..a52ccd95d 100644 --- a/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap +++ b/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap @@ -578,8 +578,8 @@ Object { > - Latency + Duration @@ -603,8 +603,8 @@ Object { > - Error rate + Errors @@ -627,8 +627,8 @@ Object { > - Throughput + Request Rate @@ -1831,8 +1831,8 @@ Object { > - Latency + Duration @@ -1856,8 +1856,8 @@ Object { > - Error rate + Errors @@ -1880,8 +1880,8 @@ Object { > - Throughput + Request Rate @@ -3023,8 +3023,8 @@ Object { > - Latency + Duration @@ -3048,8 +3048,8 @@ Object { > - Error rate + Errors @@ -3072,8 +3072,8 @@ Object { > - Throughput + Request Rate @@ -4190,8 +4190,8 @@ Object { > - Latency + Duration @@ -4215,8 +4215,8 @@ Object { > - Error rate + Errors @@ -4239,8 +4239,8 @@ Object { > - Throughput + Request Rate @@ -5450,8 +5450,8 @@ Object { > - Latency + Duration @@ -5475,8 +5475,8 @@ Object { > - Error rate + Errors @@ -5499,8 +5499,8 @@ Object { > - Throughput + Request Rate @@ -6617,8 +6617,8 @@ Object { > - Latency + Duration @@ -6642,8 +6642,8 @@ Object { > - Error rate + Errors @@ -6666,8 +6666,8 @@ Object { > - Throughput + Request Rate @@ -7792,8 +7792,8 @@ Object { > - Latency + Duration @@ -7817,8 +7817,8 @@ Object { > - Error rate + Errors @@ -7841,8 +7841,8 @@ Object { > - Throughput + Request Rate @@ -8896,8 +8896,8 @@ Object { > - Latency + Duration @@ -8921,8 +8921,8 @@ Object { > - Error rate + Errors @@ -8945,8 +8945,8 @@ Object { > - Throughput + Request Rate @@ -10074,8 +10074,8 @@ Object { > - Latency + Duration @@ -10099,8 +10099,8 @@ Object { > - Error rate + Errors @@ -10123,8 +10123,8 @@ Object { > - Throughput + Request Rate @@ -11207,8 +11207,8 @@ Object { > - Latency + Duration @@ -11232,8 +11232,8 @@ Object { > - Error rate + Errors @@ -11256,8 +11256,8 @@ Object { > - Throughput + Request Rate @@ -12431,8 +12431,8 @@ Object { > - Latency + Duration @@ -12456,8 +12456,8 @@ Object { > - Error rate + Errors @@ -12480,8 +12480,8 @@ Object { > - Throughput + Request Rate @@ -13598,8 +13598,8 @@ Object { > - Latency + Duration @@ -13623,8 +13623,8 @@ Object { > - Error rate + Errors @@ -13647,8 +13647,8 @@ Object { > - Throughput + Request Rate @@ -14790,8 +14790,8 @@ Object { > - Latency + Duration @@ -14815,8 +14815,8 @@ Object { > - Error rate + Errors @@ -14839,8 +14839,8 @@ Object { > - Throughput + Request Rate @@ -15957,8 +15957,8 @@ Object { > - Latency + Duration @@ -15982,8 +15982,8 @@ Object { > - Error rate + Errors @@ -16006,8 +16006,8 @@ Object { > - Throughput + Request Rate @@ -17187,8 +17187,8 @@ Object { > - Latency + Duration @@ -17212,8 +17212,8 @@ Object { > - Error rate + Errors @@ -17236,8 +17236,8 @@ Object { > - Throughput + Request Rate @@ -18436,8 +18436,8 @@ Object { > - Latency + Duration @@ -18461,8 +18461,8 @@ Object { > - Error rate + Errors @@ -18485,8 +18485,8 @@ Object { > - Throughput + Request Rate diff --git a/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap b/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap index 6a9d6769a..b8bc8d640 100644 --- a/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap +++ b/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap @@ -686,15 +686,15 @@ exports[`Service Config component renders empty service config 1`] = ` Array [ Object { "id": "latency", - "label": "Latency", + "label": "Duration", }, Object { "id": "error_rate", - "label": "Error rate", + "label": "Errors", }, Object { "id": "throughput", - "label": "Throughput", + "label": "Request Rate", }, ] } @@ -719,7 +719,7 @@ exports[`Service Config component renders empty service config 1`] = ` isIconOnly={false} isSelected={true} key="0" - label="Latency" + label="Duration" name="random_html_id" onChange={[Function]} size="s" @@ -737,9 +737,9 @@ exports[`Service Config component renders empty service config 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Latency", + "data-text": "Duration", "ref": [Function], - "title": "Latency", + "title": "Duration", } } > @@ -760,9 +760,9 @@ exports[`Service Config component renders empty service config 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Latency", + "data-text": "Duration", "ref": [Function], - "title": "Latency", + "title": "Duration", } } > @@ -771,8 +771,8 @@ exports[`Service Config component renders empty service config 1`] = ` > - Latency + Duration @@ -799,7 +799,7 @@ exports[`Service Config component renders empty service config 1`] = ` isIconOnly={false} isSelected={false} key="1" - label="Error rate" + label="Errors" name="random_html_id" onChange={[Function]} size="s" @@ -817,9 +817,9 @@ exports[`Service Config component renders empty service config 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -840,9 +840,9 @@ exports[`Service Config component renders empty service config 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -851,8 +851,8 @@ exports[`Service Config component renders empty service config 1`] = ` > - Error rate + Errors @@ -879,7 +879,7 @@ exports[`Service Config component renders empty service config 1`] = ` isIconOnly={false} isSelected={false} key="2" - label="Throughput" + label="Request Rate" name="random_html_id" onChange={[Function]} size="s" @@ -897,9 +897,9 @@ exports[`Service Config component renders empty service config 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -920,9 +920,9 @@ exports[`Service Config component renders empty service config 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -931,8 +931,8 @@ exports[`Service Config component renders empty service config 1`] = ` > - Throughput + Request Rate @@ -1884,15 +1884,15 @@ exports[`Service Config component renders with one service selected 1`] = ` Array [ Object { "id": "latency", - "label": "Latency", + "label": "Duration", }, Object { "id": "error_rate", - "label": "Error rate", + "label": "Errors", }, Object { "id": "throughput", - "label": "Throughput", + "label": "Request Rate", }, ] } @@ -1917,7 +1917,7 @@ exports[`Service Config component renders with one service selected 1`] = ` isIconOnly={false} isSelected={true} key="0" - label="Latency" + label="Duration" name="random_html_id" onChange={[Function]} size="s" @@ -1935,9 +1935,9 @@ exports[`Service Config component renders with one service selected 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Latency", + "data-text": "Duration", "ref": [Function], - "title": "Latency", + "title": "Duration", } } > @@ -1958,9 +1958,9 @@ exports[`Service Config component renders with one service selected 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Latency", + "data-text": "Duration", "ref": [Function], - "title": "Latency", + "title": "Duration", } } > @@ -1969,8 +1969,8 @@ exports[`Service Config component renders with one service selected 1`] = ` > - Latency + Duration @@ -1997,7 +1997,7 @@ exports[`Service Config component renders with one service selected 1`] = ` isIconOnly={false} isSelected={false} key="1" - label="Error rate" + label="Errors" name="random_html_id" onChange={[Function]} size="s" @@ -2015,9 +2015,9 @@ exports[`Service Config component renders with one service selected 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -2038,9 +2038,9 @@ exports[`Service Config component renders with one service selected 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -2049,8 +2049,8 @@ exports[`Service Config component renders with one service selected 1`] = ` > - Error rate + Errors @@ -2077,7 +2077,7 @@ exports[`Service Config component renders with one service selected 1`] = ` isIconOnly={false} isSelected={false} key="2" - label="Throughput" + label="Request Rate" name="random_html_id" onChange={[Function]} size="s" @@ -2095,9 +2095,9 @@ exports[`Service Config component renders with one service selected 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -2118,9 +2118,9 @@ exports[`Service Config component renders with one service selected 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -2129,8 +2129,8 @@ exports[`Service Config component renders with one service selected 1`] = ` > - Throughput + Request Rate diff --git a/public/components/application_analytics/components/application.tsx b/public/components/application_analytics/components/application.tsx index 9e1186324..d5ba1b8fe 100644 --- a/public/components/application_analytics/components/application.tsx +++ b/public/components/application_analytics/components/application.tsx @@ -284,25 +284,6 @@ export function Application(props: AppDetailProps) { }, ]; - const getOverview = () => { - return ( - <> - - - - ); - }; - const nameColumnAction = (item: any) => openServiceFlyout(item); const traceColumnAction = () => switchToTrace(); @@ -497,11 +478,6 @@ export function Application(props: AppDetailProps) { } const appAnalyticsTabs = [ - getAppAnalyticsTab({ - tabId: TAB_OVERVIEW_ID, - tabTitle: TAB_OVERVIEW_TITLE, - getContent: () => getOverview(), - }), getAppAnalyticsTab({ tabId: TAB_SERVICE_ID, tabTitle: TAB_SERVICE_TITLE, diff --git a/public/components/trace_analytics/components/common/helper_functions.tsx b/public/components/trace_analytics/components/common/helper_functions.tsx index f93222fb2..3e996b0aa 100644 --- a/public/components/trace_analytics/components/common/helper_functions.tsx +++ b/public/components/trace_analytics/components/common/helper_functions.tsx @@ -22,6 +22,10 @@ import { serviceMapColorPalette } from './color_palette'; import { FilterType } from './filters/filters'; import { ServiceObject } from './plots/service_map'; +const missingJaegerTracesConfigurationMessage = `The indices required for trace analytics (${JAEGER_INDEX_NAME} and ${JAEGER_SERVICE_INDEX_NAME}) do not exist or you do not have permission to access them.`; + +const missingDataPrepperTracesConfigurationMessage = `The indices required for trace analytics (${DATA_PREPPER_INDEX_NAME} and ${DATA_PREPPER_SERVICE_INDEX_NAME}) do not exist or you do not have permission to access them.`; + export function PanelTitle({ title, totalItems }: { title: string; totalItems?: number }) { return ( @@ -51,16 +55,16 @@ export function NoMatchMessage(props: { size: SpacerSize }) { ); } -export function MissingConfigurationMessage(props: {mode: TraceAnalyticsMode}) { +export function MissingConfigurationMessage(props: { mode: TraceAnalyticsMode }) { + const missingConfigurationBody = + props.mode === 'jaeger' + ? missingJaegerTracesConfigurationMessage + : missingDataPrepperTracesConfigurationMessage; return ( <> Trace Analytics not set up} - body={ - - {`The indices required for trace analytics (${props.mode === 'jaeger' ? JAEGER_INDEX_NAME : DATA_PREPPER_INDEX_NAME} and ${props.mode === 'jaeger' ? JAEGER_SERVICE_INDEX_NAME : DATA_PREPPER_SERVICE_INDEX_NAME}) do not exist or you do not have permission to access them.`} - - } + body={{missingConfigurationBody}} actions={ = 0 ? map[service].latency + 'ms' : 'N/A' }`; hover += `\nError rate: ${ map[service].error_rate! >= 0 ? map[service].error_rate + '%' : 'N/A' }`; - hover += `\nThroughput: ${map[service].throughput! >= 0 ? map[service].throughput : 'N/A'}`; + hover += `\nRequest rate: ${map[service].throughput! >= 0 ? map[service].throughput : 'N/A'}`; if (map[service].throughputPerMinute != null) hover += ` (${map[service].throughputPerMinute} per minute)`; @@ -381,7 +385,7 @@ export const filtersToDsl = ( let filterQuery = {}; let field = filter.field; - if (field === 'latency'){ + if (field === 'latency') { if (mode === 'data_prepper') { field = 'traceGroupFields.durationInNanos'; } else if (mode === 'jaeger') { @@ -391,7 +395,7 @@ export const filtersToDsl = ( if (mode === 'data_prepper') { field = 'traceGroupFields.statusCode'; } else if (mode === 'jaeger') { - field = 'tag.error' + field = 'tag.error'; } } let value; diff --git a/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap b/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap index ec80b8296..0d8ec16df 100644 --- a/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap +++ b/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap @@ -18,15 +18,15 @@ exports[`Service map component renders service map 1`] = ` Array [ Object { "id": "latency", - "label": "Latency", + "label": "Duration", }, Object { "id": "error_rate", - "label": "Error rate", + "label": "Errors", }, Object { "id": "throughput", - "label": "Throughput", + "label": "Request Rate", }, ] } diff --git a/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap b/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap index f89aac7e8..30ed8d0d4 100644 --- a/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap +++ b/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap @@ -113,7 +113,7 @@ exports[`Service map scale component renders service map scale plot 1`] = ` ], "title": Object { "standoff": 15, - "text": "Latency (ms)", + "text": "Average duration (ms)", }, "zeroline": false, }, @@ -225,7 +225,7 @@ exports[`Service map scale component renders service map scale plot 1`] = ` ], "title": Object { "standoff": 15, - "text": "Latency (ms)", + "text": "Average duration (ms)", }, "zeroline": false, }, diff --git a/public/components/trace_analytics/components/common/plots/service_map.tsx b/public/components/trace_analytics/components/common/plots/service_map.tsx index a63604968..0f711eb2a 100644 --- a/public/components/trace_analytics/components/common/plots/service_map.tsx +++ b/public/components/trace_analytics/components/common/plots/service_map.tsx @@ -71,26 +71,32 @@ export function ServiceMap({ const toggleButtons = [ { id: 'latency', - label: 'Latency', + label: 'Duration', }, { id: 'error_rate', - label: 'Error rate', + label: 'Errors', }, { id: 'throughput', - label: 'Throughput', + label: 'Request Rate', }, ]; const options = { layout: { - hierarchical: false, + // hierarchical: true, + hierarchical: { + enabled: true, + direction: 'UD', // UD, DU, LR, RL + sortMethod: 'directed', // hubsize, directed + shakeTowards: 'leaves', // roots, leaves + }, }, edges: { arrows: { to: { - enabled: false, + enabled: true, }, }, physics: false, @@ -98,7 +104,6 @@ export function ServiceMap({ nodes: { shape: 'dot', color: '#adadad', - borderWidth: 0, font: { size: 17, color: '#387ab9', diff --git a/public/components/trace_analytics/components/common/plots/service_map_scale.tsx b/public/components/trace_analytics/components/common/plots/service_map_scale.tsx index e9c900bcc..61bba2841 100644 --- a/public/components/trace_analytics/components/common/plots/service_map_scale.tsx +++ b/public/components/trace_analytics/components/common/plots/service_map_scale.tsx @@ -4,9 +4,9 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; -import { BarOrientation } from '../../../../../../common/constants/shared'; import _ from 'lodash'; import React, { useEffect, useState } from 'react'; +import { BarOrientation } from '../../../../../../common/constants/shared'; import { Plt } from '../../../../visualizations/plotly/plot'; import unmatchedNode from '../../../images/unmatched_node.png'; import { getServiceMapScaleColor } from '../helper_functions'; @@ -21,9 +21,11 @@ export function ServiceMapScale(props: { const getScaleData = () => { const ticks = props.ticks; const delta = ticks[1] - ticks[0]; - const title = { latency: 'Latency (ms)', error_rate: 'Error rate', throughput: 'Throughput' }[ - props.idSelected - ]; + const title = { + latency: 'Average duration (ms)', + error_rate: 'Error rate (%)', + throughput: 'Request rate (spans)', + }[props.idSelected]; const percentInterval = 1 / Math.max(ticks.length - 1, 1); const percents = Array.from({ length: ticks.length - 1 }, (v, i) => percentInterval * i); const color = percents diff --git a/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap b/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap index 731ac7253..4fc8791bb 100644 --- a/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap +++ b/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap @@ -525,839 +525,6 @@ exports[`Dashboard component renders dashboard 1`] = ` setStartTime={[MockFunction]} startTime="now-5m" > - - -
- -
- - -
-
- - - - -
- - - - - -
-
-
-
-
-
-
-
- -
- - -
- -
- - } - > -
- - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - > -
-
- - - -
-
-
-
-
- } - iconType={false} - isCustom={true} - startDateControl={
} - > -
- -
- - -
-
- -
- -
- - -
- - -
- - - - - -
-
-
- - -
- - - -
- -
- - - } - closePopover={[Function]} - data-test-subj="global-filter-button" - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="none" - withTitle={true} - > -
-
- - - -
-
-
-
-
-
- -
- - - + Add filter - - } - closePopover={[Function]} - data-test-subj="addfilter" - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - withTitle={true} - > -
-
- - - -
-
-
-
-
-
-
-
-
- - -
-
- +
- - -
- + +
- -
- - Service map - -
-
- - -
- - -
- - - -
- - - - - - - - - - - - - - - -
-
-
- -
-
- -
- -
- -
- Focus on -
-
-
-
- -
- - -
-
- - - - -
- - - - - -
-
-
-
-
-
-
-
-
-
- -
- -
- - -
- - - No data matches the selected filter. Clear the filter and/or increase the time range to see more results. - - } - title={ -

- No matches -

- } - > -
- -

- No matches -

-
- - - -
- - -
- -
- No data matches the selected filter. Clear the filter and/or increase the time range to see more results. -
-
-
-
- - -
- - -
- - -
-
- - -
- - -
- -
- -
- -
- - + -
- -
+
+ - -
-
- - - -
- - - - - -
-
-
-
-
-
-
- - -
- - -
- -
- - } - > -
- - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - > -
-
- - - -
-
-
-
-
- } - iconType={false} - isCustom={true} - startDateControl={
} - > -
- -
- - -
-
- -
- -
- - -
- - -
- - - - - -
-
-
- - -
- - - -
- -
- - - } - closePopover={[Function]} - data-test-subj="global-filter-button" - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="none" - withTitle={true} - > -
-
- - - -
-
-
-
-
-
- -
- - - + Add filter - - } - closePopover={[Function]} - data-test-subj="addfilter" - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - withTitle={true} - > -
-
- - - -
-
-
-
-
-
-
-
-
- - -
- -
- - -
- -
- -
- - -
- Latency by trace group @@ -4018,584 +1840,53 @@ exports[`Dashboard component renders empty dashboard 1`] = ` /> -
- -
- No data matches the selected filter. Clear the filter and/or increase the time range to see more results. -
-
-
-
- - -
- - -
- - -
- - - -
- - -
- -
- - -
- - -
- - Service map - -
-
-
- -
- - -
- - - -
- - - - - - - - - - - - - - - -
-
-
- -
-
- -
- -
- -
- Focus on -
-
-
-
- -
- - -
-
- - - - -
- - - - - -
-
-
-
-
-
-
-
-
-
- -
- -
- - -
- - - No data matches the selected filter. Clear the filter and/or increase the time range to see more results. - - } - title={ -

- No matches -

- } - > -
- -

- No matches -

-
- - - -
- - -
- -
- No data matches the selected filter. Clear the filter and/or increase the time range to see more results. -
-
-
-
- - -
- - -
- - -
-
- - -
- +
+ +
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results. +
+
+
+ + + +
+ + +
+ + +
+ + + +
+ + +
- - -
- -
- - -
-
- - - - -
- - - - - -
-
-
-
-
-
-
-
- -
- - -
- -
- - } - > -
- - - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - > -
-
- - - -
-
-
-
-
- } - iconType={false} - isCustom={true} - startDateControl={
} - > -
- -
- - -
-
- -
- -
- - -
- - -
- - - - - -
-
-
- - -
- - - -
- -
- - - } - closePopover={[Function]} - data-test-subj="global-filter-button" - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="none" - withTitle={true} - > -
-
- - - -
-
-
-
-
-
- -
- - - + Add filter - - } - closePopover={[Function]} - data-test-subj="addfilter" - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - withTitle={true} - > -
-
- - - -
-
-
-
-
-
-
-
-
- - -
-
@@ -6472,9 +2930,9 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -6483,8 +2941,8 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` > - Error rate + Errors @@ -6512,7 +2970,7 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` isIconOnly={false} isSelected={false} key="1" - label="Throughput" + label="Request rate" name="random_html_id" onChange={[Function]} size="s" @@ -6531,9 +2989,9 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request rate", "ref": [Function], - "title": "Throughput", + "title": "Request rate", } } > @@ -6555,9 +3013,9 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request rate", "ref": [Function], - "title": "Throughput", + "title": "Request rate", } } > @@ -6566,8 +3024,8 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` > - Throughput + Request rate diff --git a/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap b/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap index e5a546bb0..fdabcbc28 100644 --- a/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap +++ b/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap @@ -237,7 +237,7 @@ exports[`Dashboard table component renders dashboard table 1`] = ` position="top" > - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms)
- 24-hour latency trend + 24-hour duration trend - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms)
- 24-hour latency trend + 24-hour duration trend - Latency variance (ms) + Duration variance (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms)
- 24-hour latency trend + 24-hour duration trend - Latency variance (ms) + Duration variance (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms)
- 24-hour latency trend + 24-hour duration trend
- 24-hour latency trend + 24-hour duration trend
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms) - Latency variance (ms) + Duration variance (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms) - Latency variance (ms) + Duration variance (ms) - Latency variance (ms) + Duration variance (ms)
- Average latency (ms) + Average duration (ms)
- Average latency (ms) + Average duration (ms) ({}); - const [serviceMapIdSelected, setServiceMapIdSelected] = useState< - 'latency' | 'error_rate' | 'throughput' - >('latency'); const [percentileMap, setPercentileMap] = useState<{ [traceGroup: string]: number[] }>({}); const [filteredService, setFilteredService] = useState(''); const [redirect, setRedirect] = useState(true); const [loading, setLoading] = useState(false); const [showTimeoutToast, setShowTimeoutToast] = useState(false); + const { setToast } = useToast(); useEffect(() => { - if (showTimeoutToast === true && toasts.length === 0) { + if (showTimeoutToast === true && (!toasts || toasts.length === 0)) { setToast!( 'Query took too long to execute.', 'danger', @@ -203,6 +200,7 @@ export function DashboardContent(props: DashboardProps) { tableItems, setTableItems, mode, + () => setShowTimeoutToast(true), setPercentileMap ).then(() => setLoading(false)); // service map should not be filtered by service name (https://github.com/opensearch-project/observability/issues/442) @@ -210,13 +208,6 @@ export function DashboardContent(props: DashboardProps) { serviceMapDSL.query.bool.must = serviceMapDSL.query.bool.must.filter( (must: any) => must?.term?.serviceName == null ); - handleServiceMapRequest( - http, - serviceMapDSL, - mode, - setServiceMap, - currService || filteredService - ); } handleDashboardThroughputPltRequest( @@ -298,21 +289,6 @@ export function DashboardContent(props: DashboardProps) { return ( <> - - {(mode === 'data_prepper' && dataPrepperIndicesExist) || (mode === 'jaeger' && jaegerIndicesExist) ? (
@@ -329,18 +305,8 @@ export function DashboardContent(props: DashboardProps) { /> - - - - + - Latency variance (ms){' '} + Duration variance (ms){' '} {/*
Average
*/}
- Average latency (ms){' '} + Average duration (ms){' '} {/*
24-hour
*/}
- 24-hour latency trend{' '} + 24-hour duration trend{' '} {/*
Average
*/}
- Average latency (ms){' '} + Average duration (ms){' '} - Latency variance (ms){' '} + Duration variance (ms){' '} {/*
Average
*/}
- Average latency (ms){' '} + Average duration (ms){' '} - Average latency (ms) + Average duration (ms) - Throughput + Request rate - -

- Services -

-
@@ -1605,9 +1591,9 @@ exports[`Services component renders empty services page 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Latency", + "data-text": "Duration", "ref": [Function], - "title": "Latency", + "title": "Duration", } } > @@ -1616,8 +1602,8 @@ exports[`Services component renders empty services page 1`] = ` > - Latency + Duration @@ -1644,7 +1630,7 @@ exports[`Services component renders empty services page 1`] = ` isIconOnly={false} isSelected={false} key="1" - label="Error rate" + label="Errors" name="random_html_id" onChange={[Function]} size="s" @@ -1662,9 +1648,9 @@ exports[`Services component renders empty services page 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -1685,9 +1671,9 @@ exports[`Services component renders empty services page 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -1696,8 +1682,8 @@ exports[`Services component renders empty services page 1`] = ` > - Error rate + Errors @@ -1724,7 +1710,7 @@ exports[`Services component renders empty services page 1`] = ` isIconOnly={false} isSelected={false} key="2" - label="Throughput" + label="Request Rate" name="random_html_id" onChange={[Function]} size="s" @@ -1742,9 +1728,9 @@ exports[`Services component renders empty services page 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -1765,9 +1751,9 @@ exports[`Services component renders empty services page 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -1776,8 +1762,8 @@ exports[`Services component renders empty services page 1`] = ` > - Throughput + Request Rate @@ -2009,6 +1995,110 @@ exports[`Services component renders empty services page 1`] = `
+ +
+ + +
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+ `; @@ -2211,20 +2301,6 @@ exports[`Services component renders jaeger services page 1`] = ` startTime="now-5m" traceColumnAction={[Function]} > - -

- Services -

-
+ +
+ + +
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+ `; @@ -3730,20 +3915,6 @@ exports[`Services component renders services page 1`] = ` startTime="now-5m" traceColumnAction={[Function]} > - -

- Services -

-
@@ -5164,9 +5335,9 @@ exports[`Services component renders services page 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Latency", + "data-text": "Duration", "ref": [Function], - "title": "Latency", + "title": "Duration", } } > @@ -5175,8 +5346,8 @@ exports[`Services component renders services page 1`] = ` > - Latency + Duration @@ -5203,7 +5374,7 @@ exports[`Services component renders services page 1`] = ` isIconOnly={false} isSelected={false} key="1" - label="Error rate" + label="Errors" name="random_html_id" onChange={[Function]} size="s" @@ -5221,9 +5392,9 @@ exports[`Services component renders services page 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -5244,9 +5415,9 @@ exports[`Services component renders services page 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Error rate", + "data-text": "Errors", "ref": [Function], - "title": "Error rate", + "title": "Errors", } } > @@ -5255,8 +5426,8 @@ exports[`Services component renders services page 1`] = ` > - Error rate + Errors @@ -5283,7 +5454,7 @@ exports[`Services component renders services page 1`] = ` isIconOnly={false} isSelected={false} key="2" - label="Throughput" + label="Request Rate" name="random_html_id" onChange={[Function]} size="s" @@ -5301,9 +5472,9 @@ exports[`Services component renders services page 1`] = ` textProps={ Object { "className": "euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -5324,9 +5495,9 @@ exports[`Services component renders services page 1`] = ` textProps={ Object { "className": "euiButton__text euiButtonGroupButton__textShift", - "data-text": "Throughput", + "data-text": "Request Rate", "ref": [Function], - "title": "Throughput", + "title": "Request Rate", } } > @@ -5335,8 +5506,8 @@ exports[`Services component renders services page 1`] = ` > - Throughput + Request Rate @@ -5572,6 +5743,115 @@ exports[`Services component renders services page 1`] = `
+ +
+ + +
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+ `; diff --git a/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap b/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap index 9d99f82c4..21bbad336 100644 --- a/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap +++ b/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap @@ -387,7 +387,7 @@ exports[`Services table component renders jaeger services table 1`] = ` Object { "align": "right", "field": "average_latency", - "name": "Average latency (ms)", + "name": "Average duration (ms)", "render": [Function], "sortable": true, }, @@ -401,7 +401,7 @@ exports[`Services table component renders jaeger services table 1`] = ` Object { "align": "right", "field": "throughput", - "name": "Throughput", + "name": "Request rate", "render": [Function], "sortable": true, "truncateText": true, @@ -462,7 +462,7 @@ exports[`Services table component renders jaeger services table 1`] = ` Object { "align": "right", "field": "average_latency", - "name": "Average latency (ms)", + "name": "Average duration (ms)", "render": [Function], "sortable": true, }, @@ -476,7 +476,7 @@ exports[`Services table component renders jaeger services table 1`] = ` Object { "align": "right", "field": "throughput", - "name": "Throughput", + "name": "Request rate", "render": [Function], "sortable": true, "truncateText": true, @@ -573,7 +573,7 @@ exports[`Services table component renders jaeger services table 1`] = ` "isSortAscending": undefined, "isSorted": false, "key": "_data_s_average_latency_1", - "name": "Average latency (ms)", + "name": "Average duration (ms)", "onSort": [Function], }, Object { @@ -587,7 +587,7 @@ exports[`Services table component renders jaeger services table 1`] = ` "isSortAscending": undefined, "isSorted": false, "key": "_data_s_throughput_3", - "name": "Throughput", + "name": "Request rate", "onSort": [Function], }, Object { @@ -867,15 +867,15 @@ exports[`Services table component renders jaeger services table 1`] = ` values={ Object { "description": undefined, - "innerText": "Average latency (ms)", + "innerText": "Average duration (ms)", } } > - Average latency (ms) + Average duration (ms) @@ -983,15 +983,15 @@ exports[`Services table component renders jaeger services table 1`] = ` values={ Object { "description": undefined, - "innerText": "Throughput", + "innerText": "Request rate", } } > - Throughput + Request rate @@ -1123,7 +1123,7 @@ exports[`Services table component renders jaeger services table 1`] = ` key="_data_column_average_latency_0_1" mobileOptions={ Object { - "header": "Average latency (ms)", + "header": "Average duration (ms)", "render": undefined, } } @@ -1141,7 +1141,7 @@ exports[`Services table component renders jaeger services table 1`] = `
- Average latency (ms) + Average duration (ms)
- Throughput + Request rate
- Average latency (ms) + Average duration (ms) @@ -2446,15 +2446,15 @@ exports[`Services table component renders services table 1`] = ` values={ Object { "description": undefined, - "innerText": "Throughput", + "innerText": "Request rate", } } > - Throughput + Request rate @@ -2703,7 +2703,7 @@ exports[`Services table component renders services table 1`] = ` key="_data_column_average_latency_0_1" mobileOptions={ Object { - "header": "Average latency (ms)", + "header": "Average duration (ms)", "render": undefined, } } @@ -2721,7 +2721,7 @@ exports[`Services table component renders services table 1`] = `
- Average latency (ms) + Average duration (ms)
- Throughput + Request rate
- Average latency (ms) + Average duration (ms) {fields.average_latency !== undefined ? fields.average_latency : '-'} @@ -170,7 +170,7 @@ export function ServiceView(props: ServiceViewProps) { - Throughput + Request rate {fields.throughput !== undefined ? ( diff --git a/public/components/trace_analytics/components/services/services.tsx b/public/components/trace_analytics/components/services/services.tsx index d1a6cbe2a..2029cdfb8 100644 --- a/public/components/trace_analytics/components/services/services.tsx +++ b/public/components/trace_analytics/components/services/services.tsx @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { EuiBreadcrumb, EuiTitle } from '@elastic/eui'; +import { EuiBreadcrumb } from '@elastic/eui'; import _ from 'lodash'; import React from 'react'; +import { Toast } from '@elastic/eui/src/components/toast/global_toast_list'; import { TraceAnalyticsComponentDeps } from '../../home'; import { DataSourcePicker } from '../dashboard/mode_picker'; import { ServicesContent } from './services_content'; @@ -15,14 +16,12 @@ export interface ServicesProps extends TraceAnalyticsComponentDeps { nameColumnAction: any; traceColumnAction: any; page: 'services' | 'app'; + toasts: Toast[]; } export function Services(props: ServicesProps) { return ( <> - -

Services

-
diff --git a/public/components/trace_analytics/components/services/services_content.tsx b/public/components/trace_analytics/components/services/services_content.tsx index 417c9420e..0552c567e 100644 --- a/public/components/trace_analytics/components/services/services_content.tsx +++ b/public/components/trace_analytics/components/services/services_content.tsx @@ -4,12 +4,13 @@ */ /* eslint-disable react-hooks/exhaustive-deps */ -import { EuiSpacer } from '@elastic/eui'; +import { EuiAccordion, EuiPanel, EuiSpacer } from '@elastic/eui'; import _ from 'lodash'; import React, { useEffect, useState } from 'react'; import { handleServiceMapRequest, handleServicesRequest, + handleTraceGroupsRequest, } from '../../requests/services_request_handler'; import { FilterType } from '../common/filters/filters'; import { getValidFilterFields } from '../common/filters/filter_helpers'; @@ -18,6 +19,8 @@ import { ServiceMap, ServiceObject } from '../common/plots/service_map'; import { SearchBar } from '../common/search_bar'; import { ServicesProps } from './services'; import { ServicesTable } from './services_table'; +import { OptionType } from '../../../../../common/types/application_analytics'; +import { DashboardContent } from '../dashboard/dashboard_content'; export function ServicesContent(props: ServicesProps) { const { @@ -42,6 +45,8 @@ export function ServicesContent(props: ServicesProps) { jaegerIndicesExist, } = props; const [tableItems, setTableItems] = useState([]); + + const [trigger, setTrigger] = useState<'open' | 'closed'>('closed'); const [serviceMap, setServiceMap] = useState({}); const [serviceMapIdSelected, setServiceMapIdSelected] = useState< 'latency' | 'error_rate' | 'throughput' @@ -50,9 +55,15 @@ export function ServicesContent(props: ServicesProps) { const [loading, setLoading] = useState(false); const [filteredService, setFilteredService] = useState(''); + const onToggle = (isOpen) => { + const newState = isOpen ? 'open' : 'closed'; + setTrigger(newState); + }; + useEffect(() => { chrome.setBreadcrumbs([parentBreadcrumb, ...childBreadcrumbs]); const validFilters = getValidFilterFields(mode, 'services'); + setFilters([ ...filters.map((filter) => ({ ...filter, @@ -60,7 +71,7 @@ export function ServicesContent(props: ServicesProps) { })), ]); setRedirect(false); - }, []); + }, [mode]); useEffect(() => { let newFilteredService = ''; @@ -123,6 +134,10 @@ export function ServicesContent(props: ServicesProps) { setFilters(newFilters); }; + const dashboardContent = () => { + return ; + }; + return ( <> )} + + + + + {trigger === 'open' && dashboardContent()} + + ); } diff --git a/public/components/trace_analytics/components/services/services_table.tsx b/public/components/trace_analytics/components/services/services_table.tsx index 4ffe85107..fb405dfe3 100644 --- a/public/components/trace_analytics/components/services/services_table.tsx +++ b/public/components/trace_analytics/components/services/services_table.tsx @@ -76,7 +76,7 @@ export function ServicesTable(props: ServicesTableProps) { }, { field: 'average_latency', - name: 'Average latency (ms)', + name: 'Average duration (ms)', align: 'right', sortable: true, render: (item: any) => (item === 0 || item ? _.round(item, 2) : '-'), @@ -91,7 +91,7 @@ export function ServicesTable(props: ServicesTableProps) { }, { field: 'throughput', - name: 'Throughput', + name: 'Request rate', align: 'right', sortable: true, truncateText: true, diff --git a/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap b/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap index b9a28eade..3e07d460d 100644 --- a/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap +++ b/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap @@ -197,20 +197,6 @@ exports[`Traces component renders empty traces page 1`] = ` startTime="now-5m" traceIdColumnAction={[Function]} > - -

- Traces -

-
- -

- Traces -

-
- -

- Traces -

-
- Latency (ms) + Duration (ms) @@ -2806,7 +2806,7 @@ exports[`Traces table component renders traces table 1`] = ` key="_data_column_latency_0_2" mobileOptions={ Object { - "header": "Latency (ms)", + "header": "Duration (ms)", "render": undefined, } } @@ -2825,7 +2825,7 @@ exports[`Traces table component renders traces table 1`] = `
- Latency (ms) + Duration (ms)
- -

Traces

-
diff --git a/public/components/trace_analytics/components/traces/traces_table.tsx b/public/components/trace_analytics/components/traces/traces_table.tsx index 03fa6c68a..cd6699961 100644 --- a/public/components/trace_analytics/components/traces/traces_table.tsx +++ b/public/components/trace_analytics/components/traces/traces_table.tsx @@ -110,7 +110,7 @@ export function TracesTable(props: TracesTableProps) { }, { field: 'latency', - name: 'Latency (ms)', + name: 'Duration (ms)', align: 'right', sortable: true, truncateText: true, diff --git a/public/components/trace_analytics/home.tsx b/public/components/trace_analytics/home.tsx index 7d4569949..3fa8dfc11 100644 --- a/public/components/trace_analytics/home.tsx +++ b/public/components/trace_analytics/home.tsx @@ -101,17 +101,6 @@ export const Home = (props: HomeProps) => { } }, [jaegerIndicesExist, dataPrepperIndicesExist]); - const dashboardBreadcrumbs = [ - { - text: 'Trace analytics', - href: '#/', - }, - { - text: 'Dashboard', - href: '#/', - }, - ]; - const serviceBreadcrumbs = [ { text: 'Trace analytics', @@ -175,21 +164,6 @@ export const Home = (props: HomeProps) => { toastLifeTimeMs={6000} /> - ( - - - - )} - /> { /> ( { childBreadcrumbs={serviceBreadcrumbs} nameColumnAction={nameColumnAction} traceColumnAction={traceColumnAction} + toasts={toasts} {...commonProps} /> diff --git a/public/components/trace_analytics/requests/dashboard_request_handler.ts b/public/components/trace_analytics/requests/dashboard_request_handler.ts index d25ad03fd..d9316bca0 100644 --- a/public/components/trace_analytics/requests/dashboard_request_handler.ts +++ b/public/components/trace_analytics/requests/dashboard_request_handler.ts @@ -28,6 +28,7 @@ export const handleDashboardRequest = async ( items, setItems, mode, + setShowTimeoutToast, setPercentileMap? ) => { // latency_variance should only be affected by timefilter @@ -49,7 +50,7 @@ export const handleDashboardRequest = async ( .catch((error) => console.error(error)); if (setPercentileMap) setPercentileMap(latencyVariances); - const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getLatencyTrendQuery(), mode) + const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getLatencyTrendQuery(), mode, setShowTimeoutToast) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -104,7 +105,7 @@ export const handleDashboardRequest = async ( }) .catch((error) => console.error(error)); - await handleDslRequest(http, DSL, getDashboardQuery(), mode) + await handleDslRequest(http, DSL, getDashboardQuery(), mode, setShowTimeoutToast) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -137,7 +138,7 @@ export const handleJaegerDashboardRequest = async ( setShowTimeoutToast, setPercentileMap? ) => { - const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerLatencyTrendQuery(), mode, true, setShowTimeoutToast) + const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerLatencyTrendQuery(), mode, setShowTimeoutToast) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -194,7 +195,7 @@ export const handleJaegerDashboardRequest = async ( console.error(error); }); - await handleDslRequest(http, DSL, getJaegerDashboardQuery(), mode, true, setShowTimeoutToast) + await handleDslRequest(http, DSL, getJaegerDashboardQuery(), mode, setShowTimeoutToast) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -248,7 +249,7 @@ export const handleJaegerErrorDashboardRequest = async ( setShowTimeoutToast, setPercentileMap? ) => { - const errorTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerErrorTrendQuery(), mode, true, setShowTimeoutToast) + const errorTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerErrorTrendQuery(), mode, setShowTimeoutToast) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -303,7 +304,7 @@ export const handleJaegerErrorDashboardRequest = async ( }) .catch((error) => console.error(error)); - await handleDslRequest(http, DSL, getJaegerErrorDashboardQuery(), mode, true, setShowTimeoutToast) + await handleDslRequest(http, DSL, getJaegerErrorDashboardQuery(), mode, setShowTimeoutToast) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { diff --git a/public/components/trace_analytics/requests/request_handler.ts b/public/components/trace_analytics/requests/request_handler.ts index 2d3191a02..bb687183d 100644 --- a/public/components/trace_analytics/requests/request_handler.ts +++ b/public/components/trace_analytics/requests/request_handler.ts @@ -18,7 +18,6 @@ export async function handleDslRequest( DSL: any, bodyQuery: any, mode: TraceAnalyticsMode, - timeout?: boolean, setShowTimeoutToast?: () => void ) { if (DSL?.query) { @@ -33,8 +32,8 @@ export async function handleDslRequest( if (!bodyQuery.index) { body = { ...bodyQuery, index: mode === 'jaeger' ? JAEGER_INDEX_NAME : DATA_PREPPER_INDEX_NAME }; } - if (timeout) { - const id = setTimeout(() => setShowTimeoutToast!(), 30000); + if (setShowTimeoutToast) { + const id = setTimeout(() => setShowTimeoutToast(), 25000); // 25 seconds try { return await http.post(TRACE_ANALYTICS_DSL_ROUTE, { @@ -45,14 +44,15 @@ export async function handleDslRequest( } finally { clearTimeout(id); } - } + } else { - try { - return await http.post(TRACE_ANALYTICS_DSL_ROUTE, { - body: JSON.stringify(body), - }); - } catch (error_1) { - console.error(error_1); + try { + return await http.post(TRACE_ANALYTICS_DSL_ROUTE, { + body: JSON.stringify(body), + }); + } catch (error_1) { + console.error(error_1); + } } } diff --git a/public/components/trace_analytics/trace_side_nav.tsx b/public/components/trace_analytics/trace_side_nav.tsx index 77cb44596..de1a346d4 100644 --- a/public/components/trace_analytics/trace_side_nav.tsx +++ b/public/components/trace_analytics/trace_side_nav.tsx @@ -4,7 +4,6 @@ */ import { - EuiButton, EuiFlexGroup, EuiFlexItem, EuiPage, @@ -12,22 +11,17 @@ import { EuiPageSideBar, EuiSideNav, EuiSideNavItemType, - EuiSwitch, } from '@elastic/eui'; import React from 'react'; export function TraceSideBar(props: { children: React.ReactNode }) { function setIsSelected(items: Array>, hash: string): boolean { - if (hash === '#/') { - items[0].isSelected = true; - return true; - } if (hash === '#/traces') { - items[0].items[0].isSelected = true; + items[0].items[1].isSelected = true; return true; } - if (hash === '#/services') { - items[0].items[1].isSelected = true; + if (hash === '#/services' || hash === '#/') { + items[0].items[0].isSelected = true; return true; } } @@ -39,14 +33,14 @@ export function TraceSideBar(props: { children: React.ReactNode }) { href: '#/', items: [ { - name: 'Traces', + name: 'Services', id: 1.1, - href: '#/traces', + href: '#/services', }, { - name: 'Services', + name: 'Traces', id: 1.2, - href: '#/services', + href: '#/traces', }, ], }, diff --git a/test/constants.ts b/test/constants.ts index fde1baea6..6bacecdae 100644 --- a/test/constants.ts +++ b/test/constants.ts @@ -205,7 +205,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 1, label: 'order', size: 15, - title: 'order\n\nAverage latency: 90.1ms\nError rate: 4.17%\nThroughput: 48', + title: 'order\n\nAverage duration: 90.1ms\nError rate: 4.17%\nRequest rate: 48', borderWidth: 0, color: 'rgba(158, 134, 192, 1)', font: { @@ -216,7 +216,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 2, label: 'analytics-service', size: 15, - title: 'analytics-service\n\nAverage latency: 12.99ms\nError rate: 0%\nThroughput: 37', + title: 'analytics-service\n\nAverage duration: 12.99ms\nError rate: 0%\nRequest rate: 37', borderWidth: 0, color: 'rgba(210, 202, 224, 1)', font: { @@ -227,7 +227,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 3, label: 'database', size: 15, - title: 'database\n\nAverage latency: 49.54ms\nError rate: 3.77%\nThroughput: 53', + title: 'database\n\nAverage duration: 49.54ms\nError rate: 3.77%\nRequest rate: 53', borderWidth: 0, color: 'rgba(187, 171, 212, 1)', font: { @@ -238,7 +238,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 4, label: 'frontend-client', size: 15, - title: 'frontend-client\n\nAverage latency: 207.71ms\nError rate: 7.41%\nThroughput: 27', + title: 'frontend-client\n\nAverage duration: 207.71ms\nError rate: 7.41%\nRequest rate: 27', borderWidth: 0, color: 'rgba(78, 42, 122, 1)', font: { @@ -249,7 +249,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 5, label: 'inventory', size: 15, - title: 'inventory\n\nAverage latency: 183.52ms\nError rate: 3.23%\nThroughput: 31', + title: 'inventory\n\nAverage duration: 183.52ms\nError rate: 3.23%\nRequest rate: 31', borderWidth: 0, color: 'rgba(95, 61, 138, 1)', font: { @@ -260,7 +260,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 6, label: 'authentication', size: 15, - title: 'authentication\n\nAverage latency: 139.09ms\nError rate: 8.33%\nThroughput: 12', + title: 'authentication\n\nAverage duration: 139.09ms\nError rate: 8.33%\nRequest rate: 12', borderWidth: 0, color: 'rgba(125, 95, 166, 1)', font: { @@ -271,7 +271,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 7, label: 'payment', size: 15, - title: 'payment\n\nAverage latency: 134.36ms\nError rate: 9.09%\nThroughput: 11', + title: 'payment\n\nAverage duration: 134.36ms\nError rate: 9.09%\nRequest rate: 11', borderWidth: 0, color: 'rgba(129, 99, 169, 1)', font: { @@ -282,7 +282,7 @@ export const TEST_SERVICE_MAP_GRAPH = { id: 8, label: 'recommendation', size: 15, - title: 'recommendation\n\nAverage latency: 176.97ms\nError rate: 6.25%\nThroughput: 16', + title: 'recommendation\n\nAverage duration: 176.97ms\nError rate: 6.25%\nRequest rate: 16', borderWidth: 0, color: 'rgba(100, 66, 143, 1)', font: {