From 47ac43753a03e8507165eb885cc13b2bdc45298c Mon Sep 17 00:00:00 2001
From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
Date: Mon, 25 Dec 2023 20:57:36 +0530
Subject: [PATCH 1/5] feat: remove ReactGA and migrate to GA4
Signed-off-by: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
---
packages/jaeger-ui/package.json | 1 -
packages/jaeger-ui/src/utils/tracking/ga.tsx | 66 +++++++++++++++++---
yarn.lock | 5 --
3 files changed, 58 insertions(+), 14 deletions(-)
diff --git a/packages/jaeger-ui/package.json b/packages/jaeger-ui/package.json
index f5eff1ab16..67319d7918 100644
--- a/packages/jaeger-ui/package.json
+++ b/packages/jaeger-ui/package.json
@@ -74,7 +74,6 @@
"react": "^18.2.0",
"react-circular-progressbar": "^2.1.0",
"react-dom": "^18.2.0",
- "react-ga": "^3.3.1",
"react-helmet": "^6.1.0",
"react-icons": "^4.10.1",
"react-is": "^18.2.0",
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.tsx b/packages/jaeger-ui/src/utils/tracking/ga.tsx
index a85d681e56..07c82ee36e 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/ga.tsx
@@ -13,7 +13,6 @@
// limitations under the License.
import _get from 'lodash/get';
-import ReactGA from 'react-ga';
import Raven, { RavenOptions, RavenTransportOptions } from 'raven-js';
import convRavenToGa from './conv-raven-to-ga';
@@ -24,6 +23,40 @@ import { logTrackingCalls } from './utils';
import { getAppEnvironment, shouldDebugGoogleAnalytics } from '../constants';
import parseQuery from '../parseQuery';
+// Modify the global scope to add the `gtag` function and the `dataLayer` array
+declare global {
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ interface Window {
+ dataLayer: object[];
+ gtag: (...args: (string | object)[]) => void;
+ }
+}
+
+// Function to initialize the Google Analytics script
+const initGA = (GA_MEASUREMENT_ID: string, gtagUrl = 'https://www.googletagmanager.com/gtag/js') => {
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
+ return;
+ }
+
+ const script = document.createElement('script');
+ script.async = true;
+ script.src = `${gtagUrl}?id=${GA_MEASUREMENT_ID}`;
+ document.body.appendChild(script);
+
+ window.dataLayer = window.dataLayer || [];
+ window.gtag = (...args) => {
+ window.dataLayer.push(args);
+ };
+};
+
+// Function to call the `gtag` function defined on the window object
+const gtag = (...args: (string | object)[]) => {
+ if (typeof window !== 'undefined')
+ if (typeof window.gtag === 'function') {
+ window.gtag(...args);
+ }
+};
+
const isTruish = (value?: string | string[]) => {
return Boolean(value) && value !== '0' && value !== 'false';
};
@@ -56,7 +89,12 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
msg = `jaeger/${msg}`;
}
msg = msg.slice(0, 149);
- ReactGA.exception({ description: msg, fatal: false });
+
+ gtag('event', 'exception', {
+ description: msg,
+ fatal: false,
+ });
+
if (isDebugMode) {
logTrackingCalls();
}
@@ -90,7 +128,13 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
if (value != null) {
event.value = Math.round(value);
}
- ReactGA.event(event);
+
+ gtag('event', event.action, {
+ event_category: event.category,
+ event_label: event.label,
+ value: event.value,
+ });
+
if (isDebugMode) {
logTrackingCalls();
}
@@ -107,18 +151,22 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
return;
}
- const gaConfig = { testMode: isTest || isDebugMode, titleCase: false, debug: true };
- ReactGA.initialize(gaID || 'debug-mode', gaConfig);
- ReactGA.set({
+ initGA(gaID || 'debug-mode');
+ gtag('set', {
appId: 'github.com/jaegertracing/jaeger-ui',
appName: 'Jaeger UI',
appVersion: versionLong,
});
+
if (cookiesToDimensions !== undefined) {
(cookiesToDimensions as unknown as Array<{ cookie: string; dimension: string }>).forEach(
({ cookie, dimension }: { cookie: string; dimension: string }) => {
const match = ` ${document.cookie}`.match(new RegExp(`[; ]${cookie}=([^\\s;]*)`));
- if (match) ReactGA.set({ [dimension]: match[1] });
+ if (match) {
+ gtag('set', {
+ [dimension]: match[1],
+ });
+ }
// eslint-disable-next-line no-console
else console.warn(`${cookie} not present in cookies, could not set dimension: ${dimension}`);
}
@@ -152,7 +200,9 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
const trackPageView = (pathname: string, search: string | TNil) => {
const pagePath = search ? `${pathname}${search}` : pathname;
- ReactGA.pageview(pagePath);
+ gtag('event', 'page_view', {
+ page_path: pagePath,
+ });
if (isDebugMode) {
logTrackingCalls();
}
diff --git a/yarn.lock b/yarn.lock
index eede1fd901..3b83649d5d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8470,11 +8470,6 @@ react-fast-compare@^3.1.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
-react-ga@^3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-3.3.1.tgz#d8e1f4e05ec55ed6ff944dcb14b99011dfaf9504"
- integrity sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ==
-
react-helmet@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726"
From 23098d7d31c2098feb2c516f7b728cad34502526 Mon Sep 17 00:00:00 2001
From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
Date: Tue, 26 Dec 2023 13:02:35 +0530
Subject: [PATCH 2/5] fix types and implementation
Signed-off-by: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
---
packages/jaeger-ui/src/utils/tracking/ga.tsx | 34 +++++++++++---------
packages/jaeger-ui/src/vite-env.d.ts | 9 ++++++
2 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.tsx b/packages/jaeger-ui/src/utils/tracking/ga.tsx
index 07c82ee36e..62583df86c 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/ga.tsx
@@ -23,38 +23,41 @@ import { logTrackingCalls } from './utils';
import { getAppEnvironment, shouldDebugGoogleAnalytics } from '../constants';
import parseQuery from '../parseQuery';
-// Modify the global scope to add the `gtag` function and the `dataLayer` array
+// Modify the `window` object to have an additional attribute `dataLayer`
+// This is required by the gtag.js script to work
declare global {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface Window {
- dataLayer: object[];
- gtag: (...args: (string | object)[]) => void;
+ dataLayer: (string | object)[][] | undefined;
}
}
+// Function to add a new event to the Google Analytics dataLayer
+const gtag = (...args: (string | object)[]) => {
+ if (window !== undefined)
+ if (window.dataLayer !== undefined) {
+ window.dataLayer.push(args);
+ }
+};
+
// Function to initialize the Google Analytics script
-const initGA = (GA_MEASUREMENT_ID: string, gtagUrl = 'https://www.googletagmanager.com/gtag/js') => {
+const initGA = (GA_MEASUREMENT_ID: string) => {
if (typeof window === 'undefined' || typeof document === 'undefined') {
return;
}
+ const gtagUrl = 'https://www.googletagmanager.com/gtag/js';
+
+ // Load the script asynchronously
const script = document.createElement('script');
script.async = true;
script.src = `${gtagUrl}?id=${GA_MEASUREMENT_ID}`;
document.body.appendChild(script);
+ // Initialize the dataLayer and send initial configuration data
window.dataLayer = window.dataLayer || [];
- window.gtag = (...args) => {
- window.dataLayer.push(args);
- };
-};
-
-// Function to call the `gtag` function defined on the window object
-const gtag = (...args: (string | object)[]) => {
- if (typeof window !== 'undefined')
- if (typeof window.gtag === 'function') {
- window.gtag(...args);
- }
+ gtag('js', new Date());
+ gtag('config', GA_MEASUREMENT_ID);
};
const isTruish = (value?: string | string[]) => {
@@ -152,6 +155,7 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
}
initGA(gaID || 'debug-mode');
+
gtag('set', {
appId: 'github.com/jaegertracing/jaeger-ui',
appName: 'Jaeger UI',
diff --git a/packages/jaeger-ui/src/vite-env.d.ts b/packages/jaeger-ui/src/vite-env.d.ts
index c70e348b4d..5afdcd36c9 100644
--- a/packages/jaeger-ui/src/vite-env.d.ts
+++ b/packages/jaeger-ui/src/vite-env.d.ts
@@ -14,3 +14,12 @@
// eslint-disable-next-line spaced-comment
///
+
+declare namespace JaegerUI {
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ interface Window {
+ // dataLayer is used by Google Tag Manager
+ // It should never be changed by any module except utils/tracking/ga.ts
+ dataLayer: never;
+ }
+}
From daacac33df4d540ffdf291d44ed3d90de9f0f90f Mon Sep 17 00:00:00 2001
From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
Date: Tue, 26 Dec 2023 13:54:07 +0530
Subject: [PATCH 3/5] update tests
Signed-off-by: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
---
.../jaeger-ui/src/utils/tracking/ga.test.js | 71 ++++++++++---------
packages/jaeger-ui/src/utils/tracking/ga.tsx | 4 +-
.../jaeger-ui/src/utils/tracking/utils.tsx | 11 +--
packages/jaeger-ui/src/vite-env.d.ts | 2 +-
4 files changed, 42 insertions(+), 46 deletions(-)
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.test.js b/packages/jaeger-ui/src/utils/tracking/ga.test.js
index d9944851d1..8d1528d88a 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.test.js
+++ b/packages/jaeger-ui/src/utils/tracking/ga.test.js
@@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import ReactGA from 'react-ga';
import * as GA from './ga';
import * as utils from './utils';
-import { getVersionInfo, getAppEnvironment } from '../constants';
+import { getAppEnvironment } from '../constants';
jest.mock('./conv-raven-to-ga', () => () => ({
category: 'jaeger/a',
@@ -35,7 +34,6 @@ function getStr(len) {
}
describe('google analytics tracking', () => {
- let calls;
let tracking;
beforeAll(() => {
@@ -54,16 +52,18 @@ describe('google analytics tracking', () => {
});
beforeEach(() => {
- getVersionInfo.mockReturnValue('{}');
- calls = ReactGA.testModeAPI.calls;
- calls.length = 0;
+ jest.useFakeTimers();
+ // Set an arbitrary date so that we can test the date-based dimension
+ jest.setSystemTime(new Date('2023-01-01'));
+ window.dataLayer = [];
});
describe('init', () => {
it('check init function (no cookies)', () => {
tracking.init();
- expect(calls).toEqual([
- ['create', 'UA-123456', 'auto'],
+ expect(window.dataLayer).toEqual([
+ ['js', new Date()],
+ ['config', 'UA-123456'],
[
'set',
{
@@ -78,8 +78,9 @@ describe('google analytics tracking', () => {
it('check init function (no cookies)', () => {
document.cookie = 'page=1;';
tracking.init();
- expect(calls).toEqual([
- ['create', 'UA-123456', 'auto'],
+ expect(window.dataLayer).toEqual([
+ ['js', new Date()],
+ ['config', 'UA-123456'],
[
'set',
{
@@ -96,33 +97,33 @@ describe('google analytics tracking', () => {
describe('trackPageView', () => {
it('tracks a page view', () => {
tracking.trackPageView('a', 'b');
- expect(calls).toEqual([['send', { hitType: 'pageview', page: 'ab' }]]);
+ expect(window.dataLayer).toEqual([['event', 'page_view', { page_path: 'ab' }]]);
});
it('ignores search when it is falsy', () => {
tracking.trackPageView('a');
- expect(calls).toEqual([['send', { hitType: 'pageview', page: 'a' }]]);
+ expect(window.dataLayer).toEqual([['event', 'page_view', { page_path: 'a' }]]);
});
});
describe('trackError', () => {
it('tracks an error', () => {
tracking.trackError('a');
- expect(calls).toEqual([
- ['send', { hitType: 'exception', exDescription: expect.any(String), exFatal: false }],
+ expect(window.dataLayer).toEqual([
+ ['event', 'exception', { description: expect.any(String), fatal: false }],
]);
});
it('ensures "jaeger" is prepended', () => {
tracking.trackError('a');
- expect(calls).toEqual([['send', { hitType: 'exception', exDescription: 'jaeger/a', exFatal: false }]]);
+ expect(window.dataLayer).toEqual([['event', 'exception', { description: 'jaeger/a', fatal: false }]]);
});
it('truncates if needed', () => {
const str = `jaeger/${getStr(200)}`;
tracking.trackError(str);
- expect(calls).toEqual([
- ['send', { hitType: 'exception', exDescription: str.slice(0, 149), exFatal: false }],
+ expect(window.dataLayer).toEqual([
+ ['event', 'exception', { description: str.slice(0, 149), fatal: false }],
]);
});
});
@@ -132,13 +133,12 @@ describe('google analytics tracking', () => {
const category = 'jaeger/some-category';
const action = 'some-action';
tracking.trackEvent(category, action);
- expect(calls).toEqual([
+ expect(window.dataLayer).toEqual([
[
- 'send',
+ 'event',
+ 'some-action',
{
- hitType: 'event',
- eventCategory: category,
- eventAction: action,
+ event_category: category,
},
],
]);
@@ -148,22 +148,19 @@ describe('google analytics tracking', () => {
const category = 'some-category';
const action = 'some-action';
tracking.trackEvent(category, action);
- expect(calls).toEqual([
- ['send', { hitType: 'event', eventCategory: `jaeger/${category}`, eventAction: action }],
- ]);
+ expect(window.dataLayer).toEqual([['event', 'some-action', { event_category: `jaeger/${category}` }]]);
});
it('truncates values, if needed', () => {
const str = `jaeger/${getStr(600)}`;
tracking.trackEvent(str, str, str);
- expect(calls).toEqual([
+ expect(window.dataLayer).toEqual([
[
- 'send',
+ 'event',
+ str.slice(0, 499),
{
- hitType: 'event',
- eventCategory: str.slice(0, 149),
- eventAction: str.slice(0, 499),
- eventLabel: str.slice(0, 499),
+ event_category: str.slice(0, 149),
+ event_label: str.slice(0, 499),
},
],
]);
@@ -171,10 +168,12 @@ describe('google analytics tracking', () => {
});
it('converting raven-js errors', () => {
- window.onunhandledrejection({ reason: new Error('abc') });
- expect(calls).toEqual([
- ['send', { hitType: 'exception', exDescription: expect.any(String), exFatal: false }],
- ['send', { hitType: 'event', eventCategory: expect.any(String), eventAction: expect.any(String) }],
+ window.onunhandledrejection({
+ reason: new Error('abc'),
+ });
+ expect(window.dataLayer).toEqual([
+ ['event', 'exception', { description: expect.any(String), fatal: false }],
+ ['event', expect.any(String), { event_category: expect.any(String) }],
]);
});
@@ -209,10 +208,12 @@ describe('google analytics tracking', () => {
it('isDebugMode = true', () => {
// eslint-disable-next-line no-import-assign
utils.logTrackingCalls = jest.fn();
+
trackingDebug.init();
trackingDebug.trackError();
trackingDebug.trackEvent('jaeger/some-category', 'some-action');
trackingDebug.trackPageView('a', 'b');
+
expect(utils.logTrackingCalls).toHaveBeenCalledTimes(4);
});
});
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.tsx b/packages/jaeger-ui/src/utils/tracking/ga.tsx
index 62583df86c..03779b65e3 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/ga.tsx
@@ -134,8 +134,8 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
gtag('event', event.action, {
event_category: event.category,
- event_label: event.label,
- value: event.value,
+ ...(event.label && { event_label: event.label }),
+ ...(event.value && { event_value: event.value }),
});
if (isDebugMode) {
diff --git a/packages/jaeger-ui/src/utils/tracking/utils.tsx b/packages/jaeger-ui/src/utils/tracking/utils.tsx
index 75f826da59..0abc1f46f1 100644
--- a/packages/jaeger-ui/src/utils/tracking/utils.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/utils.tsx
@@ -12,14 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import ReactGA from 'react-ga';
-
// eslint-disable-next-line import/prefer-default-export
export const logTrackingCalls = () => {
- const calls = ReactGA.testModeAPI.calls;
- for (let i = 0; i < calls.length; i++) {
- // eslint-disable-next-line no-console
- console.log('[react-ga]', ...calls[i]);
- }
- calls.length = 0;
+ // eslint-disable-next-line no-console
+ window.dataLayer?.forEach(callArgs => console.log('[GA Tracking]', ...callArgs));
+ window.dataLayer = [];
};
diff --git a/packages/jaeger-ui/src/vite-env.d.ts b/packages/jaeger-ui/src/vite-env.d.ts
index 5afdcd36c9..71bbc6b698 100644
--- a/packages/jaeger-ui/src/vite-env.d.ts
+++ b/packages/jaeger-ui/src/vite-env.d.ts
@@ -15,7 +15,7 @@
// eslint-disable-next-line spaced-comment
///
-declare namespace JaegerUI {
+declare namespace global {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface Window {
// dataLayer is used by Google Tag Manager
From 6a486405cb7368e1a58d051f8cb3648ec022e8e1 Mon Sep 17 00:00:00 2001
From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
Date: Tue, 26 Dec 2023 14:12:23 +0530
Subject: [PATCH 4/5] fix leaking of window type
Signed-off-by: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
---
packages/jaeger-ui/src/utils/tracking/ga.tsx | 15 ++++++---------
packages/jaeger-ui/src/utils/tracking/utils.tsx | 4 ++++
packages/jaeger-ui/src/vite-env.d.ts | 5 +++--
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.tsx b/packages/jaeger-ui/src/utils/tracking/ga.tsx
index 03779b65e3..90f2450ce1 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/ga.tsx
@@ -25,13 +25,14 @@ import parseQuery from '../parseQuery';
// Modify the `window` object to have an additional attribute `dataLayer`
// This is required by the gtag.js script to work
-declare global {
- // eslint-disable-next-line @typescript-eslint/naming-convention
- interface Window {
- dataLayer: (string | object)[][] | undefined;
- }
+
+// eslint-disable-next-line @typescript-eslint/naming-convention
+export interface WindowWithGATracking extends Window {
+ dataLayer: (string | object)[][] | undefined;
}
+declare let window: WindowWithGATracking;
+
// Function to add a new event to the Google Analytics dataLayer
const gtag = (...args: (string | object)[]) => {
if (window !== undefined)
@@ -42,10 +43,6 @@ const gtag = (...args: (string | object)[]) => {
// Function to initialize the Google Analytics script
const initGA = (GA_MEASUREMENT_ID: string) => {
- if (typeof window === 'undefined' || typeof document === 'undefined') {
- return;
- }
-
const gtagUrl = 'https://www.googletagmanager.com/gtag/js';
// Load the script asynchronously
diff --git a/packages/jaeger-ui/src/utils/tracking/utils.tsx b/packages/jaeger-ui/src/utils/tracking/utils.tsx
index 0abc1f46f1..d78a8a2cb1 100644
--- a/packages/jaeger-ui/src/utils/tracking/utils.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/utils.tsx
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { WindowWithGATracking } from './ga';
+
+declare let window: WindowWithGATracking;
+
// eslint-disable-next-line import/prefer-default-export
export const logTrackingCalls = () => {
// eslint-disable-next-line no-console
diff --git a/packages/jaeger-ui/src/vite-env.d.ts b/packages/jaeger-ui/src/vite-env.d.ts
index 71bbc6b698..0cfcf9462c 100644
--- a/packages/jaeger-ui/src/vite-env.d.ts
+++ b/packages/jaeger-ui/src/vite-env.d.ts
@@ -18,8 +18,9 @@
declare namespace global {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface Window {
- // dataLayer is used by Google Tag Manager
- // It should never be changed by any module except utils/tracking/ga.ts
+ // dataLayer property is used by Google Tag Manager
+ // It should be only be changed with the help of the custom Interface WindowWithGATracking
+ // defined in utils/tracking/ga.ts
dataLayer: never;
}
}
From ada2383ff15f4d7a580e7c13e715f92b3fe0bbfb Mon Sep 17 00:00:00 2001
From: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
Date: Tue, 26 Dec 2023 23:47:25 +0530
Subject: [PATCH 5/5] remove logging utils
Signed-off-by: Eshaan Aggarwal <96648934+EshaanAgg@users.noreply.github.com>
---
.../jaeger-ui/src/utils/tracking/ga.test.js | 9 +--
packages/jaeger-ui/src/utils/tracking/ga.tsx | 66 +++++++------------
.../src/utils/tracking/utils.test.js | 23 -------
.../jaeger-ui/src/utils/tracking/utils.tsx | 24 -------
packages/jaeger-ui/src/vite-env.d.ts | 10 ---
5 files changed, 30 insertions(+), 102 deletions(-)
delete mode 100644 packages/jaeger-ui/src/utils/tracking/utils.test.js
delete mode 100644 packages/jaeger-ui/src/utils/tracking/utils.tsx
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.test.js b/packages/jaeger-ui/src/utils/tracking/ga.test.js
index 8d1528d88a..dbe48d9bdd 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.test.js
+++ b/packages/jaeger-ui/src/utils/tracking/ga.test.js
@@ -13,7 +13,6 @@
// limitations under the License.
import * as GA from './ga';
-import * as utils from './utils';
import { getAppEnvironment } from '../constants';
jest.mock('./conv-raven-to-ga', () => () => ({
@@ -205,16 +204,18 @@ describe('google analytics tracking', () => {
);
});
+ /* eslint-disable no-console */
it('isDebugMode = true', () => {
// eslint-disable-next-line no-import-assign
- utils.logTrackingCalls = jest.fn();
+ console.log = jest.fn();
trackingDebug.init();
+ expect(console.log).toHaveBeenCalledTimes(4);
+
trackingDebug.trackError();
trackingDebug.trackEvent('jaeger/some-category', 'some-action');
trackingDebug.trackPageView('a', 'b');
-
- expect(utils.logTrackingCalls).toHaveBeenCalledTimes(4);
+ expect(console.log).toHaveBeenCalledTimes(7);
});
});
});
diff --git a/packages/jaeger-ui/src/utils/tracking/ga.tsx b/packages/jaeger-ui/src/utils/tracking/ga.tsx
index 90f2450ce1..b7bdfa52ec 100644
--- a/packages/jaeger-ui/src/utils/tracking/ga.tsx
+++ b/packages/jaeger-ui/src/utils/tracking/ga.tsx
@@ -19,7 +19,6 @@ import convRavenToGa from './conv-raven-to-ga';
import { TNil } from '../../types';
import { Config } from '../../types/config';
import { IWebAnalyticsFunc } from '../../types/tracking';
-import { logTrackingCalls } from './utils';
import { getAppEnvironment, shouldDebugGoogleAnalytics } from '../constants';
import parseQuery from '../parseQuery';
@@ -27,36 +26,12 @@ import parseQuery from '../parseQuery';
// This is required by the gtag.js script to work
// eslint-disable-next-line @typescript-eslint/naming-convention
-export interface WindowWithGATracking extends Window {
+interface WindowWithGATracking extends Window {
dataLayer: (string | object)[][] | undefined;
}
declare let window: WindowWithGATracking;
-// Function to add a new event to the Google Analytics dataLayer
-const gtag = (...args: (string | object)[]) => {
- if (window !== undefined)
- if (window.dataLayer !== undefined) {
- window.dataLayer.push(args);
- }
-};
-
-// Function to initialize the Google Analytics script
-const initGA = (GA_MEASUREMENT_ID: string) => {
- const gtagUrl = 'https://www.googletagmanager.com/gtag/js';
-
- // Load the script asynchronously
- const script = document.createElement('script');
- script.async = true;
- script.src = `${gtagUrl}?id=${GA_MEASUREMENT_ID}`;
- document.body.appendChild(script);
-
- // Initialize the dataLayer and send initial configuration data
- window.dataLayer = window.dataLayer || [];
- gtag('js', new Date());
- gtag('config', GA_MEASUREMENT_ID);
-};
-
const isTruish = (value?: string | string[]) => {
return Boolean(value) && value !== '0' && value !== 'false';
};
@@ -83,6 +58,18 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
return isTest || isDebugMode || (isProd && Boolean(gaID));
};
+ // Function to add a new event to the Google Analytics dataLayer
+ const gtag = (...args: (string | object)[]) => {
+ if (window !== undefined)
+ if (window.dataLayer !== undefined && Array.isArray(window.dataLayer)) {
+ window.dataLayer.push(args);
+ if (isDebugMode) {
+ // eslint-disable-next-line no-console
+ console.log('[GA Tracking]', ...args);
+ }
+ }
+ };
+
const trackError = (description: string) => {
let msg = description;
if (!/^jaeger/i.test(msg)) {
@@ -94,10 +81,6 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
description: msg,
fatal: false,
});
-
- if (isDebugMode) {
- logTrackingCalls();
- }
};
const trackEvent = (
@@ -134,10 +117,6 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
...(event.label && { event_label: event.label }),
...(event.value && { event_value: event.value }),
});
-
- if (isDebugMode) {
- logTrackingCalls();
- }
};
const trackRavenError = (ravenData: RavenTransportOptions) => {
@@ -151,8 +130,19 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
return;
}
- initGA(gaID || 'debug-mode');
+ const gtagUrl = 'https://www.googletagmanager.com/gtag/js';
+ const GA_MEASUREMENT_ID = gaID || 'debug-mode';
+
+ // Load the script asynchronously
+ const script = document.createElement('script');
+ script.async = true;
+ script.src = `${gtagUrl}?id=${GA_MEASUREMENT_ID}`;
+ document.body.appendChild(script);
+ // Initialize the dataLayer and send initial configuration data
+ window.dataLayer = window.dataLayer || [];
+ gtag('js', new Date());
+ gtag('config', GA_MEASUREMENT_ID);
gtag('set', {
appId: 'github.com/jaegertracing/jaeger-ui',
appName: 'Jaeger UI',
@@ -194,9 +184,6 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
Raven.captureException(evt.reason);
};
}
- if (isDebugMode) {
- logTrackingCalls();
- }
};
const trackPageView = (pathname: string, search: string | TNil) => {
@@ -204,9 +191,6 @@ const GA: IWebAnalyticsFunc = (config: Config, versionShort: string, versionLong
gtag('event', 'page_view', {
page_path: pagePath,
});
- if (isDebugMode) {
- logTrackingCalls();
- }
};
return {
diff --git a/packages/jaeger-ui/src/utils/tracking/utils.test.js b/packages/jaeger-ui/src/utils/tracking/utils.test.js
deleted file mode 100644
index 30c61067d3..0000000000
--- a/packages/jaeger-ui/src/utils/tracking/utils.test.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2021 The Jaeger Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import * as utils from './utils';
-
-describe('utils', () => {
- describe('logTrackingCalls', () => {
- it('dry run', () => {
- expect(utils.logTrackingCalls()).toBeUndefined();
- });
- });
-});
diff --git a/packages/jaeger-ui/src/utils/tracking/utils.tsx b/packages/jaeger-ui/src/utils/tracking/utils.tsx
deleted file mode 100644
index d78a8a2cb1..0000000000
--- a/packages/jaeger-ui/src/utils/tracking/utils.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2021 The Jaeger Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { WindowWithGATracking } from './ga';
-
-declare let window: WindowWithGATracking;
-
-// eslint-disable-next-line import/prefer-default-export
-export const logTrackingCalls = () => {
- // eslint-disable-next-line no-console
- window.dataLayer?.forEach(callArgs => console.log('[GA Tracking]', ...callArgs));
- window.dataLayer = [];
-};
diff --git a/packages/jaeger-ui/src/vite-env.d.ts b/packages/jaeger-ui/src/vite-env.d.ts
index 0cfcf9462c..c70e348b4d 100644
--- a/packages/jaeger-ui/src/vite-env.d.ts
+++ b/packages/jaeger-ui/src/vite-env.d.ts
@@ -14,13 +14,3 @@
// eslint-disable-next-line spaced-comment
///
-
-declare namespace global {
- // eslint-disable-next-line @typescript-eslint/naming-convention
- interface Window {
- // dataLayer property is used by Google Tag Manager
- // It should be only be changed with the help of the custom Interface WindowWithGATracking
- // defined in utils/tracking/ga.ts
- dataLayer: never;
- }
-}