mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
fix: Faro usage issue (#80033)
This commit is contained in:
parent
fbd0ceec7c
commit
329ec2624a
@ -1,12 +1,11 @@
|
||||
import { BuildInfo } from '@grafana/data';
|
||||
import { GrafanaEdition } from '@grafana/data/src/types/config';
|
||||
import { BaseTransport, Instrumentation, InternalLoggerLevel } from '@grafana/faro-core';
|
||||
import { Instrumentation } from '@grafana/faro-core';
|
||||
import * as faroWebSdkModule from '@grafana/faro-web-sdk';
|
||||
import { FetchTransport, initializeFaro } from '@grafana/faro-web-sdk';
|
||||
import { EchoEventType, EchoMeta } from '@grafana/runtime';
|
||||
|
||||
import { EchoSrvTransport } from './EchoSrvTransport';
|
||||
import { GrafanaJavascriptAgentBackend, GrafanaJavascriptAgentBackendOptions } from './GrafanaJavascriptAgentBackend';
|
||||
import { GrafanaJavascriptAgentEchoEvent } from './types';
|
||||
|
||||
describe('GrafanaJavascriptAgentEchoBackend', () => {
|
||||
beforeEach(() => {
|
||||
@ -44,20 +43,16 @@ describe('GrafanaJavascriptAgentEchoBackend', () => {
|
||||
|
||||
it('will set up FetchTransport if customEndpoint is provided', () => {
|
||||
// arrange
|
||||
jest.spyOn(faroWebSdkModule, 'initializeFaro').mockReturnValueOnce({
|
||||
...faroWebSdkModule.faro,
|
||||
api: {
|
||||
...faroWebSdkModule.faro.api,
|
||||
setUser: jest.fn(),
|
||||
},
|
||||
});
|
||||
const constructorSpy = jest.spyOn(faroWebSdkModule, 'FetchTransport');
|
||||
|
||||
//act
|
||||
const backend = new GrafanaJavascriptAgentBackend(options);
|
||||
new GrafanaJavascriptAgentBackend(options);
|
||||
|
||||
//assert
|
||||
expect(backend.transports.length).toEqual(1);
|
||||
expect(backend.transports[0]).toBeInstanceOf(FetchTransport);
|
||||
expect(constructorSpy).toHaveBeenCalledTimes(1);
|
||||
expect(faroWebSdkModule.faro.transports.transports.length).toEqual(2);
|
||||
expect(faroWebSdkModule.faro.transports.transports[0]).toBeInstanceOf(EchoSrvTransport);
|
||||
expect(faroWebSdkModule.faro.transports.transports[1]).toBeInstanceOf(FetchTransport);
|
||||
});
|
||||
|
||||
it('will initialize GrafanaJavascriptAgent and set user', () => {
|
||||
@ -76,71 +71,20 @@ describe('GrafanaJavascriptAgentEchoBackend', () => {
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
};
|
||||
const mockedAgent = () => {
|
||||
return {
|
||||
api: {
|
||||
setUser: mockedSetUser,
|
||||
pushLog: jest.fn(),
|
||||
callOriginalConsoleMethod: jest.fn(),
|
||||
pushError: jest.fn(),
|
||||
pushMeasurement: jest.fn(),
|
||||
pushTraces: jest.fn(),
|
||||
pushEvent: jest.fn(),
|
||||
initOTEL: jest.fn(),
|
||||
getOTEL: jest.fn(),
|
||||
getTraceContext: jest.fn(),
|
||||
changeStacktraceParser: jest.fn(),
|
||||
getStacktraceParser: jest.fn(),
|
||||
isOTELInitialized: jest.fn(),
|
||||
setSession: jest.fn(),
|
||||
getSession: jest.fn(),
|
||||
resetUser: jest.fn(),
|
||||
resetSession: jest.fn(),
|
||||
setView: jest.fn(),
|
||||
getView: jest.fn(),
|
||||
},
|
||||
config: {
|
||||
globalObjectKey: '',
|
||||
preventGlobalExposure: false,
|
||||
transports: [],
|
||||
instrumentations: mockedInstrumentationsForConfig,
|
||||
metas: [],
|
||||
parseStacktrace: jest.fn(),
|
||||
app: jest.fn(),
|
||||
paused: false,
|
||||
dedupe: true,
|
||||
isolate: false,
|
||||
internalLoggerLevel: InternalLoggerLevel.ERROR,
|
||||
unpatchedConsole: { ...console },
|
||||
},
|
||||
metas: {
|
||||
add: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
value: {},
|
||||
addListener: jest.fn(),
|
||||
removeListener: jest.fn(),
|
||||
},
|
||||
transports: {
|
||||
add: jest.fn(),
|
||||
execute: jest.fn(),
|
||||
transports: [],
|
||||
pause: jest.fn(),
|
||||
unpause: jest.fn(),
|
||||
addBeforeSendHooks: jest.fn(),
|
||||
addIgnoreErrorsPatterns: jest.fn(),
|
||||
getBeforeSendHooks: jest.fn(),
|
||||
isPaused: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
removeBeforeSendHooks: jest.fn(),
|
||||
},
|
||||
pause: jest.fn(),
|
||||
unpause: jest.fn(),
|
||||
instrumentations: mockedInstrumentations,
|
||||
internalLogger: mockedInternalLogger,
|
||||
unpatchedConsole: { ...console },
|
||||
};
|
||||
};
|
||||
jest.mocked(initializeFaro).mockImplementation(mockedAgent);
|
||||
|
||||
jest.spyOn(faroWebSdkModule, 'initializeFaro').mockReturnValueOnce({
|
||||
...faroWebSdkModule.faro,
|
||||
api: {
|
||||
...faroWebSdkModule.faro.api,
|
||||
setUser: mockedSetUser,
|
||||
},
|
||||
config: {
|
||||
...faroWebSdkModule.faro.config,
|
||||
instrumentations: mockedInstrumentationsForConfig,
|
||||
},
|
||||
instrumentations: mockedInstrumentations,
|
||||
internalLogger: mockedInternalLogger,
|
||||
});
|
||||
|
||||
//act
|
||||
new GrafanaJavascriptAgentBackend(options);
|
||||
@ -156,111 +100,6 @@ describe('GrafanaJavascriptAgentEchoBackend', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('will forward events to transports', () => {
|
||||
//arrange
|
||||
const mockedSetUser = jest.fn();
|
||||
const mockedInstrumentationsForConfig: Instrumentation[] = [];
|
||||
const mockedInstrumentations = {
|
||||
add: jest.fn(),
|
||||
instrumentations: mockedInstrumentationsForConfig,
|
||||
remove: jest.fn(),
|
||||
};
|
||||
const mockedInternalLogger = {
|
||||
prefix: 'Faro',
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
};
|
||||
const mockedAgent = () => {
|
||||
return {
|
||||
api: {
|
||||
setUser: mockedSetUser,
|
||||
pushLog: jest.fn(),
|
||||
callOriginalConsoleMethod: jest.fn(),
|
||||
pushError: jest.fn(),
|
||||
pushMeasurement: jest.fn(),
|
||||
pushTraces: jest.fn(),
|
||||
pushEvent: jest.fn(),
|
||||
initOTEL: jest.fn(),
|
||||
getOTEL: jest.fn(),
|
||||
getTraceContext: jest.fn(),
|
||||
changeStacktraceParser: jest.fn(),
|
||||
getStacktraceParser: jest.fn(),
|
||||
isOTELInitialized: jest.fn(),
|
||||
setSession: jest.fn(),
|
||||
getSession: jest.fn(),
|
||||
resetUser: jest.fn(),
|
||||
resetSession: jest.fn(),
|
||||
setView: jest.fn(),
|
||||
getView: jest.fn(),
|
||||
},
|
||||
config: {
|
||||
globalObjectKey: '',
|
||||
preventGlobalExposure: false,
|
||||
transports: [],
|
||||
instrumentations: mockedInstrumentationsForConfig,
|
||||
metas: [],
|
||||
parseStacktrace: jest.fn(),
|
||||
app: jest.fn(),
|
||||
paused: false,
|
||||
dedupe: true,
|
||||
isolate: false,
|
||||
internalLoggerLevel: InternalLoggerLevel.ERROR,
|
||||
unpatchedConsole: { ...console },
|
||||
},
|
||||
metas: {
|
||||
add: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
value: {},
|
||||
addListener: jest.fn(),
|
||||
removeListener: jest.fn(),
|
||||
},
|
||||
transports: {
|
||||
add: jest.fn(),
|
||||
execute: jest.fn(),
|
||||
transports: [],
|
||||
pause: jest.fn(),
|
||||
unpause: jest.fn(),
|
||||
addBeforeSendHooks: jest.fn(),
|
||||
addIgnoreErrorsPatterns: jest.fn(),
|
||||
getBeforeSendHooks: jest.fn(),
|
||||
isPaused: jest.fn(),
|
||||
remove: jest.fn(),
|
||||
removeBeforeSendHooks: jest.fn(),
|
||||
},
|
||||
pause: jest.fn(),
|
||||
unpause: jest.fn(),
|
||||
instrumentations: mockedInstrumentations,
|
||||
internalLogger: mockedInternalLogger,
|
||||
unpatchedConsole: { ...console },
|
||||
};
|
||||
};
|
||||
|
||||
jest.mocked(initializeFaro).mockImplementation(mockedAgent);
|
||||
const backend = new GrafanaJavascriptAgentBackend({
|
||||
...options,
|
||||
preventGlobalExposure: true,
|
||||
});
|
||||
|
||||
backend.transports = [
|
||||
/* eslint-disable */
|
||||
{ send: jest.fn() } as unknown as BaseTransport,
|
||||
{ send: jest.fn() } as unknown as BaseTransport,
|
||||
];
|
||||
const event: GrafanaJavascriptAgentEchoEvent = {
|
||||
type: EchoEventType.GrafanaJavascriptAgent,
|
||||
payload: { foo: 'bar' } as unknown as GrafanaJavascriptAgentEchoEvent,
|
||||
meta: {} as unknown as EchoMeta,
|
||||
};
|
||||
/* eslint-enable */
|
||||
backend.addEvent(event);
|
||||
backend.transports.forEach((transport) => {
|
||||
expect(transport.send).toHaveBeenCalledTimes(1);
|
||||
expect(transport.send).toHaveBeenCalledWith(event.payload);
|
||||
});
|
||||
});
|
||||
|
||||
//@FIXME - make integration test work
|
||||
|
||||
// it('integration test with EchoSrv and GrafanaJavascriptAgent', async () => {
|
||||
|
@ -29,16 +29,15 @@ export class GrafanaJavascriptAgentBackend
|
||||
{
|
||||
supportedEvents = [EchoEventType.GrafanaJavascriptAgent];
|
||||
private faroInstance;
|
||||
transports: BaseTransport[];
|
||||
|
||||
constructor(public options: GrafanaJavascriptAgentBackendOptions) {
|
||||
// configure instrumentations.
|
||||
const instrumentations: Instrumentation[] = [];
|
||||
|
||||
this.transports = [];
|
||||
const transports: BaseTransport[] = [new EchoSrvTransport()];
|
||||
|
||||
if (options.customEndpoint) {
|
||||
this.transports.push(new FetchTransport({ url: options.customEndpoint, apiKey: options.apiKey }));
|
||||
transports.push(new FetchTransport({ url: options.customEndpoint, apiKey: options.apiKey }));
|
||||
}
|
||||
|
||||
if (options.errorInstrumentalizationEnabled) {
|
||||
@ -63,7 +62,7 @@ export class GrafanaJavascriptAgentBackend
|
||||
environment: options.buildInfo.env,
|
||||
},
|
||||
instrumentations,
|
||||
transports: [new EchoSrvTransport()],
|
||||
transports,
|
||||
ignoreErrors: [
|
||||
'ResizeObserver loop limit exceeded',
|
||||
'ResizeObserver loop completed',
|
||||
@ -71,9 +70,6 @@ export class GrafanaJavascriptAgentBackend
|
||||
],
|
||||
sessionTracking: {
|
||||
persistent: true,
|
||||
generateSessionId() {
|
||||
return (Math.random() + 1).toString(36).substring(2);
|
||||
},
|
||||
},
|
||||
batching: {
|
||||
sendTimeout: 1000,
|
||||
@ -91,9 +87,8 @@ export class GrafanaJavascriptAgentBackend
|
||||
}
|
||||
}
|
||||
|
||||
addEvent = (e: EchoEvent) => {
|
||||
this.transports.forEach((t) => t.send(e.payload));
|
||||
};
|
||||
// noop because the EchoSrvTransport registered in Faro will already broadcast all signals emitted by the Faro API
|
||||
addEvent = (e: EchoEvent) => {};
|
||||
|
||||
// backend will log events to stdout, and at least in case of hosted grafana they will be
|
||||
// ingested into Loki. Due to Loki limitations logs cannot be backdated,
|
||||
|
Loading…
Reference in New Issue
Block a user