Skip to content

Add details drawer panel to Logs List UI

Daniele Rossetti requested to merge drosse/logs-details-drawer into master

What does this MR do and why?

  • Add Logs details drawer to logs list
    • Add LogsDrawer component, used to show log entry details
    • On selecting a log entry from the list, the drawer should open
  • Adjust Logs list styling according to latest spec

Close Add details drawer panel to Logs List UI (gitlab-org/opstrace/opstrace#2648 - 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 image

How to set up and validate locally

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

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

diff --git a/app/assets/javascripts/observability/client.js b/app/assets/javascripts/observability/client.js
index 056eeec85be7..ceaa8f42668a 100644
--- a/app/assets/javascripts/observability/client.js
+++ b/app/assets/javascripts/observability/client.js
@@ -1,3 +1,4 @@
+/* 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';
@@ -9,14 +10,18 @@ function reportErrorAndThrow(e) {
   Sentry.captureException(e);
   throw e;
 }
+
+function mockReturnDataWithDelay(data) {
+  return new Promise((resolve) => {
+    setTimeout(() => resolve(data), 1000);
+  });
+}
+
 // 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);
   }
@@ -25,11 +30,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) {
@@ -448,13 +454,153 @@ async function fetchMetricSearchMetadata(searchMetadataUrl, name, type) {
 
 export async function fetchLogs(logsSearchUrl) {
   try {
-    const { data } = await axios.get(logsSearchUrl, {
-      withCredentials: true,
-    });
-    if (!Array.isArray(data.results)) {
-      throw new Error('logs are missing/invalid in the response'); // eslint-disable-line @gitlab/require-i18n-strings
-    }
-    return data.results;
+    return mockReturnDataWithDelay(
+      [
+        {
+          timestamp: '2024-02-19T16:10:15.4433398Z',
+          trace_id: ']?4ft^T\u0011\ufffd\u0013\ufffd6\ufffdbj\ufffd',
+          span_id: "'\u0013\ufffd\ufffd_\ufffd\ufffd\ufffd",
+          trace_flags: 1,
+          severity_text: 'Information',
+          severity_number: 1,
+          service_name: 'cartservice/test',
+          body:
+            'AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity} ',
+          resource_attributes: {
+            'container.id': 'ae165f3300bf7da7cc83b360e955683f31f959268241895747f23ad165014005',
+            'k8s.deployment.name': 'otel-demo-cartservice',
+            'k8s.namespace.name': 'otel-demo-app',
+            'k8s.node.name': 'opstrace-worker2',
+            'k8s.pod.ip': '192.168.62.215',
+            'k8s.pod.name': 'otel-demo-cartservice-6dcc867f5f-pcm68',
+            'k8s.pod.start_time': '2024-02-12T13:32:12Z',
+            'k8s.pod.uid': 'bb0991d5-d2f9-486d-aed6-fb431da28bcb',
+            'service.name': 'cartservice',
+            'service.namespace': 'opentelemetry-demo',
+            'telemetry.sdk.language': 'dotnet',
+            'telemetry.sdk.name': 'opentelemetry',
+            'telemetry.sdk.version': '1.6.0',
+          },
+          log_attributes: {
+            productId: 'LS4PSXUNUM',
+            quantity: '5',
+            userId: '5e22f0f6-cf41-11ee-a97f-768346730ebf',
+          },
+        },
+        {
+          timestamp: '2024-02-19T16:10:15.4488072Z',
+          trace_id: ']?4ft^T\u0011\ufffd\u0013\ufffd6\ufffdbj\ufffd',
+          span_id: '\u0015_\ufffd z\ufffd\ufffd\ufffd',
+          trace_flags: 1,
+          severity_text: 'Information',
+          severity_number: 13,
+          service_name: 'cartservice/test',
+          body: 'GetCartAsync called with userId={userId}',
+          resource_attributes: {
+            'container.id': 'ae165f3300bf7da7cc83b360e955683f31f959268241895747f23ad165014005',
+            'k8s.deployment.name': 'otel-demo-cartservice',
+            'k8s.namespace.name': 'otel-demo-app',
+            'k8s.node.name': 'opstrace-worker2',
+            'k8s.pod.ip': '192.168.62.215',
+            'k8s.pod.name': 'otel-demo-cartservice-6dcc867f5f-pcm68',
+            'k8s.pod.start_time': '2024-02-12T13:32:12Z',
+            'k8s.pod.uid': 'bb0991d5-d2f9-486d-aed6-fb431da28bcb',
+            'service.name': 'cartservice',
+            'service.namespace': 'opentelemetry-demo',
+            'telemetry.sdk.language': 'dotnet',
+            'telemetry.sdk.name': 'opentelemetry',
+            'telemetry.sdk.version': '1.6.0',
+          },
+          log_attributes: { userId: '5e22f0f6-cf41-11ee-a97f-768346730ebf' },
+        },
+        {
+          timestamp: '2024-02-19T16:10:18.9380111Z',
+          trace_id: '\ufffd\u000cbi\ufffd\u001c\ufffd\ufffd,4f\ufffd!\ufffd\ufffd\ufffd',
+          span_id: '\ufffdv\ufffd(\ufffdyD\ufffd',
+          trace_flags: 1,
+          severity_text: 'Information',
+          severity_number: 17,
+          service_name: 'cartservice/test',
+          body: 'GetCartAsync called with userId={userId}',
+          resource_attributes: {
+            'container.id': 'ae165f3300bf7da7cc83b360e955683f31f959268241895747f23ad165014005',
+            'k8s.deployment.name': 'otel-demo-cartservice',
+            'k8s.namespace.name': 'otel-demo-app',
+            'k8s.node.name': 'opstrace-worker2',
+            'k8s.pod.ip': '192.168.62.215',
+            'k8s.pod.name': 'otel-demo-cartservice-6dcc867f5f-pcm68',
+            'k8s.pod.start_time': '2024-02-12T13:32:12Z',
+            'k8s.pod.uid': 'bb0991d5-d2f9-486d-aed6-fb431da28bcb',
+            'service.name': 'cartservice',
+            'service.namespace': 'opentelemetry-demo',
+            'telemetry.sdk.language': 'dotnet',
+            'telemetry.sdk.name': 'opentelemetry',
+            'telemetry.sdk.version': '1.6.0',
+          },
+          log_attributes: { userId: '' },
+        },
+        {
+          timestamp: '2024-02-19T16:10:19.7969402Z',
+          trace_id: '\ufffdq\ufffd7\ufffd\ufffd\ufffd\ufffd ]2M~7{\ufffd',
+          span_id: '\u0018H\ufffd\ufffd\ufffd.L\ufffd',
+          trace_flags: 1,
+          severity_text: 'Information',
+          severity_number: 21,
+          service_name: 'cartservice/test',
+          body:
+            'AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}',
+          resource_attributes: {
+            'container.id': 'ae165f3300bf7da7cc83b360e955683f31f959268241895747f23ad165014005',
+            'k8s.deployment.name': 'otel-demo-cartservice',
+            'k8s.namespace.name': 'otel-demo-app',
+            'k8s.node.name': 'opstrace-worker2',
+            'k8s.pod.ip': '192.168.62.215',
+            'k8s.pod.name': 'otel-demo-cartservice-6dcc867f5f-pcm68',
+            'k8s.pod.start_time': '2024-02-12T13:32:12Z',
+            'k8s.pod.uid': 'bb0991d5-d2f9-486d-aed6-fb431da28bcb',
+            'service.name': 'cartservice',
+            'service.namespace': 'opentelemetry-demo',
+            'telemetry.sdk.language': 'dotnet',
+            'telemetry.sdk.name': 'opentelemetry',
+            'telemetry.sdk.version': '1.6.0',
+          },
+          log_attributes: {
+            productId: '66VCHSJNUP',
+            quantity: '1',
+            userId: '60bc5708-cf41-11ee-a97f-768346730ebf',
+          },
+        },
+        {
+          timestamp: '2024-02-19T16:10:19.8003226Z',
+          trace_id: '\ufffdq\ufffd7\ufffd\ufffd\ufffd\ufffd ]2M~7{\ufffd',
+          span_id: 'G\u0006\ufffd`B\r\ufffd\ufffd',
+          trace_flags: 1,
+          severity_text: 'Information',
+          severity_number: 9,
+          service_name: 'cartservice/test',
+          body: 'GetCartAsync called with userId={userId}',
+          resource_attributes: {
+            'container.id': 'ae165f3300bf7da7cc83b360e955683f31f959268241895747f23ad165014005',
+            'k8s.deployment.name': 'otel-demo-cartservice',
+            'k8s.namespace.name': 'otel-demo-app',
+            'k8s.node.name': 'opstrace-worker2',
+            'k8s.pod.ip': '192.168.62.215',
+            'k8s.pod.name': 'otel-demo-cartservice-6dcc867f5f-pcm68',
+            'k8s.pod.start_time': '2024-02-12T13:32:12Z',
+            'k8s.pod.uid': 'bb0991d5-d2f9-486d-aed6-fb431da28bcb',
+            'service.name': 'cartservice',
+            'service.namespace': 'opentelemetry-demo',
+            'telemetry.sdk.language': 'dotnet',
+            'telemetry.sdk.name': 'opentelemetry',
+            'telemetry.sdk.version': '1.6.0',
+          },
+          log_attributes: { userId: '60bc5708-cf41-11ee-a97f-768346730ebf' },
+        },
+      ].map((l) => ({
+        ...l,
+        fingerprint: crypto.randomUUID(),
+      })),
+    );
   } 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 b89c2624f81c..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.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

Loading