mirror of https://github.com/grafana/grafana.git
EchoSrv: Guard backend initialisation with try/catch (#111612)
* EchoSrv: Guard backend initialisation with try/catch * remove test exception
This commit is contained in:
parent
dab39c873f
commit
e426b1d9d9
|
|
@ -23,10 +23,8 @@ import { DEFAULT_LANGUAGE } from '@grafana/i18n';
|
|||
import { initializeI18n, loadNamespacedResources } from '@grafana/i18n/internal';
|
||||
import {
|
||||
locationService,
|
||||
registerEchoBackend,
|
||||
setBackendSrv,
|
||||
setDataSourceSrv,
|
||||
setEchoSrv,
|
||||
setLocationSrv,
|
||||
setQueryRunnerFactory,
|
||||
setRunRequest,
|
||||
|
|
@ -79,8 +77,7 @@ import { CorrelationsService } from './core/services/CorrelationsService';
|
|||
import { NewFrontendAssetsChecker } from './core/services/NewFrontendAssetsChecker';
|
||||
import { backendSrv } from './core/services/backend_srv';
|
||||
import { contextSrv, RedirectToUrlKey } from './core/services/context_srv';
|
||||
import { Echo } from './core/services/echo/Echo';
|
||||
import { reportPerformance } from './core/services/echo/EchoSrv';
|
||||
import { initEchoSrv } from './core/services/echo/init';
|
||||
import { KeybindingSrv } from './core/services/keybindingSrv';
|
||||
import { startMeasure, stopMeasure } from './core/utils/metrics';
|
||||
import { initAlerting } from './features/alerting/unified/initAlerting';
|
||||
|
|
@ -325,125 +322,6 @@ function initExtensions() {
|
|||
}
|
||||
}
|
||||
|
||||
async function initEchoSrv() {
|
||||
setEchoSrv(new Echo({ debug: process.env.NODE_ENV === 'development' }));
|
||||
|
||||
window.addEventListener('load', (e) => {
|
||||
const loadMetricName = 'frontend_boot_load_time_seconds';
|
||||
// Metrics below are marked in public/views/index.html
|
||||
const jsLoadMetricName = 'frontend_boot_js_done_time_seconds';
|
||||
const cssLoadMetricName = 'frontend_boot_css_time_seconds';
|
||||
|
||||
if (performance) {
|
||||
performance.mark(loadMetricName);
|
||||
reportMetricPerformanceMark('first-paint', 'frontend_boot_', '_time_seconds');
|
||||
reportMetricPerformanceMark('first-contentful-paint', 'frontend_boot_', '_time_seconds');
|
||||
reportMetricPerformanceMark(loadMetricName);
|
||||
reportMetricPerformanceMark(jsLoadMetricName);
|
||||
reportMetricPerformanceMark(cssLoadMetricName);
|
||||
}
|
||||
});
|
||||
|
||||
if (contextSrv.user.orgRole !== '') {
|
||||
const { PerformanceBackend } = await import('./core/services/echo/backends/PerformanceBackend');
|
||||
registerEchoBackend(new PerformanceBackend({}));
|
||||
}
|
||||
|
||||
if (config.grafanaJavascriptAgent.enabled) {
|
||||
// Ignore Rudderstack URLs
|
||||
const rudderstackUrls = [
|
||||
config.rudderstackConfigUrl,
|
||||
config.rudderstackDataPlaneUrl,
|
||||
config.rudderstackIntegrationsUrl,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.map((url) => new RegExp(`${url}.*.`));
|
||||
|
||||
const { GrafanaJavascriptAgentBackend } = await import(
|
||||
'./core/services/echo/backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend'
|
||||
);
|
||||
|
||||
registerEchoBackend(
|
||||
new GrafanaJavascriptAgentBackend({
|
||||
...config.grafanaJavascriptAgent,
|
||||
app: {
|
||||
version: config.buildInfo.version,
|
||||
environment: config.buildInfo.env,
|
||||
},
|
||||
buildInfo: config.buildInfo,
|
||||
user: {
|
||||
id: String(contextSrv.user?.id),
|
||||
email: contextSrv.user?.email,
|
||||
},
|
||||
ignoreUrls: rudderstackUrls,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (config.googleAnalyticsId) {
|
||||
const { GAEchoBackend } = await import('./core/services/echo/backends/analytics/GABackend');
|
||||
registerEchoBackend(
|
||||
new GAEchoBackend({
|
||||
googleAnalyticsId: config.googleAnalyticsId,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (config.googleAnalytics4Id) {
|
||||
const { GA4EchoBackend } = await import('./core/services/echo/backends/analytics/GA4Backend');
|
||||
registerEchoBackend(
|
||||
new GA4EchoBackend({
|
||||
googleAnalyticsId: config.googleAnalytics4Id,
|
||||
googleAnalytics4SendManualPageViews: config.googleAnalytics4SendManualPageViews,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (config.rudderstackWriteKey && config.rudderstackDataPlaneUrl) {
|
||||
const { RudderstackBackend } = await import('./core/services/echo/backends/analytics/RudderstackBackend');
|
||||
registerEchoBackend(
|
||||
new RudderstackBackend({
|
||||
writeKey: config.rudderstackWriteKey,
|
||||
dataPlaneUrl: config.rudderstackDataPlaneUrl,
|
||||
user: contextSrv.user,
|
||||
sdkUrl: config.rudderstackSdkUrl,
|
||||
configUrl: config.rudderstackConfigUrl,
|
||||
integrationsUrl: config.rudderstackIntegrationsUrl,
|
||||
buildInfo: config.buildInfo,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (config.applicationInsightsConnectionString) {
|
||||
const { ApplicationInsightsBackend } = await import(
|
||||
'./core/services/echo/backends/analytics/ApplicationInsightsBackend'
|
||||
);
|
||||
registerEchoBackend(
|
||||
new ApplicationInsightsBackend({
|
||||
connectionString: config.applicationInsightsConnectionString,
|
||||
endpointUrl: config.applicationInsightsEndpointUrl,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (config.analyticsConsoleReporting) {
|
||||
const { BrowserConsoleBackend } = await import('./core/services/echo/backends/analytics/BrowseConsoleBackend');
|
||||
registerEchoBackend(new BrowserConsoleBackend());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report when a metric of a given name was marked during the document lifecycle. Works for markers with no duration,
|
||||
* like PerformanceMark or PerformancePaintTiming (e.g. created with performance.mark, or first-contentful-paint)
|
||||
*/
|
||||
function reportMetricPerformanceMark(metricName: string, prefix = '', suffix = ''): void {
|
||||
const metric = performance.getEntriesByName(metricName).at(0);
|
||||
if (metric) {
|
||||
const metricName = metric.name.replace(/-/g, '_');
|
||||
reportPerformance(`${prefix}${metricName}${suffix}`, Math.round(metric.startTime) / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function handleRedirectTo(): void {
|
||||
const queryParams = locationService.getSearch();
|
||||
const redirectToParamKey = 'redirectTo';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
import { config, registerEchoBackend, setEchoSrv } from '@grafana/runtime';
|
||||
import { reportMetricPerformanceMark } from 'app/core/utils/metrics';
|
||||
|
||||
import { contextSrv } from '../context_srv';
|
||||
|
||||
import { Echo } from './Echo';
|
||||
|
||||
// Initialise EchoSrv backends, calls during frontend app startup
|
||||
export async function initEchoSrv() {
|
||||
setEchoSrv(new Echo({ debug: process.env.NODE_ENV === 'development' }));
|
||||
|
||||
window.addEventListener('load', (e) => {
|
||||
const loadMetricName = 'frontend_boot_load_time_seconds';
|
||||
// Metrics below are marked in public/views/index.html
|
||||
const jsLoadMetricName = 'frontend_boot_js_done_time_seconds';
|
||||
const cssLoadMetricName = 'frontend_boot_css_time_seconds';
|
||||
|
||||
if (performance) {
|
||||
performance.mark(loadMetricName);
|
||||
reportMetricPerformanceMark('first-paint', 'frontend_boot_', '_time_seconds');
|
||||
reportMetricPerformanceMark('first-contentful-paint', 'frontend_boot_', '_time_seconds');
|
||||
reportMetricPerformanceMark(loadMetricName);
|
||||
reportMetricPerformanceMark(jsLoadMetricName);
|
||||
reportMetricPerformanceMark(cssLoadMetricName);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await initPerformanceBackend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv Performance backend', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await initFaroBackend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv Faro backend', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await initGoogleAnalyticsBackend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv GoogleAnalytics backend', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await initGoogleAnalaytics4Backend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv GoogleAnalaytics4 backend', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await initRudderstackBackend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv Rudderstack backend', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await initAzureAppInsightsBackend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv AzureAppInsights backend', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await initConsoleBackend();
|
||||
} catch (error) {
|
||||
console.error('Error initializing EchoSrv Console backend', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function initPerformanceBackend() {
|
||||
if (contextSrv.user.orgRole === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
const { PerformanceBackend } = await import('./backends/PerformanceBackend');
|
||||
registerEchoBackend(new PerformanceBackend({}));
|
||||
}
|
||||
|
||||
async function initFaroBackend() {
|
||||
if (!config.grafanaJavascriptAgent.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore Rudderstack URLs
|
||||
const rudderstackUrls = [
|
||||
config.rudderstackConfigUrl,
|
||||
config.rudderstackDataPlaneUrl,
|
||||
config.rudderstackIntegrationsUrl,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.map((url) => new RegExp(`${url}.*.`));
|
||||
|
||||
const { GrafanaJavascriptAgentBackend } = await import(
|
||||
'./backends/grafana-javascript-agent/GrafanaJavascriptAgentBackend'
|
||||
);
|
||||
|
||||
registerEchoBackend(
|
||||
new GrafanaJavascriptAgentBackend({
|
||||
...config.grafanaJavascriptAgent,
|
||||
app: {
|
||||
version: config.buildInfo.version,
|
||||
environment: config.buildInfo.env,
|
||||
},
|
||||
buildInfo: config.buildInfo,
|
||||
user: {
|
||||
id: String(contextSrv.user?.id),
|
||||
email: contextSrv.user?.email,
|
||||
},
|
||||
ignoreUrls: rudderstackUrls,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function initGoogleAnalyticsBackend() {
|
||||
if (!config.googleAnalyticsId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { GAEchoBackend } = await import('./backends/analytics/GABackend');
|
||||
registerEchoBackend(
|
||||
new GAEchoBackend({
|
||||
googleAnalyticsId: config.googleAnalyticsId,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function initGoogleAnalaytics4Backend() {
|
||||
if (!config.googleAnalytics4Id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { GA4EchoBackend } = await import('./backends/analytics/GA4Backend');
|
||||
registerEchoBackend(
|
||||
new GA4EchoBackend({
|
||||
googleAnalyticsId: config.googleAnalytics4Id,
|
||||
googleAnalytics4SendManualPageViews: config.googleAnalytics4SendManualPageViews,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function initRudderstackBackend() {
|
||||
if (!(config.rudderstackWriteKey && config.rudderstackDataPlaneUrl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { RudderstackBackend } = await import('./backends/analytics/RudderstackBackend');
|
||||
registerEchoBackend(
|
||||
new RudderstackBackend({
|
||||
writeKey: config.rudderstackWriteKey,
|
||||
dataPlaneUrl: config.rudderstackDataPlaneUrl,
|
||||
user: contextSrv.user,
|
||||
sdkUrl: config.rudderstackSdkUrl,
|
||||
configUrl: config.rudderstackConfigUrl,
|
||||
integrationsUrl: config.rudderstackIntegrationsUrl,
|
||||
buildInfo: config.buildInfo,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function initAzureAppInsightsBackend() {
|
||||
if (!config.applicationInsightsConnectionString) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { ApplicationInsightsBackend } = await import('./backends/analytics/ApplicationInsightsBackend');
|
||||
registerEchoBackend(
|
||||
new ApplicationInsightsBackend({
|
||||
connectionString: config.applicationInsightsConnectionString,
|
||||
endpointUrl: config.applicationInsightsEndpointUrl,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function initConsoleBackend() {
|
||||
if (!config.analyticsConsoleReporting) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { BrowserConsoleBackend } = await import('./backends/analytics/BrowseConsoleBackend');
|
||||
registerEchoBackend(new BrowserConsoleBackend());
|
||||
}
|
||||
|
|
@ -35,3 +35,15 @@ export function stopMeasure(eventName: string) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report when a metric of a given name was marked during the document lifecycle. Works for markers with no duration,
|
||||
* like PerformanceMark or PerformancePaintTiming (e.g. created with performance.mark, or first-contentful-paint)
|
||||
*/
|
||||
export function reportMetricPerformanceMark(metricName: string, prefix = '', suffix = ''): void {
|
||||
const metric = performance.getEntriesByName(metricName).at(0);
|
||||
if (metric) {
|
||||
const metricName = metric.name.replace(/-/g, '_');
|
||||
reportPerformance(`${prefix}${metricName}${suffix}`, Math.round(metric.startTime) / 1000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue