diff options
Diffstat (limited to 'app/assets/javascripts/observability')
4 files changed, 281 insertions, 1 deletions
diff --git a/app/assets/javascripts/observability/client.js b/app/assets/javascripts/observability/client.js new file mode 100644 index 00000000000..6e39d2b450b --- /dev/null +++ b/app/assets/javascripts/observability/client.js @@ -0,0 +1,41 @@ +// import axios from '~/lib/utils/axios_utils'; +import * as mockData from './mock_traces.json'; + +function enableTraces(provisioningUrl) { + console.log(`Enabling tracing - ${provisioningUrl}`); // eslint-disable-line no-console + + return new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 500); + }); +} + +function isTracingEnabled(provisioningUrl) { + console.log(`Checking status - ${provisioningUrl}`); // eslint-disable-line no-console + + return new Promise((resolve) => { + setTimeout(() => { + resolve(false); + }, 1000); + }); +} + +function fetchTraces(tracingUrl) { + console.log(`Fetching traces from ${tracingUrl}`); // eslint-disable-line no-console + + // axios.get(`${this.endpoint}/v1/jaeger/22/api/services`, { credentials: 'include' }); + return new Promise((resolve) => { + setTimeout(() => { + resolve(mockData.data); + }, 2000); + }); +} + +export function buildClient({ provisioningUrl, tracingUrl }) { + return { + enableTraces: () => enableTraces(provisioningUrl), + isTracingEnabled: () => isTracingEnabled(provisioningUrl), + fetchTraces: () => fetchTraces(tracingUrl), + }; +} diff --git a/app/assets/javascripts/observability/components/observability_container.vue b/app/assets/javascripts/observability/components/observability_container.vue new file mode 100644 index 00000000000..7fb352cc171 --- /dev/null +++ b/app/assets/javascripts/observability/components/observability_container.vue @@ -0,0 +1,86 @@ +<script> +import { buildClient } from '../client'; +import ObservabilitySkeleton from './skeleton/index.vue'; + +export default { + components: { + ObservabilitySkeleton, + }, + props: { + oauthUrl: { + type: String, + required: true, + }, + tracingUrl: { + type: String, + required: true, + }, + provisioningUrl: { + type: String, + required: true, + }, + }, + data() { + return { + observabilityClient: null, + authCompleted: false, + }; + }, + mounted() { + window.addEventListener('message', this.messageHandler); + + // TODO Remove once backend work done - just for testing + // setTimeout(() => { + // this.messageHandler({ + // data: { type: 'AUTH_COMPLETION', status: 'success' }, + // origin: new URL(this.oauthUrl).origin, + // }); + // }, 2000); + }, + destroyed() { + window.removeEventListener('message', this.messageHandler); + }, + methods: { + messageHandler(e) { + const isExpectedOrigin = e.origin === new URL(this.oauthUrl).origin; + if (!isExpectedOrigin) return; + + const { data } = e; + + if (data.type === 'AUTH_COMPLETION') { + if (this.authCompleted) return; + + const { status, message, statusCode } = data; + if (status === 'success') { + this.observabilityClient = buildClient({ + provisioningUrl: this.provisioningUrl, + tracingUrl: this.tracingUrl, + }); + this.$refs.observabilitySkeleton?.onContentLoaded(); + } else if (status === 'error') { + // eslint-disable-next-line @gitlab/require-i18n-strings,no-console + console.error('GOB auth failed with error:', message, statusCode); + this.$refs.observabilitySkeleton?.onError(); + } + this.authCompleted = true; + } + }, + }, +}; +</script> + +<template> + <div> + <iframe + v-if="!authCompleted" + sandbox="allow-same-origin allow-forms allow-scripts" + hidden + :src="oauthUrl" + data-testid="observability-oauth-iframe" + ></iframe> + + <observability-skeleton ref="observabilitySkeleton"> + <slot v-if="observabilityClient" :observability-client="observabilityClient"></slot> + </observability-skeleton> + </div> +</template> diff --git a/app/assets/javascripts/observability/components/skeleton/index.vue b/app/assets/javascripts/observability/components/skeleton/index.vue index d91f2874943..75e5ca81939 100644 --- a/app/assets/javascripts/observability/components/skeleton/index.vue +++ b/app/assets/javascripts/observability/components/skeleton/index.vue @@ -61,6 +61,12 @@ export default { this.hideSkeleton(); }, + onError() { + clearTimeout(this.errorTimeout); + clearTimeout(this.loadingTimeout); + + this.showError(); + }, setLoadingTimeout() { this.loadingTimeout = setTimeout(() => { /** @@ -130,7 +136,7 @@ export default { <transition> <div v-show="state === $options.SKELETON_STATE.HIDDEN" - data-testid="observability-wrapper" + data-testid="content-wrapper" class="gl-flex-grow-1 gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch" > <slot></slot> diff --git a/app/assets/javascripts/observability/mock_traces.json b/app/assets/javascripts/observability/mock_traces.json new file mode 100644 index 00000000000..7b472081a24 --- /dev/null +++ b/app/assets/javascripts/observability/mock_traces.json @@ -0,0 +1,147 @@ +{ + "data": [ + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 100, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + }, + { + "traceID": "668ec7d464968a87", + "date": "Mon, 03 Jul 2023 14:35:37 GMT", + "service": "HealthCheck", + "operation": "/grpc.health.v1.Health/Check", + "duration": 343, + "method": "GET", + "status": 200, + "spans": [ + + ], + "warnings": null + } + ] +} |