mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Echo: Add support for Google Analytics 4 (#55446)
* user essentials mob! 🔱 lastFile:public/app/core/services/echo/backends/analytics/GA4Backend.ts * user essentials mob! 🔱 * user essentials mob! 🔱 lastFile:public/app/core/services/echo/backends/analytics/GA4Backend.ts * user essentials mob! 🔱 lastFile:public/app/core/services/echo/backends/analytics/GA4Backend.ts * user essentials mob! 🔱 lastFile:public/app/app.ts * user essentials mob! 🔱 Co-authored-by: eledobleefe <laura.fernandez@grafana.com> Co-authored-by: Leodegario Pasakdal <leodegario.pasakdal@grafana.com>
This commit is contained in:
@@ -212,6 +212,9 @@ check_for_plugin_updates = true
|
|||||||
# Google Analytics universal tracking code, only enabled if you specify an id here
|
# Google Analytics universal tracking code, only enabled if you specify an id here
|
||||||
google_analytics_ua_id =
|
google_analytics_ua_id =
|
||||||
|
|
||||||
|
# Google Analytics 4 tracking code, only enabled if you specify an id here
|
||||||
|
google_analytics_4_id =
|
||||||
|
|
||||||
# Google Tag Manager ID, only enabled if you specify an id here
|
# Google Tag Manager ID, only enabled if you specify an id here
|
||||||
google_tag_manager_id =
|
google_tag_manager_id =
|
||||||
|
|
||||||
|
|||||||
@@ -218,6 +218,9 @@
|
|||||||
# Google Analytics universal tracking code, only enabled if you specify an id here
|
# Google Analytics universal tracking code, only enabled if you specify an id here
|
||||||
;google_analytics_ua_id =
|
;google_analytics_ua_id =
|
||||||
|
|
||||||
|
# Google Analytics 4 tracking code, only enabled if you specify an id here
|
||||||
|
;google_analytics_4_id =
|
||||||
|
|
||||||
# Google Tag Manager ID, only enabled if you specify an id here
|
# Google Tag Manager ID, only enabled if you specify an id here
|
||||||
;google_tag_manager_id =
|
;google_tag_manager_id =
|
||||||
|
|
||||||
|
|||||||
@@ -474,6 +474,10 @@ Set to false disables checking for new versions of installed plugins from https:
|
|||||||
If you want to track Grafana usage via Google analytics specify _your_ Universal
|
If you want to track Grafana usage via Google analytics specify _your_ Universal
|
||||||
Analytics ID here. By default this feature is disabled.
|
Analytics ID here. By default this feature is disabled.
|
||||||
|
|
||||||
|
### google_analytics_4_id
|
||||||
|
|
||||||
|
If you want to track Grafana usage via Google Analytics 4 specify _your_ GA4 ID here. By default this feature is disabled.
|
||||||
|
|
||||||
### google_tag_manager_id
|
### google_tag_manager_id
|
||||||
|
|
||||||
Google Tag Manager ID, only enabled if you enter an ID here.
|
Google Tag Manager ID, only enabled if you enter an ID here.
|
||||||
|
|||||||
@@ -124,6 +124,7 @@
|
|||||||
"@types/eslint": "8.4.5",
|
"@types/eslint": "8.4.5",
|
||||||
"@types/file-saver": "2.0.5",
|
"@types/file-saver": "2.0.5",
|
||||||
"@types/google.analytics": "^0.0.42",
|
"@types/google.analytics": "^0.0.42",
|
||||||
|
"@types/gtag.js": "^0.0.11",
|
||||||
"@types/history": "4.7.11",
|
"@types/history": "4.7.11",
|
||||||
"@types/hoist-non-react-statics": "3.3.1",
|
"@types/hoist-non-react-statics": "3.3.1",
|
||||||
"@types/jest": "28.1.6",
|
"@types/jest": "28.1.6",
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ export interface GrafanaConfig {
|
|||||||
feedbackLinksEnabled: boolean;
|
feedbackLinksEnabled: boolean;
|
||||||
secretsManagerPluginEnabled: boolean;
|
secretsManagerPluginEnabled: boolean;
|
||||||
googleAnalyticsId: string | undefined;
|
googleAnalyticsId: string | undefined;
|
||||||
|
googleAnalytics4Id: string | undefined;
|
||||||
rudderstackWriteKey: string | undefined;
|
rudderstackWriteKey: string | undefined;
|
||||||
rudderstackDataPlaneUrl: string | undefined;
|
rudderstackDataPlaneUrl: string | undefined;
|
||||||
rudderstackSdkUrl: string | undefined;
|
rudderstackSdkUrl: string | undefined;
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
};
|
};
|
||||||
googleAnalyticsId: undefined;
|
googleAnalyticsId: undefined;
|
||||||
|
googleAnalytics4Id: undefined;
|
||||||
rudderstackWriteKey: undefined;
|
rudderstackWriteKey: undefined;
|
||||||
rudderstackDataPlaneUrl: undefined;
|
rudderstackDataPlaneUrl: undefined;
|
||||||
rudderstackSdkUrl: undefined;
|
rudderstackSdkUrl: undefined;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type IndexViewData struct {
|
|||||||
AppUrl string
|
AppUrl string
|
||||||
AppSubUrl string
|
AppSubUrl string
|
||||||
GoogleAnalyticsId string
|
GoogleAnalyticsId string
|
||||||
|
GoogleAnalytics4Id string
|
||||||
GoogleTagManagerId string
|
GoogleTagManagerId string
|
||||||
NavTree []*NavLink
|
NavTree []*NavLink
|
||||||
BuildVersion string
|
BuildVersion string
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
|||||||
"profileEnabled": setting.ProfileEnabled,
|
"profileEnabled": setting.ProfileEnabled,
|
||||||
"queryHistoryEnabled": hs.Cfg.QueryHistoryEnabled,
|
"queryHistoryEnabled": hs.Cfg.QueryHistoryEnabled,
|
||||||
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
||||||
|
"googleAnalytics4Id": setting.GoogleAnalytics4Id,
|
||||||
"rudderstackWriteKey": setting.RudderstackWriteKey,
|
"rudderstackWriteKey": setting.RudderstackWriteKey,
|
||||||
"rudderstackDataPlaneUrl": setting.RudderstackDataPlaneUrl,
|
"rudderstackDataPlaneUrl": setting.RudderstackDataPlaneUrl,
|
||||||
"rudderstackSdkUrl": setting.RudderstackSdkUrl,
|
"rudderstackSdkUrl": setting.RudderstackSdkUrl,
|
||||||
|
|||||||
@@ -840,6 +840,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
|
|||||||
AppUrl: appURL,
|
AppUrl: appURL,
|
||||||
AppSubUrl: appSubURL,
|
AppSubUrl: appSubURL,
|
||||||
GoogleAnalyticsId: setting.GoogleAnalyticsId,
|
GoogleAnalyticsId: setting.GoogleAnalyticsId,
|
||||||
|
GoogleAnalytics4Id: setting.GoogleAnalytics4Id,
|
||||||
GoogleTagManagerId: setting.GoogleTagManagerId,
|
GoogleTagManagerId: setting.GoogleTagManagerId,
|
||||||
BuildVersion: setting.BuildVersion,
|
BuildVersion: setting.BuildVersion,
|
||||||
BuildCommit: setting.BuildCommit,
|
BuildCommit: setting.BuildCommit,
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ var (
|
|||||||
|
|
||||||
// analytics
|
// analytics
|
||||||
GoogleAnalyticsId string
|
GoogleAnalyticsId string
|
||||||
|
GoogleAnalytics4Id string
|
||||||
GoogleTagManagerId string
|
GoogleTagManagerId string
|
||||||
RudderstackDataPlaneUrl string
|
RudderstackDataPlaneUrl string
|
||||||
RudderstackWriteKey string
|
RudderstackWriteKey string
|
||||||
@@ -956,6 +957,7 @@ func (cfg *Cfg) Load(args CommandLineArgs) error {
|
|||||||
cfg.CheckForGrafanaUpdates = analytics.Key("check_for_updates").MustBool(true)
|
cfg.CheckForGrafanaUpdates = analytics.Key("check_for_updates").MustBool(true)
|
||||||
cfg.CheckForPluginUpdates = analytics.Key("check_for_plugin_updates").MustBool(true)
|
cfg.CheckForPluginUpdates = analytics.Key("check_for_plugin_updates").MustBool(true)
|
||||||
GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String()
|
GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String()
|
||||||
|
GoogleAnalytics4Id = analytics.Key("google_analytics_4_id").String()
|
||||||
GoogleTagManagerId = analytics.Key("google_tag_manager_id").String()
|
GoogleTagManagerId = analytics.Key("google_tag_manager_id").String()
|
||||||
RudderstackWriteKey = analytics.Key("rudderstack_write_key").String()
|
RudderstackWriteKey = analytics.Key("rudderstack_write_key").String()
|
||||||
RudderstackDataPlaneUrl = analytics.Key("rudderstack_data_plane_url").String()
|
RudderstackDataPlaneUrl = analytics.Key("rudderstack_data_plane_url").String()
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import { Echo } from './core/services/echo/Echo';
|
|||||||
import { reportPerformance } from './core/services/echo/EchoSrv';
|
import { reportPerformance } from './core/services/echo/EchoSrv';
|
||||||
import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend';
|
import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend';
|
||||||
import { ApplicationInsightsBackend } from './core/services/echo/backends/analytics/ApplicationInsightsBackend';
|
import { ApplicationInsightsBackend } from './core/services/echo/backends/analytics/ApplicationInsightsBackend';
|
||||||
|
import { GA4EchoBackend } from './core/services/echo/backends/analytics/GA4Backend';
|
||||||
import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend';
|
import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend';
|
||||||
import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend';
|
import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend';
|
||||||
import { GrafanaJavascriptAgentBackend } from './core/services/echo/backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend';
|
import { GrafanaJavascriptAgentBackend } from './core/services/echo/backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend';
|
||||||
@@ -256,6 +257,14 @@ function initEchoSrv() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.googleAnalytics4Id) {
|
||||||
|
registerEchoBackend(
|
||||||
|
new GA4EchoBackend({
|
||||||
|
googleAnalyticsId: config.googleAnalytics4Id,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (config.rudderstackWriteKey && config.rudderstackDataPlaneUrl) {
|
if (config.rudderstackWriteKey && config.rudderstackDataPlaneUrl) {
|
||||||
registerEchoBackend(
|
registerEchoBackend(
|
||||||
new RudderstackBackend({
|
new RudderstackBackend({
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
import { CurrentUserDTO } from '@grafana/data';
|
||||||
|
import { EchoBackend, EchoEventType, PageviewEchoEvent } from '@grafana/runtime';
|
||||||
|
|
||||||
|
import { getUserIdentifier } from '../../utils';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
dataLayer: unknown[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GA4EchoBackendOptions {
|
||||||
|
googleAnalyticsId: string;
|
||||||
|
user?: CurrentUserDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GA4EchoBackend implements EchoBackend<PageviewEchoEvent, GA4EchoBackendOptions> {
|
||||||
|
supportedEvents = [EchoEventType.Pageview];
|
||||||
|
trackedUserId: number | null = null;
|
||||||
|
|
||||||
|
constructor(public options: GA4EchoBackendOptions) {
|
||||||
|
const url = `https://www.googletagmanager.com/gtag/js?id=${options.googleAnalyticsId}`;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url,
|
||||||
|
dataType: 'script',
|
||||||
|
cache: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
window.gtag = function gtag() {
|
||||||
|
window.dataLayer.push(arguments);
|
||||||
|
};
|
||||||
|
window.gtag('js', new Date());
|
||||||
|
|
||||||
|
const configOptions: Gtag.CustomParams = {};
|
||||||
|
|
||||||
|
if (options.user) {
|
||||||
|
configOptions.user_id = getUserIdentifier(options.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.gtag('config', options.googleAnalyticsId, configOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvent = (e: PageviewEchoEvent) => {
|
||||||
|
if (!window.gtag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.gtag('set', 'page_path', e.payload.page);
|
||||||
|
window.gtag('event', 'page_view');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Not using Echo buffering, addEvent above sends events to GA as soon as they appear
|
||||||
|
flush = () => {};
|
||||||
|
}
|
||||||
@@ -11570,6 +11570,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/gtag.js@npm:^0.0.11":
|
||||||
|
version: 0.0.11
|
||||||
|
resolution: "@types/gtag.js@npm:0.0.11"
|
||||||
|
checksum: fe3f0550f609a903fd23b2b7eae2771ad6c9f314c7458320759e8e328b2c148b7d3bff0462d05e3ffe6e800dbd4dfacf174cbeb29796b31813a8bb2fbecca1cc
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/hast@npm:^2.0.0":
|
"@types/hast@npm:^2.0.0":
|
||||||
version: 2.3.4
|
version: 2.3.4
|
||||||
resolution: "@types/hast@npm:2.3.4"
|
resolution: "@types/hast@npm:2.3.4"
|
||||||
@@ -22224,6 +22231,7 @@ __metadata:
|
|||||||
"@types/eslint": 8.4.5
|
"@types/eslint": 8.4.5
|
||||||
"@types/file-saver": 2.0.5
|
"@types/file-saver": 2.0.5
|
||||||
"@types/google.analytics": ^0.0.42
|
"@types/google.analytics": ^0.0.42
|
||||||
|
"@types/gtag.js": ^0.0.11
|
||||||
"@types/history": 4.7.11
|
"@types/history": 4.7.11
|
||||||
"@types/hoist-non-react-statics": 3.3.1
|
"@types/hoist-non-react-statics": 3.3.1
|
||||||
"@types/jest": 28.1.6
|
"@types/jest": 28.1.6
|
||||||
|
|||||||
Reference in New Issue
Block a user