Skip to content

Commit

Permalink
Faro - Point to 3 separate apps instead of just 1 for all environments (
Browse files Browse the repository at this point in the history
#1110)

# What this PR does

- App will now send traces to either of the Faro configured apps:
`grafana-oncall-dev`, `grafana-oncall-ops` or `grafana-oncall-prod`
instead of just `grafana-oncall` for all of 3.
- Added tests to reflect latest changes
  • Loading branch information
teodosii authored Jan 10, 2023
1 parent d09bfa2 commit 5cc07b9
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 119 deletions.
16 changes: 16 additions & 0 deletions src/utils/consts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import plugin from '../../package.json'; // eslint-disable-line

// Navbar
export const APP_TITLE = 'Grafana OnCall';
export const APP_SUBTITLE = `Developer-friendly incident response (${plugin?.version})`;

// License
export const GRAFANA_LICENSE_OSS = 'OpenSource';

// Reusable breakpoint sizes
export const BREAKPOINT_TABS = 1024;

// Default redirect page
export const DEFAULT_PAGE = 'incidents';

// Environment options list for onCallApiUrl
export const ONCALL_PROD = 'https://oncall-prod-us-central-0.grafana.net/oncall';
export const ONCALL_OPS = 'https://oncall-ops-us-east-0.grafana.net/oncall';
export const ONCALL_DEV = 'https://oncall-dev-us-central-0.grafana.net/oncall';

// Faro
export const FARO_ENDPOINT_DEV =
'https://faro-collector-prod-us-central-0.grafana.net/collect/fb03e474a96cf867f4a34590c002984c';
export const FARO_ENDPOINT_OPS =
'https://faro-collector-prod-us-central-0.grafana.net/collect/40ccaafad6b71aa90fc53c3b0a1adb31';
export const FARO_ENDPOINT_PROD =
'https://faro-collector-prod-us-central-0.grafana.net/collect/03a11ed03c3af04dcfc3be9755f2b053';
89 changes: 0 additions & 89 deletions src/utils/faro.test.disabled

This file was deleted.

65 changes: 65 additions & 0 deletions src/utils/faro.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'jest/matchMedia.ts';
import { describe, test } from '@jest/globals';

import FaroHelper from 'utils/faro';

import '@testing-library/jest-dom';
import { ONCALL_DEV, ONCALL_OPS, ONCALL_PROD } from './consts';

const ErrorMock = jest.spyOn(window, 'Error');

jest.mock('@grafana/faro-web-sdk', () => ({
initializeFaro: jest.fn().mockReturnValue({
api: {
pushLog: jest.fn(),
},
}),
getWebInstrumentations: () => [],
}));

jest.mock('@grafana/faro-web-tracing', () => ({
TracingInstrumentation: jest.fn(),
}));
jest.mock('@opentelemetry/instrumentation-document-load', () => ({
DocumentLoadInstrumentation: jest.fn(),
}));
jest.mock('@opentelemetry/instrumentation-fetch', () => ({
FetchInstrumentation: jest.fn(),
}));

describe('Faro', () => {
beforeEach(() => {
jest.clearAllMocks();

FaroHelper.faro = undefined;
});

test.each([ONCALL_DEV, ONCALL_OPS, ONCALL_PROD])('It initializes faro for environment %s', (onCallApiUrl) => {
const faro = FaroHelper.initializeFaro(onCallApiUrl);
expect(faro).toBeDefined();
expect(ErrorMock).not.toHaveBeenCalled();
});

test.each(['https://test.com', 'http://localhost:3000'])(
'It fails initializing for dummy environment values',
(onCallApiUrl) => {
const faro = FaroHelper.initializeFaro(onCallApiUrl);
expect(faro).toBeUndefined();
}
);

test('It does not reinitialize faro instance if already initialized', () => {
const instance = FaroHelper.initializeFaro(ONCALL_DEV);
expect(instance).toBeDefined();

const result = FaroHelper.initializeFaro(ONCALL_PROD);
expect(result).toBeUndefined();
expect(FaroHelper.faro).toBe(instance);
});

test('Initializer throws error for wrong env value', () => {
const faro = FaroHelper.initializeFaro('https://test.com');
expect(ErrorMock).toHaveBeenCalledWith(`No match found for given onCallApiUrl = https://test.com`);
expect(faro).toBeUndefined();
});
});
57 changes: 27 additions & 30 deletions src/utils/faro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,45 @@ import { UserInteractionInstrumentation } from '@opentelemetry/instrumentation-u
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';

import plugin from '../../package.json'; // eslint-disable-line
import {
FARO_ENDPOINT_DEV,
FARO_ENDPOINT_OPS,
FARO_ENDPOINT_PROD,
ONCALL_DEV,
ONCALL_OPS,
ONCALL_PROD,
} from './consts';

const IGNORE_URLS = [/^((?!\/{0,1}a\/grafana\-oncall\-app\\).)*$/];

interface FaroConfig {
url: string;
enabled: boolean;
environment: string;
export function getAppNameUrlPair(onCallApiUrl: string): { appName: string; url: string } {
const baseName = 'grafana-oncall';

switch (onCallApiUrl) {
case ONCALL_DEV:
return { appName: `${baseName}-dev`, url: FARO_ENDPOINT_DEV };
case ONCALL_OPS:
return { appName: `${baseName}-ops`, url: FARO_ENDPOINT_OPS };
case ONCALL_PROD:
return { appName: `${baseName}-prod`, url: FARO_ENDPOINT_PROD };
default:
throw new Error(`No match found for given onCallApiUrl = ${onCallApiUrl}`);
}
}

class FaroHelper {
faro: Faro;

initializeFaro(onCallApiUrl: string) {
const faroConfig: FaroConfig = {
url: 'https://faro-collector-prod-us-central-0.grafana.net/collect/f3a038193e7802cf47531ca94cfbada7',
enabled: false,
environment: undefined,
};

if (onCallApiUrl === 'https://oncall-prod-us-central-0.grafana.net/oncall') {
faroConfig.enabled = true;
faroConfig.environment = 'prod';
} else if (onCallApiUrl === 'https://oncall-ops-us-east-0.grafana.net/oncall') {
faroConfig.enabled = true;
faroConfig.environment = 'ops';
} else if (onCallApiUrl === 'https://oncall-dev-us-central-0.grafana.net/oncall') {
faroConfig.enabled = true;
faroConfig.environment = 'dev';
} else {
// This opensource, don't send traces
/* faroConfig.enabled = true;
faroConfig.environment = 'local'; */
}

if (!faroConfig?.enabled || !faroConfig?.url || this.faro) {
if (this.faro) {
return undefined;
}

try {
const { appName, url } = getAppNameUrlPair(onCallApiUrl);

const faroOptions = {
url: faroConfig.url,
url: url,
isolate: true,
instrumentations: [
...getWebInstrumentations({
Expand All @@ -63,15 +61,14 @@ class FaroHelper {
],
session: (window as any).__PRELOADED_STATE__?.faro?.session,
app: {
name: 'grafana-oncall',
name: appName,
version: plugin?.version,
environment: faroConfig.environment,
},
};

this.faro = initializeFaro(faroOptions);

this.faro.api.pushLog([`Faro was initialized for ${faroConfig.environment}`]);
this.faro.api.pushLog([`Faro was initialized for ${appName}`]);
} catch (ex) {}

return this.faro;
Expand Down

0 comments on commit 5cc07b9

Please sign in to comment.