diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 3b326a11..52c0d923 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -51,10 +51,8 @@ jobs:
PROOFMARKET_TOOLCHAIN_REPO = "${{ secrets.PROOFMARKET_TOOLCHAIN_REPO }}"
CIRCUIT_DEVELOPER_GUIDE_URL = "${{ secrets.CIRCUIT_DEVELOPER_GUIDE_URL }}"
API_RESPONSE_WAIT_TIMEOUT = "${{ secrets.API_RESPONSE_WAIT_TIMEOUT }}"
- DATADOG_APPLICATION_ID = "${{ secrets.DATADOG_APPLICATION_ID }}"
- DATADOG_CLIENT_TOKEN = "${{ secrets.DATADOG_CLIENT_TOKEN }}"
- DATADOG_SITE = "${{ secrets.DATADOG_SITE }}"
- DATADOG_SERVICE_NAME = "${{ secrets.DATADOG_SERVICE_NAME }}"
+ OTEL_TRACE_EXPORTER_URL = "${{ secrets.OTEL_TRACE_EXPORTER_URL }}"
+ OTEL_SERVICE_NAME = "${{ secrets.OTEL_SERVICE_NAME }}"
'
echo "$config" > runtime-config.toml
echo runtime-config.toml
diff --git a/package-lock.json b/package-lock.json
index 071e3eba..31fdd6ee 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,10 +8,11 @@
"name": "proof-market.frontend",
"version": "0.1.9",
"dependencies": {
- "@datadog/browser-rum": "^5.17.1",
"@loadable/component": "^5.15.3",
"@nilfoundation/react-components": "^0.8.3",
"@nilfoundation/ui-kit": "^2.1.3",
+ "@opentelemetry/exporter-trace-otlp-http": "^0.51.1",
+ "@opentelemetry/sdk-trace-web": "^1.24.1",
"@reduxjs/toolkit": "^1.8.5",
"baseui": "^13.0.0",
"bootstrap-sass": "^3.4.3",
@@ -1932,36 +1933,6 @@
"w3c-keyname": "^2.2.4"
}
},
- "node_modules/@datadog/browser-core": {
- "version": "5.17.1",
- "resolved": "https://registry.npmjs.org/@datadog/browser-core/-/browser-core-5.17.1.tgz",
- "integrity": "sha512-OsdjeRCCT1U9+ddygqg3PkqHOkkk7Vr2tI3U8xgZQyiqCzCuooDHebq/40UMP6mf9OVETDkqlSWQ/ouqvFKjUQ=="
- },
- "node_modules/@datadog/browser-rum": {
- "version": "5.17.1",
- "resolved": "https://registry.npmjs.org/@datadog/browser-rum/-/browser-rum-5.17.1.tgz",
- "integrity": "sha512-BiXA47pBTCjifQxseEVDsrKzLByMdhcp223z8LpyJfjAjMsJad0qxJV5EC+sXANN6yXvpCiC0IjMWNpNHRqpIA==",
- "dependencies": {
- "@datadog/browser-core": "5.17.1",
- "@datadog/browser-rum-core": "5.17.1"
- },
- "peerDependencies": {
- "@datadog/browser-logs": "5.17.1"
- },
- "peerDependenciesMeta": {
- "@datadog/browser-logs": {
- "optional": true
- }
- }
- },
- "node_modules/@datadog/browser-rum-core": {
- "version": "5.17.1",
- "resolved": "https://registry.npmjs.org/@datadog/browser-rum-core/-/browser-rum-core-5.17.1.tgz",
- "integrity": "sha512-tb+kzIR5C5EHeCXLiTW5bQTm4T1KsuBUE+Xdf1MJJlpcPKtiqnNKS2gJ1OJQpfuOHWwWrGsH2tIO7fZUtALqAg==",
- "dependencies": {
- "@datadog/browser-core": "5.17.1"
- }
- },
"node_modules/@date-io/core": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.17.0.tgz",
@@ -2658,6 +2629,177 @@
"node": ">= 8"
}
},
+ "node_modules/@opentelemetry/api": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz",
+ "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@opentelemetry/api-logs": {
+ "version": "0.51.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz",
+ "integrity": "sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==",
+ "dependencies": {
+ "@opentelemetry/api": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@opentelemetry/core": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.24.1.tgz",
+ "integrity": "sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg==",
+ "dependencies": {
+ "@opentelemetry/semantic-conventions": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ }
+ },
+ "node_modules/@opentelemetry/exporter-trace-otlp-http": {
+ "version": "0.51.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.51.1.tgz",
+ "integrity": "sha512-n+LhLPsX07URh+HhV2SHVSvz1t4G/l/CE5BjpmhAPqeTceFac1VpyQkavWEJbvnK5bUEXijWt4LxAxFpt2fXyw==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/otlp-exporter-base": "0.51.1",
+ "@opentelemetry/otlp-transformer": "0.51.1",
+ "@opentelemetry/resources": "1.24.1",
+ "@opentelemetry/sdk-trace-base": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.0.0"
+ }
+ },
+ "node_modules/@opentelemetry/otlp-exporter-base": {
+ "version": "0.51.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.51.1.tgz",
+ "integrity": "sha512-UYlnOYyDdzo1Gw559EHCzru0RwhvuXCwoH8jGo9J4gO1TE58GjnEmIjomMsKBCym3qWNJfIQXw+9SZCV0DdQNg==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.0.0"
+ }
+ },
+ "node_modules/@opentelemetry/otlp-transformer": {
+ "version": "0.51.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.51.1.tgz",
+ "integrity": "sha512-OppYOXwV9LQqqtYUCywqoOqX/JT9LQ5/FMuPZ//eTkvuHdUC4ZMwz2c6uSoT2R90GWvvGnF1iEqTGyTT3xAt2Q==",
+ "dependencies": {
+ "@opentelemetry/api-logs": "0.51.1",
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/resources": "1.24.1",
+ "@opentelemetry/sdk-logs": "0.51.1",
+ "@opentelemetry/sdk-metrics": "1.24.1",
+ "@opentelemetry/sdk-trace-base": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.9.0"
+ }
+ },
+ "node_modules/@opentelemetry/resources": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz",
+ "integrity": "sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/semantic-conventions": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-logs": {
+ "version": "0.51.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.51.1.tgz",
+ "integrity": "sha512-ULQQtl82b673PpZc5/0EtH4V+BrwVOgKJZEB7tYZnGTG3I98tQVk89S9/JSixomDr++F4ih+LSJTCqIKBz+MQQ==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/resources": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.4.0 <1.9.0",
+ "@opentelemetry/api-logs": ">=0.39.1"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-metrics": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.24.1.tgz",
+ "integrity": "sha512-FrAqCbbGao9iKI+Mgh+OsC9+U2YMoXnlDHe06yH7dvavCKzE3S892dGtX54+WhSFVxHR/TMRVJiK/CV93GR0TQ==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/resources": "1.24.1",
+ "lodash.merge": "^4.6.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.9.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-trace-base": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.24.1.tgz",
+ "integrity": "sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/resources": "1.24.1",
+ "@opentelemetry/semantic-conventions": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-trace-web": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.24.1.tgz",
+ "integrity": "sha512-0w+aKRai9VREeo3VrtW+hcbrE2Fl/uKL7G+oXgRNf6pI9QLaEGuEzUTX+oxXVPBadzjOd+5dqCHYdX7UeVjzwA==",
+ "dependencies": {
+ "@opentelemetry/core": "1.24.1",
+ "@opentelemetry/sdk-trace-base": "1.24.1",
+ "@opentelemetry/semantic-conventions": "1.24.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.9.0"
+ }
+ },
+ "node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz",
+ "integrity": "sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@redux-saga/core": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.3.tgz",
@@ -7268,9 +7410,7 @@
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true,
- "peer": true
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"node_modules/log-update": {
"version": "5.0.1",
diff --git a/package.json b/package.json
index 34dc3a8d..0cfb45a7 100644
--- a/package.json
+++ b/package.json
@@ -3,10 +3,11 @@
"version": "0.1.9",
"private": true,
"dependencies": {
- "@datadog/browser-rum": "^5.17.1",
"@loadable/component": "^5.15.3",
"@nilfoundation/react-components": "^0.8.3",
"@nilfoundation/ui-kit": "^2.1.3",
+ "@opentelemetry/exporter-trace-otlp-http": "^0.51.1",
+ "@opentelemetry/sdk-trace-web": "^1.24.1",
"@reduxjs/toolkit": "^1.8.5",
"baseui": "^13.0.0",
"bootstrap-sass": "^3.4.3",
diff --git a/public/runtime-config.toml b/public/runtime-config.toml
index 595eaea5..f1a85096 100644
--- a/public/runtime-config.toml
+++ b/public/runtime-config.toml
@@ -8,7 +8,5 @@ GA_TRACKING_ID = ""
PROOFMARKET_TOOLCHAIN_REPO = ""
CIRCUIT_DEVELOPER_GUIDE_URL = ""
API_RESPONSE_WAIT_TIMEOUT = ""
-DATADOG_APPLICATION_ID = ""
-DATADOG_CLIENT_TOKEN = ""
-DATADOG_SITE = ""
-DATADOG_SERVICE_NAME = ""
+OTEL_TRACE_EXPORTER_URL = ""
+OTEL_SERVICE_NAME = ""
diff --git a/src/App.tsx b/src/App.tsx
index 0104e07b..f5f2bde5 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -15,6 +15,7 @@ import { useBreakpoint } from './features/shared';
import { MobileRouter } from './features/mobile';
import { NotificationContainer } from './features/notifications';
import { BREAKPOINT } from './styles/Breakpoint';
+import { exportErrorToOtelCollector } from './opentelemetry';
const baseDocumentTitle = getRuntimeConfigOrThrow().SITE_DEFAULT_TITLE;
@@ -25,7 +26,10 @@ function App(): ReactElement {
const bp = useBreakpoint();
return (
- }>
+ }
+ onError={e => exportErrorToOtelCollector(e)}
+ >
- */
-
-import { datadogRum } from '@datadog/browser-rum';
-import { getRuntimeConfigOrThrow } from './utils';
-
-/**
- * Configures Datadog Real User Monitoring (RUM) for the application.
- *
- * @see {@link https://docs.datadoghq.com/real_user_monitoring/browser/}
- */
-export const configureDatadogRUM = (): void => {
- // if (!import.meta.env.PROD) {
- // return;
- // }
-
- const { DATADOG_APPLICATION_ID, DATADOG_CLIENT_TOKEN, DATADOG_SERVICE_NAME, DATADOG_SITE } =
- getRuntimeConfigOrThrow();
-
- if (!DATADOG_APPLICATION_ID || !DATADOG_CLIENT_TOKEN || !DATADOG_SERVICE_NAME || !DATADOG_SITE) {
- return;
- }
-
- datadogRum.init({
- applicationId: DATADOG_APPLICATION_ID,
- clientToken: DATADOG_CLIENT_TOKEN,
- site: DATADOG_SITE,
- service: DATADOG_SERVICE_NAME,
- env: 'production',
- sessionSampleRate: 100,
- sessionReplaySampleRate: 100,
- trackResources: false,
- trackLongTasks: false,
- trackUserInteractions: false,
- silentMultipleInit: true,
- allowFallbackToLocalStorage: true,
- });
-};
diff --git a/src/features/routing/constants/routesConfig.tsx b/src/features/routing/constants/routesConfig.tsx
index f23e7e86..1b39a35c 100644
--- a/src/features/routing/constants/routesConfig.tsx
+++ b/src/features/routing/constants/routesConfig.tsx
@@ -3,7 +3,6 @@
* @copyright Yury Korotovskikh
*/
-import { lazy } from 'react';
import { Navigate } from 'react-router-dom';
import type { RouteObject } from 'react-router-dom';
import { RouterParam } from '@/enums';
diff --git a/src/index.tsx b/src/index.tsx
index 077e1744..d161e789 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -15,15 +15,15 @@ import { Provider as StyletronProvider } from 'styletron-react';
import { BaseProvider } from 'baseui';
import App from './App';
import { store } from './redux';
-import { configureDatadogRUM } from './datadog';
+import { initOpentelemetry } from './opentelemetry';
import { reportWebVitals } from './reportWebVitals';
import configureGA from './ga';
//import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import { checkRuntimeConfig } from './utils';
checkRuntimeConfig();
-configureDatadogRUM();
configureGA();
+initOpentelemetry();
const engine = new Styletron();
const { theme } = createTheme(engine, { enableDefaultFonts: false });
diff --git a/src/opentelemetry.ts b/src/opentelemetry.ts
new file mode 100644
index 00000000..4dbb2fa0
--- /dev/null
+++ b/src/opentelemetry.ts
@@ -0,0 +1,58 @@
+/**
+ * @file Opentelemtry configuration.
+ * @copyright Yury Korotovskikh
+ */
+
+import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace-web';
+import { OTLPTraceExporter as HttpTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
+import type { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base';
+import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
+import { Resource } from '@opentelemetry/resources';
+import { getRuntimeConfigOrThrow } from './utils';
+import packageJson from '../package.json';
+
+const { OTEL_TRACE_EXPORTER_URL, OTEL_SERVICE_NAME = packageJson.name } = getRuntimeConfigOrThrow();
+
+const exporterOptions = {
+ url: OTEL_TRACE_EXPORTER_URL,
+} satisfies OTLPExporterNodeConfigBase;
+
+const provider = new WebTracerProvider({
+ resource: new Resource({
+ [SEMRESATTRS_SERVICE_NAME]: OTEL_SERVICE_NAME,
+ }),
+});
+
+const exporter = new HttpTraceExporter(exporterOptions);
+
+// eslint-disable-next-line jsdoc/require-jsdoc
+export const initOpentelemetry = () => {
+ provider.addSpanProcessor(new BatchSpanProcessor(exporter));
+ provider.register();
+};
+
+/**
+ * Register error in opentelemetry.
+ *
+ * @param error - Error to be reported.
+ */
+export const exportErrorToOtelCollector = (error: Error) => {
+ const span = provider.getTracer('default').startSpan('Operational error');
+
+ span.setAttribute('message', error.message);
+ span.recordException(error);
+ span.setStatus({ code: 2, message: error.message });
+
+ span.end();
+};
+
+// Register global error handler to report uncaught errors.
+window.onerror = function (message, _source, _lineno, _colno, error) {
+ const span = provider.getTracer('default').startSpan('Uncaught error');
+
+ error && span.recordException(error);
+ typeof message === 'string' && span.setAttribute('message', message);
+ span.setStatus({ code: 2, message: typeof message === 'string' ? message : '' });
+
+ span.end();
+};
diff --git a/src/types/runtime-config.d.ts b/src/types/runtime-config.d.ts
index 743e26d6..25a744eb 100644
--- a/src/types/runtime-config.d.ts
+++ b/src/types/runtime-config.d.ts
@@ -16,10 +16,8 @@ const keys = [
'GA_TRACKING_ID',
'CIRCUIT_DEVELOPER_GUIDE_URL',
'API_RESPONSE_WAIT_TIMEOUT',
- 'DATADOG_APPLICATION_ID',
- 'DATADOG_CLIENT_TOKEN',
- 'DATADOG_SITE',
- 'DATADOG_SERVICE_NAME',
+ 'OTEL_TRACE_EXPORTER_URL',
+ 'OTEL_SERVICE_NAME',
] as const;
type RuntimConfigKeys = (typeof keys)[number];
diff --git a/src/utils/runtimeConfig/checkRuntimeConfig.ts b/src/utils/runtimeConfig/checkRuntimeConfig.ts
index c6684d10..0633fe13 100644
--- a/src/utils/runtimeConfig/checkRuntimeConfig.ts
+++ b/src/utils/runtimeConfig/checkRuntimeConfig.ts
@@ -15,10 +15,6 @@ const requiredEnvs: Array = [
'PROOFMARKET_TOOLCHAIN_REPO',
'SITE_DEFAULT_TITLE',
'CIRCUIT_DEVELOPER_GUIDE_URL',
- 'DATADOG_APPLICATION_ID',
- 'DATADOG_CLIENT_TOKEN',
- 'DATADOG_SITE',
- 'DATADOG_SERVICE_NAME',
];
/**