mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
663a8935f7
* Replace analytics service with Echo backend * Add Rudderstack integration and general pageview and interaction Echo events * Update conf/defaults.ini Co-authored-by: Dan Cech <dcech@grafana.com> * Update packages/grafana-runtime/src/types/analytics.ts Co-authored-by: Dan Cech <dcech@grafana.com> * Update conf/defaults.ini Co-authored-by: Dan Cech <dcech@grafana.com> * Update tests * Force cla check Co-authored-by: Dan Cech <dcech@grafana.com>
193 lines
6.5 KiB
TypeScript
193 lines
6.5 KiB
TypeScript
import 'symbol-observable';
|
|
import 'core-js';
|
|
import 'regenerator-runtime/runtime';
|
|
|
|
import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering
|
|
import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'; // fetch polyfill needed for PhantomJs rendering
|
|
import './polyfills/old-mediaquerylist'; // Safari < 14 does not have mql.addEventListener()
|
|
import 'file-saver';
|
|
import 'jquery';
|
|
|
|
// eslint-disable-next-line lodash/import-scope
|
|
import _ from 'lodash';
|
|
import ReactDOM from 'react-dom';
|
|
import React from 'react';
|
|
import config from 'app/core/config';
|
|
// @ts-ignore ignoring this for now, otherwise we would have to extend _ interface with move
|
|
import {
|
|
locationUtil,
|
|
monacoLanguageRegistry,
|
|
setLocale,
|
|
setTimeZoneResolver,
|
|
standardEditorsRegistry,
|
|
standardFieldConfigEditorRegistry,
|
|
standardTransformersRegistry,
|
|
} from '@grafana/data';
|
|
import { arrayMove } from 'app/core/utils/arrayMove';
|
|
import { importPluginModule } from 'app/features/plugins/plugin_loader';
|
|
import { registerEchoBackend, setEchoSrv, setPanelRenderer, setQueryRunnerFactory } from '@grafana/runtime';
|
|
import { Echo } from './core/services/echo/Echo';
|
|
import { reportPerformance } from './core/services/echo/EchoSrv';
|
|
import { PerformanceBackend } from './core/services/echo/backends/PerformanceBackend';
|
|
import 'app/routes/GrafanaCtrl';
|
|
import 'app/features/all';
|
|
import { getScrollbarWidth, getStandardFieldConfigs, getStandardOptionEditors } from '@grafana/ui';
|
|
import { getDefaultVariableAdapters, variableAdapters } from './features/variables/adapters';
|
|
import { initDevFeatures } from './dev';
|
|
import { getStandardTransformers } from 'app/core/utils/standardTransformers';
|
|
import { SentryEchoBackend } from './core/services/echo/backends/sentry/SentryBackend';
|
|
import { setVariableQueryRunner, VariableQueryRunner } from './features/variables/query/VariableQueryRunner';
|
|
import { configureStore } from './store/configureStore';
|
|
import { AppWrapper } from './AppWrapper';
|
|
import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks';
|
|
import { AngularApp } from './angular/AngularApp';
|
|
import { PanelRenderer } from './features/panel/PanelRenderer';
|
|
import { QueryRunner } from './features/query/state/QueryRunner';
|
|
import { getTimeSrv } from './features/dashboard/services/TimeSrv';
|
|
import { getVariablesUrlParams } from './features/variables/getAllVariableValuesForUrl';
|
|
import getDefaultMonacoLanguages from '../lib/monaco-languages';
|
|
import { contextSrv } from './core/services/context_srv';
|
|
import { GAEchoBackend } from './core/services/echo/backends/analytics/GABackend';
|
|
import { RudderstackBackend } from './core/services/echo/backends/analytics/RudderstackBackend';
|
|
|
|
// add move to lodash for backward compatabilty with plugins
|
|
// @ts-ignore
|
|
_.move = arrayMove;
|
|
|
|
// import symlinked extensions
|
|
const extensionsIndex = (require as any).context('.', true, /extensions\/index.ts/);
|
|
const extensionsExports = extensionsIndex.keys().map((key: any) => {
|
|
return extensionsIndex(key);
|
|
});
|
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
initDevFeatures();
|
|
}
|
|
|
|
export class GrafanaApp {
|
|
angularApp: AngularApp;
|
|
|
|
constructor() {
|
|
this.angularApp = new AngularApp();
|
|
}
|
|
|
|
init() {
|
|
initEchoSrv();
|
|
addClassIfNoOverlayScrollbar();
|
|
setLocale(config.bootData.user.locale);
|
|
setPanelRenderer(PanelRenderer);
|
|
setTimeZoneResolver(() => config.bootData.user.timezone);
|
|
// Important that extensions are initialized before store
|
|
initExtensions();
|
|
configureStore();
|
|
|
|
standardEditorsRegistry.setInit(getStandardOptionEditors);
|
|
standardFieldConfigEditorRegistry.setInit(getStandardFieldConfigs);
|
|
standardTransformersRegistry.setInit(getStandardTransformers);
|
|
variableAdapters.setInit(getDefaultVariableAdapters);
|
|
monacoLanguageRegistry.setInit(getDefaultMonacoLanguages);
|
|
|
|
setQueryRunnerFactory(() => new QueryRunner());
|
|
setVariableQueryRunner(new VariableQueryRunner());
|
|
|
|
locationUtil.initialize({
|
|
config,
|
|
getTimeRangeForUrl: getTimeSrv().timeRangeForUrl,
|
|
getVariablesUrlParams: getVariablesUrlParams,
|
|
});
|
|
|
|
// intercept anchor clicks and forward it to custom history instead of relying on browser's history
|
|
document.addEventListener('click', interceptLinkClicks);
|
|
|
|
// disable tool tip animation
|
|
$.fn.tooltip.defaults.animation = false;
|
|
|
|
this.angularApp.init();
|
|
|
|
// Preload selected app plugins
|
|
const promises = [];
|
|
for (const modulePath of config.pluginsToPreload) {
|
|
promises.push(importPluginModule(modulePath));
|
|
}
|
|
|
|
Promise.all(promises).then(() => {
|
|
ReactDOM.render(
|
|
React.createElement(AppWrapper, {
|
|
app: this,
|
|
}),
|
|
document.getElementById('reactRoot')
|
|
);
|
|
});
|
|
}
|
|
}
|
|
|
|
function initExtensions() {
|
|
if (extensionsExports.length > 0) {
|
|
extensionsExports[0].init();
|
|
}
|
|
}
|
|
|
|
function initEchoSrv() {
|
|
setEchoSrv(new Echo({ debug: process.env.NODE_ENV === 'development' }));
|
|
|
|
window.addEventListener('load', (e) => {
|
|
const loadMetricName = 'frontend_boot_load_time_seconds';
|
|
|
|
if (performance && performance.getEntriesByType) {
|
|
performance.mark(loadMetricName);
|
|
|
|
const paintMetrics = performance.getEntriesByType('paint');
|
|
|
|
for (const metric of paintMetrics) {
|
|
reportPerformance(
|
|
`frontend_boot_${metric.name}_time_seconds`,
|
|
Math.round(metric.startTime + metric.duration) / 1000
|
|
);
|
|
}
|
|
|
|
const loadMetric = performance.getEntriesByName(loadMetricName)[0];
|
|
reportPerformance(loadMetric.name, Math.round(loadMetric.startTime + loadMetric.duration) / 1000);
|
|
}
|
|
});
|
|
|
|
if (contextSrv.user.orgRole !== '') {
|
|
registerEchoBackend(new PerformanceBackend({}));
|
|
}
|
|
|
|
if (config.sentry.enabled) {
|
|
registerEchoBackend(
|
|
new SentryEchoBackend({
|
|
...config.sentry,
|
|
user: config.bootData.user,
|
|
buildInfo: config.buildInfo,
|
|
})
|
|
);
|
|
}
|
|
|
|
if ((config as any).googleAnalyticsId) {
|
|
registerEchoBackend(
|
|
new GAEchoBackend({
|
|
googleAnalyticsId: (config as any).googleAnalyticsId,
|
|
})
|
|
);
|
|
}
|
|
|
|
if ((config as any).rudderstackWriteKey && (config as any).rudderstackDataPlaneUrl) {
|
|
registerEchoBackend(
|
|
new RudderstackBackend({
|
|
writeKey: (config as any).rudderstackWriteKey,
|
|
dataPlaneUrl: (config as any).rudderstackDataPlaneUrl,
|
|
user: config.bootData.user,
|
|
})
|
|
);
|
|
}
|
|
}
|
|
|
|
function addClassIfNoOverlayScrollbar() {
|
|
if (getScrollbarWidth() > 0) {
|
|
document.body.classList.add('no-overlay-scrollbar');
|
|
}
|
|
}
|
|
|
|
export default new GrafanaApp();
|