Skip to content

Add support for handling traces with missing or multiple roots

Daniele Rossetti requested to merge drosse/tracing-multiple-missing-roots into master

What does this MR do and why?

Add support for handling traces with missing or multiple roots:

  • Improve span tree building logic to handle missing or multiple roots
    • Rename mapTraceToTreeRoot to mapTraceToSpanTrees and changed returned type to accommodate for multiple roots
    • If a root node is missing, its children nodes are considered roots, and the trace is marked as incomplete
    • If multiple nodes are roots, the trace is marked as incomplete
  • Moved tree building ( mapTraceToSpanTrees ) from TracingChart to TracingDetails, so that the tree data can be shared across components
  • Render a TracingSpanChart component for each root

Closes Trace details UI: UI assumes there's always one... (gitlab-org/opstrace/opstrace#2516 - closed)

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

image

How to set up and validate locally

  • Prerequisites: be logged in and running GDK with Ultimate license
  • Enable :observability_tracing feature flag

Apply patch to load mocks ( copy the patch content below and run in your terminal: pbpaste | git apply )

diff --git a/app/assets/javascripts/observability/client.js b/app/assets/javascripts/observability/client.js
index 70b80a766532..e6d8bfb03d9c 100644
--- a/app/assets/javascripts/observability/client.js
+++ b/app/assets/javascripts/observability/client.js
@@ -1,9 +1,217 @@
+/* eslint-disable @gitlab/require-i18n-strings */
 import { isValidDate } from '~/lib/utils/datetime_utility';
 import * as Sentry from '~/sentry/sentry_browser_wrapper';
 import axios from '~/lib/utils/axios_utils';
 import { logError } from '~/lib/logger';
 import { DEFAULT_SORTING_OPTION, SORTING_OPTIONS, CUSTOM_DATE_RANGE_OPTION } from './constants';
 
+const MOCK_TRACES = {
+  project_id: 51792562,
+  traces: [
+    {
+      timestamp: '2023-11-10T20:39:58.981780253Z',
+      timestamp_nano: 1699648798981780253,
+      trace_id: '2b1f08cd-9d10-4ac5-90c3-47fa84ab1c80',
+      service_name: 'featureflagservice',
+      operation: '/',
+      status_code: 'STATUS_CODE_UNSET',
+      duration_nano: 931979,
+      spans: [
+        {
+          timestamp: '2023-11-10T20:39:58.981780253Z',
+          span_id: 'D28D2485217F1874',
+          trace_id: '2b1f08cd-9d10-4ac5-90c3-47fa84ab1c80',
+          service_name: 'featureflagservice',
+          operation: '/',
+          duration_nano: 931979,
+          parent_span_id: '',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+        {
+          timestamp: '2023-11-10T20:39:58.981914178Z',
+          span_id: 'CE64EF2386D5B768',
+          trace_id: '2b1f08cd-9d10-4ac5-90c3-47fa84ab1c80',
+          service_name: 'featureflagservice',
+          operation: 'featureflagservice.repo.query:featureflags',
+          duration_nano: 516542,
+          parent_span_id: 'D28D2485217F1874',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+      ],
+      total_spans: 2,
+      totalSpans: 2,
+    },
+    {
+      timestamp: '2023-11-10T20:39:28.655321683Z',
+      timestamp_nano: 1699648768655321683,
+      trace_id: '68a8cc4d-1403-4561-8721-e42ac8f0ec1b',
+      service_name: 'featureflagservice',
+      operation: '/',
+      status_code: 'STATUS_CODE_UNSET',
+      duration_nano: 806467,
+      spans: [
+        {
+          timestamp: '2023-11-10T20:39:28.655321683Z',
+          span_id: '4AA0BAF116CD904D',
+          trace_id: '68a8cc4d-1403-4561-8721-e42ac8f0ec1b',
+          service_name: 'featureflagservice',
+          operation: '/',
+          duration_nano: 806467,
+          parent_span_id: '',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+        {
+          timestamp: '2023-11-10T20:39:28.655458107Z',
+          span_id: '8716FEC7EF4E8BD9',
+          trace_id: '68a8cc4d-1403-4561-8721-e42ac8f0ec1b',
+          service_name: 'featureflagservice',
+          operation: 'featureflagservice.repo.query:featureflags',
+          duration_nano: 440323,
+          parent_span_id: '4AA0BAF116CD904D',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+      ],
+      total_spans: 2,
+      totalSpans: 2,
+    },
+    {
+      timestamp: '2023-11-10T20:38:58.326464308Z',
+      timestamp_nano: 1699648738326464308,
+      trace_id: '2af9172b-a326-0462-4dac-e7030928f67a',
+      service_name: 'featureflagservice',
+      operation: '/',
+      status_code: 'STATUS_CODE_UNSET',
+      duration_nano: 1199391,
+      spans: [
+        {
+          timestamp: '2023-11-10T20:38:58.326464308Z',
+          span_id: 'C8701AF08593B86B',
+          trace_id: '2af9172b-a326-0462-4dac-e7030928f67a',
+          service_name: 'featureflagservice',
+          operation: '/',
+          duration_nano: 1199391,
+          parent_span_id: '',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+        {
+          timestamp: '2023-11-10T20:38:58.326669557Z',
+          span_id: '5A26A5CDAAFEAAE1',
+          trace_id: '2af9172b-a326-0462-4dac-e7030928f67a',
+          service_name: 'featureflagservice',
+          operation: 'featureflagservice.repo.query:featureflags',
+          duration_nano: 606424,
+          parent_span_id: 'C8701AF08593B86B',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+      ],
+      total_spans: 2,
+      totalSpans: 2,
+    },
+    {
+      timestamp: '2023-11-10T20:38:28.003531546Z',
+      timestamp_nano: 1699648708003531546,
+      trace_id: '8f6293ce-895e-8c23-8966-03b9b6b60625',
+      service_name: 'featureflagservice',
+      operation: '/',
+      status_code: 'STATUS_CODE_UNSET',
+      duration_nano: 830728,
+      spans: [
+        {
+          timestamp: '2023-11-10T20:38:28.003531546Z',
+          span_id: '1F03B387DE6C523B',
+          trace_id: '8f6293ce-895e-8c23-8966-03b9b6b60625',
+          service_name: 'featureflagservice',
+          operation: '/',
+          duration_nano: 830728,
+          parent_span_id: '',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+        {
+          timestamp: '2023-11-10T20:38:28.00366749Z',
+          span_id: 'DD8501683E1D3F89',
+          trace_id: '8f6293ce-895e-8c23-8966-03b9b6b60625',
+          service_name: 'featureflagservice',
+          operation: 'featureflagservice.repo.query:featureflags',
+          duration_nano: 427162,
+          parent_span_id: '1F03B387DE6C523B',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+      ],
+      total_spans: 2,
+      totalSpans: 2,
+    },
+    {
+      timestamp: '2023-11-10T20:37:57.682713952Z',
+      timestamp_nano: 1699648677682713952,
+      trace_id: 'd057c76c-1032-59e0-8a8d-d4cbca420107',
+      service_name: 'featureflagservice',
+      operation: '/',
+      status_code: 'STATUS_CODE_UNSET',
+      duration_nano: 850928,
+      spans: [
+        {
+          timestamp: '2023-11-10T20:37:57.682713952Z',
+          span_id: 'C57FA0DFAD04CCC1',
+          trace_id: 'd057c76c-1032-59e0-8a8d-d4cbca420107',
+          service_name: 'featureflagservice',
+          operation: '/',
+          duration_nano: 850928,
+          parent_span_id: '',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+        {
+          timestamp: '2023-11-10T20:37:57.682852917Z',
+          span_id: 'CFC23BEC4B935D8F',
+          trace_id: 'd057c76c-1032-59e0-8a8d-d4cbca420107',
+          service_name: 'featureflagservice',
+          operation: 'featureflagservice.repo.query:featureflags',
+          duration_nano: 467103,
+          parent_span_id: 'C57FA0DFAD04CCC1',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+      ],
+      total_spans: 2,
+      totalSpans: 2,
+    },
+    {
+      timestamp: '2023-11-10T20:37:27.360383093Z',
+      timestamp_nano: 1699648647360383093,
+      trace_id: 'a6abd9ca-2299-e964-d233-3b782c8f5679',
+      service_name: 'featureflagservice',
+      operation: '/',
+      status_code: 'STATUS_CODE_UNSET',
+      duration_nano: 851823,
+      spans: [
+        {
+          timestamp: '2023-11-10T20:37:27.360383093Z',
+          span_id: 'B39BEA97214DDC03',
+          trace_id: 'a6abd9ca-2299-e964-d233-3b782c8f5679',
+          service_name: 'featureflagservice',
+          operation: '/',
+          duration_nano: 851823,
+          parent_span_id: '',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+        {
+          timestamp: '2023-11-10T20:37:27.360521433Z',
+          span_id: '64C63AB1CC3D1640',
+          trace_id: 'a6abd9ca-2299-e964-d233-3b782c8f5679',
+          service_name: 'featureflagservice',
+          operation: 'featureflagservice.repo.query:featureflags',
+          duration_nano: 455900,
+          parent_span_id: 'B39BEA97214DDC03',
+          status_code: 'STATUS_CODE_UNSET',
+        },
+      ],
+      total_spans: 2,
+      totalSpans: 2,
+    },
+  ],
+  total_traces: 6,
+  next_page_token:
+    'eyJsYXN0X3NlZW5fdGltZXN0YW1wIjoiMjAyMy0xMS0xMCAxNjoyNzo0Ny4xMDQ0NzcwOTIiLCJzZWVuX3RyYWNlX2lkcyI6WyI2ZTI0NjFjZS04MWVmLTRkYWItN2ZmYS1hMTRlMDRiODhmNWUiXX0=',
+};
+
 function reportErrorAndThrow(e) {
   logError(e);
   Sentry.captureException(e);
@@ -15,15 +223,17 @@ function reportErrorAndThrow(e) {
  * Provisioning API
  *
  * ***** */
+function mockReturnDataWithDelay(data) {
+  return new Promise((resolve) => {
+    setTimeout(() => resolve(data), 500);
+  });
+}
 
 // Provisioning API spec: https://gitlab.com/gitlab-org/opstrace/opstrace/-/blob/main/provisioning-api/pkg/provisioningapi/routes.go#L59
 async function enableObservability(provisioningUrl) {
   try {
-    // Note: axios.put(url, undefined, {withCredentials: true}) does not send cookies properly, so need to use the API below for the correct behaviour
-    return await axios(provisioningUrl, {
-      method: 'put',
-      withCredentials: true,
-    });
+    console.log('[DEBUG] Enabling Observability');
+    return mockReturnDataWithDelay();
   } catch (e) {
     return reportErrorAndThrow(e);
   }
@@ -32,11 +242,12 @@ async function enableObservability(provisioningUrl) {
 // Provisioning API spec: https://gitlab.com/gitlab-org/opstrace/opstrace/-/blob/main/provisioning-api/pkg/provisioningapi/routes.go#L37
 async function isObservabilityEnabled(provisioningUrl) {
   try {
-    const { data } = await axios.get(provisioningUrl, { withCredentials: true });
+    console.log('[DEBUG] Checking Observability Enabled');
+    const data = { status: 'ready' };
     if (data && data.status) {
       // we currently ignore the 'status' payload and just check if the request was successful
       // We might improve this as part of https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2315
-      return true;
+      return mockReturnDataWithDelay(true);
     }
   } catch (e) {
     if (e.response.status === 404) {
@@ -142,19 +353,304 @@ function addDateRangeFilterToQueryParams(dateRangeFilter, params) {
  * ***** */
 
 async function fetchTrace(tracingUrl, traceId) {
-  try {
-    if (!traceId) {
-      throw new Error('traceId is required.');
-    }
-
-    const { data } = await axios.get(`${tracingUrl}/${traceId}`, {
-      withCredentials: true,
-    });
-
-    return data;
-  } catch (e) {
-    return reportErrorAndThrow(e);
-  }
+  console.log(`[DEBUG] Fetch trace ${traceId} from ${tracingUrl}`);
+  return mockReturnDataWithDelay({
+    timestamp: '2024-05-30T15:55:45.369410278Z',
+    timestamp_nano: 1717084545369410300,
+    trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+    service_name: 'gitlab-rails-staging',
+    operation: 'graphql.execute_multiplex',
+    status_code: 'STATUS_CODE_UNSET',
+    duration_nano: 22836949,
+    total_spans: 10,
+    spans: [
+      {
+        timestamp: '2024-05-30T15:55:45.369441858Z',
+        timestamp_nano: 1717084545369441800,
+        span_id: '7B6CAE754B51463A',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.analyze_query',
+        duration_nano: 2251740,
+        parent_span_id: '',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {},
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.369487208Z',
+        timestamp_nano: 1717084545369487000,
+        span_id: '8DE8254FFAE9D588',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.parse',
+        duration_nano: 149500,
+        parent_span_id: '7B6CAE754B51463A',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {},
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.369672518Z',
+        timestamp_nano: 1717084545369672400,
+        span_id: '38E1E2ABCE600F1D',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.validate',
+        duration_nano: 785460,
+        parent_span_id: '7B6CAE754B51463A',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {},
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.370623338Z',
+        timestamp_nano: 1717084545370623200,
+        span_id: '0366D7448DD98655',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.analyze_multiplex',
+        duration_nano: 1057720,
+        parent_span_id: '7B6CAE754B51463A',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {},
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.370902988Z',
+        timestamp_nano: 1717084545370903000,
+        span_id: '892161FB60FA4DAB',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.analyze_multiplex',
+        duration_nano: 596200,
+        parent_span_id: '0366D7448DD98655',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {},
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.371846398Z',
+        timestamp_nano: 1717084545371846400,
+        span_id: 'B1EF8A46CA5537FA',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.execute_query',
+        duration_nano: 15049119,
+        parent_span_id: '1B666AF79E289027',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {
+          'graphql.document':
+            'subscription ChatSubscription($userId: UserID!, $clientSubscriptionId: String!) { aiCompletionResponse(userId: $userId, aiAction: CHAT, clientSubscriptionId: $clientSubscriptionId) { id requestId content contentHtml errors role timestamp type chunkId extras { sources } } }',
+          'graphql.operation.name': 'ChatSubscription',
+          'graphql.operation.type': 'subscription',
+        },
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.372412078Z',
+        timestamp_nano: 1717084545372412200,
+        span_id: 'BF874E79EE3FB77A',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'gitlabhq_production',
+        duration_nano: 5184090,
+        parent_span_id: 'B1EF8A46CA5537FA',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_CLIENT',
+        scope_name: 'OpenTelemetry::Instrumentation::PG',
+        scope_version: '0.27.1',
+        span_attributes: {
+          'db.name': 'gitlabhq_production',
+          'db.statement': ';',
+          'db.system': 'postgresql',
+          'db.user': 'gitlab',
+          'net.peer.ip': '10.224.36.205',
+          'net.peer.name': '10.224.36.205',
+          'net.peer.port': '6433',
+          'net.transport': 'ip_tcp',
+        },
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.380326838Z',
+        timestamp_nano: 1717084545380327000,
+        span_id: 'B3B28B612D8F4F01',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'gitlabhq_production',
+        duration_nano: 5031140,
+        parent_span_id: 'B1EF8A46CA5537FA',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_CLIENT',
+        scope_name: 'OpenTelemetry::Instrumentation::PG',
+        scope_version: '0.27.1',
+        span_attributes: {
+          'db.name': 'gitlabhq_production',
+          'db.statement':
+            '? SELECT "users".* FROM find_users_by_id(?) AS users WHERE ("users"."id" IS NOT ?) LIMIT ?',
+          'db.system': 'postgresql',
+          'db.user': 'gitlab',
+          'net.peer.ip': '10.224.36.205',
+          'net.peer.name': '10.224.36.205',
+          'net.peer.port': '6433',
+          'net.transport': 'ip_tcp',
+        },
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+      {
+        timestamp: '2024-05-30T15:55:45.380326838Z',
+        timestamp_nano: 1717084545392207000,
+        span_id: 'AF5903AB2370C646',
+        trace_id: 'ce6f2e0e-9999-7aef-47e2-6930839268f9',
+        service_name: 'gitlab-rails-staging',
+        operation: 'graphql.execute_query_lazy',
+        duration_nano: 9580,
+        parent_span_id: '1B666AF79E289027',
+        status_code: 'STATUS_CODE_UNSET',
+        status_message: '',
+        trace_state: '',
+        span_kind: 'SPAN_KIND_INTERNAL',
+        scope_name: 'OpenTelemetry::Instrumentation::GraphQL',
+        scope_version: '0.28.0',
+        span_attributes: {},
+        resource_attributes: {
+          'process.command': '/srv/gitlab/vendor/bundle/ruby/3.1.0/bin/puma',
+          'process.pid': '1',
+          'process.runtime.description':
+            'ruby 3.1.5p253 (2024-04-023 revision 1945f8dc0e) [x86_64-linux]',
+          'process.runtime.name': 'ruby',
+          'process.runtime.version': '3.1.5',
+          'service.name': 'gitlab-rails-staging',
+          'telemetry.sdk.language': 'ruby',
+          'telemetry.sdk.name': 'opentelemetry',
+          'telemetry.sdk.version': '1.4.0',
+        },
+      },
+    ],
+  });
 }
 
 /**
@@ -278,16 +774,15 @@ async function fetchTraces(
     : DEFAULT_SORTING_OPTION;
   params.append('sort', sortOrder);
 
+  console.log(`[DEBUG] Fetching traces with params: ${params.toString()}`);
+
   try {
-    const { data } = await axios.get(tracingUrl, {
-      withCredentials: true,
-      params,
-      signal: abortController?.signal,
-    });
+    const data = MOCK_TRACES;
+
     if (!Array.isArray(data.traces)) {
       throw new Error('traces are missing/invalid in the response'); // eslint-disable-line @gitlab/require-i18n-strings
     }
-    return data;
+    return mockReturnDataWithDelay(data);
   } catch (e) {
     return reportErrorAndThrow(e);
   }
@@ -310,15 +805,17 @@ async function fetchTracesAnalytics(tracingAnalyticsUrl, { filters = {}, abortCo
 
 async function fetchServices(servicesUrl) {
   try {
-    const { data } = await axios.get(servicesUrl, {
-      withCredentials: true,
-    });
+    console.log(`[DEBUG] Fetching services from ${servicesUrl}`);
+    const uniqueServices = new Set(
+      MOCK_TRACES.traces.map((t) => t.spans.map((s) => s.service_name)).flat(),
+    );
+    const data = { services: Array.from(uniqueServices).map((s) => ({ name: s })) };
 
     if (!Array.isArray(data.services)) {
       throw new Error('failed to fetch services. invalid response'); // eslint-disable-line @gitlab/require-i18n-strings
     }
 
-    return data.services;
+    return mockReturnDataWithDelay(data.services);
   } catch (e) {
     return reportErrorAndThrow(e);
   }
@@ -333,15 +830,21 @@ async function fetchOperations(operationsUrl, serviceName) {
       throw new Error('fetchOperations() - operationsUrl must contain $SERVICE_NAME$');
     }
     const url = operationsUrl.replace('$SERVICE_NAME$', serviceName);
-    const { data } = await axios.get(url, {
-      withCredentials: true,
-    });
+
+    console.log('[DEBUG] fetching operations suggestions from', url); // eslint-disable-line @gitlab/require-i18n-strings
+    const uniqOps = new Set(
+      MOCK_TRACES.traces
+        .map((t) => t.spans.filter((s) => s.service_name === serviceName))
+        .flat()
+        .map((s) => s.operation),
+    );
+    const data = { operations: Array.from(uniqOps).map((s) => ({ name: s })) };
 
     if (!Array.isArray(data.operations)) {
       throw new Error('failed to fetch operations. invalid response'); // eslint-disable-line @gitlab/require-i18n-strings
     }
 
-    return data.operations;
+    return mockReturnDataWithDelay(data.operations);
   } catch (e) {
     return reportErrorAndThrow(e);
   }
diff --git a/app/assets/javascripts/observability/components/observability_container.vue b/app/assets/javascripts/observability/components/observability_container.vue
index d0902505ca73..f6cbf7ee771f 100644
--- a/app/assets/javascripts/observability/components/observability_container.vue
+++ b/app/assets/javascripts/observability/components/observability_container.vue
@@ -27,12 +27,12 @@ export default {
 
     // TODO: Improve local GDK dev experience with tracing https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2308
     // Uncomment the lines below to to test this locally
-    // setTimeout(() => {
-    //   this.messageHandler({
-    //     data: { type: 'AUTH_COMPLETION', status: 'success' },
-    //     origin: new URL(this.apiConfig.oauthUrl).origin,
-    //   });
-    // }, 2000);
+    setTimeout(() => {
+      this.messageHandler({
+        data: { type: 'AUTH_COMPLETION', status: 'success' },
+        origin: new URL(this.apiConfig.oauthUrl).origin,
+      });
+    }, 2000);
   },
   destroyed() {
     window.removeEventListener('message', this.messageHandler);
Edited by Daniele Rossetti

Merge request reports