Faro: Update configuration with best practices (#112108)
* Clean up faro configuration to align with best practices * Update grafana docs * remove fixme comment * fix tests * don't spread config in
This commit is contained in:
+31
-25
@@ -1194,11 +1194,39 @@ facility =
|
|||||||
tag =
|
tag =
|
||||||
|
|
||||||
[log.frontend]
|
[log.frontend]
|
||||||
# Should Faro javascript agent be initialized
|
# Enables the Grafana Faro javascript agent integration for capturing frontend performance and error events.
|
||||||
enabled = false
|
enabled = false
|
||||||
|
|
||||||
# Custom HTTP endpoint to send events to. Default will log the events to stdout.
|
# Custom HTTP endpoint to send Grafana Faro events to. Default will send events to /log-grafana-javascript-agent and log the events to stdout.
|
||||||
custom_endpoint =
|
custom_endpoint = /log-grafana-javascript-agent
|
||||||
|
|
||||||
|
# API Key for Grafana Faro custom endpoint
|
||||||
|
api_key =
|
||||||
|
|
||||||
|
# level of internal logging for debugging Grafana Javascript Agent.
|
||||||
|
# possible values are: 0 = OFF, 1 = ERROR, 2 = WARN, 3 = INFO, 4 = VERBOSE
|
||||||
|
# more details: https://github.com/grafana/faro-web-sdk/blob/v1.3.7/docs/sources/tutorials/quick-start-browser.md#how-to-activate-debugging
|
||||||
|
internal_logger_level = 0
|
||||||
|
|
||||||
|
# Enables the Console instrumentation for Grafana Faro
|
||||||
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/console-instrumentation/
|
||||||
|
instrumentations_console_enabled = true
|
||||||
|
|
||||||
|
# Enables the Performance instrumentation for Grafana Faro.
|
||||||
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/performance-instrumentation/
|
||||||
|
instrumentations_performance_enabled = true
|
||||||
|
|
||||||
|
# Enables the Content Security Policy Violations instrumentation for Grafana Faro.
|
||||||
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/csp-violation-tracking/
|
||||||
|
instrumentations_csp_enabled = true
|
||||||
|
|
||||||
|
# Enables the Tracing instrumentation for Grafana Faro.
|
||||||
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/tracing-instrumentation/
|
||||||
|
instrumentations_tracing_enabled = true
|
||||||
|
|
||||||
|
# Enables sending attribution data for web vitals with the Performance instrumentation.
|
||||||
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/web-vitals/#web-vitals-attribution-data
|
||||||
|
web_vitals_attribution_enabled = true
|
||||||
|
|
||||||
# Requests per second limit enforced per an extended period, for Grafana backend log ingestion endpoint (/log).
|
# Requests per second limit enforced per an extended period, for Grafana backend log ingestion endpoint (/log).
|
||||||
log_endpoint_requests_per_second_limit = 3
|
log_endpoint_requests_per_second_limit = 3
|
||||||
@@ -1206,28 +1234,6 @@ log_endpoint_requests_per_second_limit = 3
|
|||||||
# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log)
|
# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log)
|
||||||
log_endpoint_burst_limit = 15
|
log_endpoint_burst_limit = 15
|
||||||
|
|
||||||
# Enables all Faro default instrumentation by using `getWebInstrumentations`. Overrides other instrumentation flags.
|
|
||||||
instrumentations_all_enabled = false
|
|
||||||
|
|
||||||
# Should error instrumentation be enabled, only affects Grafana Javascript Agent
|
|
||||||
instrumentations_errors_enabled = true
|
|
||||||
|
|
||||||
# Should console instrumentation be enabled, only affects Grafana Javascript Agent
|
|
||||||
instrumentations_console_enabled = false
|
|
||||||
|
|
||||||
# Should webvitals instrumentation be enabled, only affects Grafana Javascript Agent
|
|
||||||
instrumentations_webvitals_enabled = false
|
|
||||||
|
|
||||||
# Should tracing instrumentation be enabled, only affects Grafana Javascript Agent
|
|
||||||
instrumentations_tracing_enabled = false
|
|
||||||
|
|
||||||
# level of internal logging for debugging Grafana Javascript Agent.
|
|
||||||
# possible values are: 0 = OFF, 1 = ERROR, 2 = WARN, 3 = INFO, 4 = VERBOSE
|
|
||||||
# more details: https://github.com/grafana/faro-web-sdk/blob/v1.3.7/docs/sources/tutorials/quick-start-browser.md#how-to-activate-debugging
|
|
||||||
internal_logger_level = 0
|
|
||||||
|
|
||||||
# Api Key, only applies to Grafana Javascript Agent provider
|
|
||||||
api_key =
|
|
||||||
|
|
||||||
#################################### Usage Quotas ########################
|
#################################### Usage Quotas ########################
|
||||||
[quota]
|
[quota]
|
||||||
|
|||||||
+23
-19
@@ -1172,35 +1172,39 @@
|
|||||||
;tag =
|
;tag =
|
||||||
|
|
||||||
[log.frontend]
|
[log.frontend]
|
||||||
# Should Faro javascript agent be initialized
|
# Enables the Grafana Faro javascript agent integration for capturing frontend performance and error events.
|
||||||
;enabled = false
|
;enabled = false
|
||||||
|
|
||||||
# Custom HTTP endpoint to send events to. Default will log the events to stdout.
|
# Custom HTTP endpoint to send Grafana Faro events to. Default will send events to /log-grafana-javascript-agent and log the events to stdout.
|
||||||
;custom_endpoint = /log-grafana-javascript-agent
|
;custom_endpoint = /log-grafana-javascript-agent
|
||||||
|
|
||||||
# Requests per second limit enforced an extended period, for Grafana backend log ingestion endpoint (/log).
|
# API Key for Grafana Faro custom endpoint
|
||||||
;log_endpoint_requests_per_second_limit = 3
|
;api_key =
|
||||||
|
|
||||||
# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log).
|
# level of internal logging for debugging Grafana Javascript Agent.
|
||||||
;log_endpoint_burst_limit = 15
|
# possible values are: 0 = OFF, 1 = ERROR, 2 = WARN, 3 = INFO, 4 = VERBOSE
|
||||||
|
# more details: https://github.com/grafana/faro-web-sdk/blob/v1.3.7/docs/sources/tutorials/quick-start-browser.md#how-to-activate-debugging
|
||||||
|
;internal_logger_level =
|
||||||
|
|
||||||
# Enables all Faro default instrumentation by using `getWebInstrumentations`. Overrides other instrumentation flags.
|
# Enables the Console instrumentation for Grafana Faro
|
||||||
;instrumentations_all_enabled = false
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/console-instrumentation/
|
||||||
|
;instrumentations_console_enabled = true
|
||||||
|
|
||||||
# Should error instrumentation be enabled, only affects Grafana Javascript Agent
|
# Enables the Performance instrumentation for Grafana Faro.
|
||||||
;instrumentations_errors_enabled = true
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/performance-instrumentation/
|
||||||
|
;instrumentations_performance_enabled = true
|
||||||
|
|
||||||
# Should console instrumentation be enabled, only affects Grafana Javascript Agent
|
# Enables the Content Security Policy Violations instrumentation for Grafana Faro.
|
||||||
;instrumentations_console_enabled = false
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/csp-violation-tracking/
|
||||||
|
; instrumentations_csp_enabled = true
|
||||||
|
|
||||||
# Should webvitals instrumentation be enabled, only affects Grafana Javascript Agent
|
# Enables the Tracing instrumentation for Grafana Faro.
|
||||||
;instrumentations_webvitals_enabled = false
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/tracing-instrumentation/
|
||||||
|
;instrumentations_tracing_enabled = true
|
||||||
|
|
||||||
# Should tracing instrumentation be enabled, only affects Grafana Javascript Agent
|
# Enables sending attribution data for web vitals with the Performance instrumentation.
|
||||||
;instrumentations_tracing_enabled = false
|
# See https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/web-vitals/#web-vitals-attribution-data
|
||||||
|
;web_vitals_attribution_enabled = true
|
||||||
# Api Key, only applies to Grafana Javascript Agent provider
|
|
||||||
;api_key = testApiKey
|
|
||||||
|
|
||||||
#################################### Usage Quotas ########################
|
#################################### Usage Quotas ########################
|
||||||
[quota]
|
[quota]
|
||||||
|
|||||||
@@ -1641,11 +1641,35 @@ Syslog tag. By default, the process's `argv[0]` is used.
|
|||||||
|
|
||||||
#### `enabled`
|
#### `enabled`
|
||||||
|
|
||||||
Faro JavaScript agent is initialized. Default is `false`.
|
Grafana Faro instrumentation is initialized. Default is `false`. Enables the default set of instrumentations from `getWebInstrumentations`. See the options below to selectively disable some of these.
|
||||||
|
|
||||||
#### `custom_endpoint`
|
#### `custom_endpoint`
|
||||||
|
|
||||||
Custom HTTP endpoint to send events captured by the Faro agent to. Default, `/log-grafana-javascript-agent`, logs the events to standard output.
|
Custom HTTP endpoint to send events captured by the Grafana Faro agent to. Default, `/log-grafana-javascript-agent`, logs the events to standard output.
|
||||||
|
|
||||||
|
#### `api_key`
|
||||||
|
|
||||||
|
If `custom_endpoint` required authentication, you can set the API key here. Only relevant for Grafana JavaScript Agent provider.
|
||||||
|
|
||||||
|
#### `instrumentations_console_enabled`
|
||||||
|
|
||||||
|
Enables the [Console instrumentation](https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/console-instrumentation/) for Grafana Faro, defaults to `true`.
|
||||||
|
|
||||||
|
#### `instrumentations_performance_enabled`
|
||||||
|
|
||||||
|
Enables the [Performance instrumentation](https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/performance-instrumentation/) for Grafana Faro, defaults to `true`.
|
||||||
|
|
||||||
|
#### `instrumentations_csp_enabled`
|
||||||
|
|
||||||
|
Enables the [Content Security Policy Violations instrumentation](https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/csp-violation-tracking/) for Grafana Faro, defaults to `true`.
|
||||||
|
|
||||||
|
#### `instrumentations_tracing_enabled`
|
||||||
|
|
||||||
|
Enables the [Tracing instrumentation](https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/tracing-instrumentation/) for Grafana Faro, defaults to `true`.
|
||||||
|
|
||||||
|
#### `web_vitals_attribution_enabled`
|
||||||
|
|
||||||
|
Enables sending [attribution data for web vitals](https://grafana.com/docs/grafana-cloud/monitor-applications/frontend-observability/instrument/web-vitals/#web-vitals-attribution-data) with the Performance instrumentation, defaults to `true`.
|
||||||
|
|
||||||
#### `log_endpoint_requests_per_second_limit`
|
#### `log_endpoint_requests_per_second_limit`
|
||||||
|
|
||||||
@@ -1655,30 +1679,6 @@ Requests per second limit enforced per an extended period, for Grafana backend l
|
|||||||
|
|
||||||
Maximum requests accepted per short interval of time for Grafana backend log ingestion endpoint, `/log-grafana-javascript-agent`. Default is `15`.
|
Maximum requests accepted per short interval of time for Grafana backend log ingestion endpoint, `/log-grafana-javascript-agent`. Default is `15`.
|
||||||
|
|
||||||
#### `instrumentations_all_enabled`
|
|
||||||
|
|
||||||
Enables all Faro default instrumentation by using `getWebInstrumentations`. Overrides other instrumentation flags.
|
|
||||||
|
|
||||||
#### `instrumentations_errors_enabled`
|
|
||||||
|
|
||||||
Turn on error instrumentation. Only affects Grafana JavaScript Agent.
|
|
||||||
|
|
||||||
#### `instrumentations_console_enabled`
|
|
||||||
|
|
||||||
Turn on console instrumentation. Only affects Grafana JavaScript Agent
|
|
||||||
|
|
||||||
#### `instrumentations_webvitals_enabled`
|
|
||||||
|
|
||||||
Turn on web vitals instrumentation. Only affects Grafana JavaScript Agent
|
|
||||||
|
|
||||||
#### `instrumentations_tracing_enabled`
|
|
||||||
|
|
||||||
Turns on tracing instrumentation. Only affects Grafana JavaScript Agent.
|
|
||||||
|
|
||||||
#### `api_key`
|
|
||||||
|
|
||||||
If `custom_endpoint` required authentication, you can set the API key here. Only relevant for Grafana JavaScript Agent provider.
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
### `[quota]`
|
### `[quota]`
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { InternalLoggerLevel } from '@grafana/faro-core';
|
||||||
|
|
||||||
import { SystemDateFormatSettings } from '../datetime/formats';
|
import { SystemDateFormatSettings } from '../datetime/formats';
|
||||||
import { MapLayerOptions } from '../geo/layer';
|
import { MapLayerOptions } from '../geo/layer';
|
||||||
|
|
||||||
@@ -93,11 +95,14 @@ export interface LicenseInfo {
|
|||||||
export interface GrafanaJavascriptAgentConfig {
|
export interface GrafanaJavascriptAgentConfig {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
customEndpoint: string;
|
customEndpoint: string;
|
||||||
errorInstrumentalizationEnabled: boolean;
|
|
||||||
consoleInstrumentalizationEnabled: boolean;
|
|
||||||
webVitalsInstrumentalizationEnabled: boolean;
|
|
||||||
tracingInstrumentalizationEnabled: boolean;
|
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
|
internalLoggerLevel: InternalLoggerLevel;
|
||||||
|
|
||||||
|
consoleInstrumentalizationEnabled: boolean;
|
||||||
|
performanceInstrumentalizationEnabled: boolean;
|
||||||
|
cspInstrumentalizationEnabled: boolean;
|
||||||
|
tracingInstrumentalizationEnabled: boolean;
|
||||||
|
webVitalsAttribution: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UnifiedAlertingStateHistoryConfig {
|
export interface UnifiedAlertingStateHistoryConfig {
|
||||||
|
|||||||
@@ -153,13 +153,14 @@ export class GrafanaBootConfig {
|
|||||||
dateFormats?: SystemDateFormatSettings;
|
dateFormats?: SystemDateFormatSettings;
|
||||||
grafanaJavascriptAgent = {
|
grafanaJavascriptAgent = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
customEndpoint: '',
|
|
||||||
apiKey: '',
|
apiKey: '',
|
||||||
allInstrumentationsEnabled: false,
|
customEndpoint: '',
|
||||||
errorInstrumentalizationEnabled: true,
|
|
||||||
consoleInstrumentalizationEnabled: false,
|
consoleInstrumentalizationEnabled: false,
|
||||||
webVitalsInstrumentalizationEnabled: false,
|
performanceInstrumentalizationEnabled: false,
|
||||||
|
cspInstrumentalizationEnabled: false,
|
||||||
tracingInstrumentalizationEnabled: false,
|
tracingInstrumentalizationEnabled: false,
|
||||||
|
webVitalsAttribution: false,
|
||||||
|
internalLoggerLevel: 0,
|
||||||
};
|
};
|
||||||
pluginCatalogURL = 'https://grafana.com/grafana/plugins/';
|
pluginCatalogURL = 'https://grafana.com/grafana/plugins/';
|
||||||
pluginAdminEnabled = true;
|
pluginAdminEnabled = true;
|
||||||
|
|||||||
@@ -1,32 +1,36 @@
|
|||||||
package setting
|
package setting
|
||||||
|
|
||||||
type GrafanaJavascriptAgent struct {
|
type GrafanaJavascriptAgent struct {
|
||||||
Enabled bool `json:"enabled"`
|
EndpointRPS int `json:"-"`
|
||||||
CustomEndpoint string `json:"customEndpoint"`
|
EndpointBurst int `json:"-"`
|
||||||
EndpointRPS int `json:"-"`
|
|
||||||
EndpointBurst int `json:"-"`
|
// Faro config
|
||||||
AllInstrumentationsEnabeld bool `json:"allInstrumentationEnabeld"`
|
Enabled bool `json:"enabled"`
|
||||||
ErrorInstrumentalizationEnabled bool `json:"errorInstrumentalizationEnabled"`
|
CustomEndpoint string `json:"customEndpoint"`
|
||||||
ConsoleInstrumentalizationEnabled bool `json:"consoleInstrumentalizationEnabled"`
|
ApiKey string `json:"apiKey"`
|
||||||
WebVitalsInstrumentalizationEnabled bool `json:"webVitalsInstrumentalizationEnabled"`
|
InternalLoggerLevel int `json:"internalLoggerLevel"`
|
||||||
TracingInstrumentalizationEnabled bool `json:"tracingInstrumentalizationEnabled"`
|
ConsoleInstrumentalizationEnabled bool `json:"consoleInstrumentalizationEnabled"`
|
||||||
InternalLoggerLevel int `json:"internalLoggerLevel"`
|
PerformanceInstrumentalizationEnabled bool `json:"performanceInstrumentalizationEnabled"`
|
||||||
ApiKey string `json:"apiKey"`
|
CSPInstrumentalizationEnabled bool `json:"cspInstrumentalizationEnabled"`
|
||||||
|
TracingInstrumentalizationEnabled bool `json:"tracingInstrumentalizationEnabled"`
|
||||||
|
WebVitalsAttributionEnabled bool `json:"webVitalsAttributionEnabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Cfg) readGrafanaJavascriptAgentConfig() {
|
func (cfg *Cfg) readGrafanaJavascriptAgentConfig() {
|
||||||
raw := cfg.Raw.Section("log.frontend")
|
raw := cfg.Raw.Section("log.frontend")
|
||||||
cfg.GrafanaJavascriptAgent = GrafanaJavascriptAgent{
|
cfg.GrafanaJavascriptAgent = GrafanaJavascriptAgent{
|
||||||
Enabled: raw.Key("enabled").MustBool(true),
|
EndpointRPS: raw.Key("log_endpoint_requests_per_second_limit").MustInt(3),
|
||||||
CustomEndpoint: raw.Key("custom_endpoint").MustString("/log-grafana-javascript-agent"),
|
EndpointBurst: raw.Key("log_endpoint_burst_limit").MustInt(15),
|
||||||
EndpointRPS: raw.Key("log_endpoint_requests_per_second_limit").MustInt(3),
|
|
||||||
EndpointBurst: raw.Key("log_endpoint_burst_limit").MustInt(15),
|
// Faro config
|
||||||
AllInstrumentationsEnabeld: raw.Key("instrumentations_all_enabled").MustBool(false),
|
Enabled: raw.Key("enabled").MustBool(false),
|
||||||
ErrorInstrumentalizationEnabled: raw.Key("instrumentations_errors_enabled").MustBool(true),
|
CustomEndpoint: raw.Key("custom_endpoint").MustString("/log-grafana-javascript-agent"),
|
||||||
ConsoleInstrumentalizationEnabled: raw.Key("instrumentations_console_enabled").MustBool(true),
|
ApiKey: raw.Key("api_key").String(),
|
||||||
WebVitalsInstrumentalizationEnabled: raw.Key("instrumentations_webvitals_enabled").MustBool(true),
|
InternalLoggerLevel: raw.Key("internal_logger_level").MustInt(0),
|
||||||
TracingInstrumentalizationEnabled: raw.Key("instrumentations_tracing_enabled").MustBool(true),
|
ConsoleInstrumentalizationEnabled: raw.Key("instrumentations_console_enabled").MustBool(true),
|
||||||
InternalLoggerLevel: raw.Key("internal_logger_level").MustInt(0),
|
PerformanceInstrumentalizationEnabled: raw.Key("instrumentations_performance_enabled").MustBool(true),
|
||||||
ApiKey: raw.Key("api_key").String(),
|
CSPInstrumentalizationEnabled: raw.Key("instrumentations_csp_enabled").MustBool(true),
|
||||||
|
TracingInstrumentalizationEnabled: raw.Key("instrumentations_tracing_enabled").MustBool(true),
|
||||||
|
WebVitalsAttributionEnabled: raw.Key("web_vitals_attribution_enabled").MustBool(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-31
@@ -2,7 +2,15 @@ import { BuildInfo } from '@grafana/data';
|
|||||||
import { GrafanaEdition } from '@grafana/data/internal';
|
import { GrafanaEdition } from '@grafana/data/internal';
|
||||||
import { Faro, Instrumentation } from '@grafana/faro-core';
|
import { Faro, Instrumentation } from '@grafana/faro-core';
|
||||||
import * as faroWebSdkModule from '@grafana/faro-web-sdk';
|
import * as faroWebSdkModule from '@grafana/faro-web-sdk';
|
||||||
import { BrowserConfig, FetchTransport, SessionInstrumentation } from '@grafana/faro-web-sdk';
|
import {
|
||||||
|
BrowserConfig,
|
||||||
|
FetchTransport,
|
||||||
|
SessionInstrumentation,
|
||||||
|
UserActionInstrumentation,
|
||||||
|
ErrorsInstrumentation,
|
||||||
|
WebVitalsInstrumentation,
|
||||||
|
ViewInstrumentation,
|
||||||
|
} from '@grafana/faro-web-sdk';
|
||||||
import { TracingInstrumentation } from '@grafana/faro-web-tracing';
|
import { TracingInstrumentation } from '@grafana/faro-web-tracing';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
|
|
||||||
@@ -71,21 +79,16 @@ describe('GrafanaJavascriptAgentEchoBackend', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const options: GrafanaJavascriptAgentBackendOptions = {
|
const options: GrafanaJavascriptAgentBackendOptions = {
|
||||||
buildInfo,
|
|
||||||
app: {
|
|
||||||
version: '1.0',
|
|
||||||
},
|
|
||||||
allInstrumentationsEnabled: true,
|
|
||||||
errorInstrumentalizationEnabled: true,
|
|
||||||
consoleInstrumentalizationEnabled: true,
|
|
||||||
webVitalsInstrumentalizationEnabled: true,
|
|
||||||
tracingInstrumentalizationEnabled: true,
|
|
||||||
customEndpoint: '/log-grafana-javascript-agent',
|
customEndpoint: '/log-grafana-javascript-agent',
|
||||||
user: {
|
|
||||||
email: 'darth.vader@sith.glx',
|
webVitalsAttribution: true,
|
||||||
id: '504',
|
consoleInstrumentalizationEnabled: true,
|
||||||
orgId: 1,
|
performanceInstrumentalizationEnabled: true,
|
||||||
},
|
cspInstrumentalizationEnabled: true,
|
||||||
|
tracingInstrumentalizationEnabled: true,
|
||||||
|
|
||||||
|
buildInfo: buildInfo,
|
||||||
|
userIdentifier: 'abc123',
|
||||||
ignoreUrls: [],
|
ignoreUrls: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -116,13 +119,13 @@ describe('GrafanaJavascriptAgentEchoBackend', () => {
|
|||||||
|
|
||||||
//assert
|
//assert
|
||||||
expect(initializeFaroMock).toHaveBeenCalledTimes(1);
|
expect(initializeFaroMock).toHaveBeenCalledTimes(1);
|
||||||
expect(mockedSetUser).toHaveBeenCalledTimes(1);
|
expect(initializeFaroMock).toHaveBeenCalledWith(
|
||||||
expect(mockedSetUser).toHaveBeenCalledWith({
|
expect.objectContaining({
|
||||||
id: '504',
|
user: {
|
||||||
attributes: {
|
id: 'abc123',
|
||||||
orgId: '1',
|
},
|
||||||
},
|
})
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('will ensure the performance of TRACKING_URLS', async () => {
|
test('will ensure the performance of TRACKING_URLS', async () => {
|
||||||
@@ -139,22 +142,39 @@ describe('GrafanaJavascriptAgentEchoBackend', () => {
|
|||||||
it('correctly set instrumentation based on options', async () => {
|
it('correctly set instrumentation based on options', async () => {
|
||||||
let opts = {
|
let opts = {
|
||||||
...options,
|
...options,
|
||||||
allInstrumentationsEnabled: false,
|
|
||||||
errorInstrumentalizationEnabled: false,
|
|
||||||
consoleInstrumentalizationEnabled: false,
|
consoleInstrumentalizationEnabled: false,
|
||||||
webVitalsInstrumentalizationEnabled: false,
|
performanceInstrumentalizationEnabled: false,
|
||||||
|
cspInstrumentalizationEnabled: false,
|
||||||
tracingInstrumentalizationEnabled: false,
|
tracingInstrumentalizationEnabled: false,
|
||||||
};
|
};
|
||||||
new GrafanaJavascriptAgentBackend(opts);
|
new GrafanaJavascriptAgentBackend(opts);
|
||||||
expect(initializeFaroMock.mock.calls[0][0].instrumentations?.length).toEqual(1);
|
|
||||||
expect(initializeFaroMock.mock.calls[0][0].instrumentations?.[0]).toBeInstanceOf(SessionInstrumentation);
|
let lastInstrumentations = initializeFaroMock.mock.calls.at(-1)?.[0].instrumentations;
|
||||||
|
expect(lastInstrumentations).toHaveLength(5);
|
||||||
|
expect(lastInstrumentations).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.any(SessionInstrumentation),
|
||||||
|
expect.any(UserActionInstrumentation),
|
||||||
|
expect.any(ErrorsInstrumentation),
|
||||||
|
expect.any(WebVitalsInstrumentation),
|
||||||
|
expect.any(ViewInstrumentation),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
opts.tracingInstrumentalizationEnabled = true;
|
opts.tracingInstrumentalizationEnabled = true;
|
||||||
|
|
||||||
new GrafanaJavascriptAgentBackend(opts);
|
new GrafanaJavascriptAgentBackend(opts);
|
||||||
expect(initializeFaroMock.mock.calls[1][0].instrumentations?.length).toEqual(2);
|
lastInstrumentations = initializeFaroMock.mock.calls.at(-1)?.[0].instrumentations;
|
||||||
expect(initializeFaroMock.mock.calls[1][0].instrumentations?.[0]).toBeInstanceOf(TracingInstrumentation);
|
expect(lastInstrumentations).toHaveLength(6);
|
||||||
expect(initializeFaroMock.mock.calls[1][0].instrumentations?.[1]).toBeInstanceOf(SessionInstrumentation);
|
expect(lastInstrumentations).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.any(SessionInstrumentation),
|
||||||
|
expect.any(UserActionInstrumentation),
|
||||||
|
expect.any(ErrorsInstrumentation),
|
||||||
|
expect.any(WebVitalsInstrumentation),
|
||||||
|
expect.any(ViewInstrumentation),
|
||||||
|
expect.any(TracingInstrumentation),
|
||||||
|
])
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use a beforeSend handler', () => {
|
it('should use a beforeSend handler', () => {
|
||||||
|
|||||||
+42
-61
@@ -1,23 +1,18 @@
|
|||||||
import { BuildInfo, escapeRegex } from '@grafana/data';
|
import { BuildInfo, escapeRegex } from '@grafana/data';
|
||||||
import { BaseTransport, defaultInternalLoggerLevel } from '@grafana/faro-core';
|
import { BaseTransport, defaultInternalLoggerLevel, InternalLoggerLevel } from '@grafana/faro-core';
|
||||||
import {
|
import {
|
||||||
initializeFaro,
|
initializeFaro,
|
||||||
BrowserConfig,
|
BrowserConfig,
|
||||||
ErrorsInstrumentation,
|
|
||||||
ConsoleInstrumentation,
|
|
||||||
WebVitalsInstrumentation,
|
|
||||||
SessionInstrumentation,
|
|
||||||
FetchTransport,
|
FetchTransport,
|
||||||
type Instrumentation,
|
|
||||||
getWebInstrumentations,
|
getWebInstrumentations,
|
||||||
Config,
|
type Instrumentation,
|
||||||
} from '@grafana/faro-web-sdk';
|
} from '@grafana/faro-web-sdk';
|
||||||
import { TracingInstrumentation } from '@grafana/faro-web-tracing';
|
import { TracingInstrumentation } from '@grafana/faro-web-tracing';
|
||||||
import { EchoBackend, EchoEvent, EchoEventType } from '@grafana/runtime';
|
import { EchoBackend, EchoEvent, EchoEventType } from '@grafana/runtime';
|
||||||
|
|
||||||
import { EchoSrvTransport } from './EchoSrvTransport';
|
import { EchoSrvTransport } from './EchoSrvTransport';
|
||||||
import { beforeSendHandler } from './beforeSendHandler';
|
import { beforeSendHandler } from './beforeSendHandler';
|
||||||
import { GrafanaJavascriptAgentEchoEvent, User } from './types';
|
import { GrafanaJavascriptAgentEchoEvent } from './types';
|
||||||
|
|
||||||
function isCrossOriginIframe() {
|
function isCrossOriginIframe() {
|
||||||
try {
|
try {
|
||||||
@@ -27,15 +22,19 @@ function isCrossOriginIframe() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GrafanaJavascriptAgentBackendOptions extends BrowserConfig {
|
export interface GrafanaJavascriptAgentBackendOptions {
|
||||||
buildInfo: BuildInfo;
|
apiKey?: string;
|
||||||
customEndpoint: string;
|
customEndpoint?: string;
|
||||||
user: User;
|
internalLoggerLevel?: InternalLoggerLevel;
|
||||||
allInstrumentationsEnabled: boolean;
|
|
||||||
errorInstrumentalizationEnabled: boolean;
|
webVitalsAttribution: boolean;
|
||||||
consoleInstrumentalizationEnabled: boolean;
|
consoleInstrumentalizationEnabled: boolean;
|
||||||
webVitalsInstrumentalizationEnabled: boolean;
|
performanceInstrumentalizationEnabled: boolean;
|
||||||
|
cspInstrumentalizationEnabled: boolean;
|
||||||
tracingInstrumentalizationEnabled: boolean;
|
tracingInstrumentalizationEnabled: boolean;
|
||||||
|
|
||||||
|
buildInfo: BuildInfo;
|
||||||
|
userIdentifier: string;
|
||||||
ignoreUrls: RegExp[];
|
ignoreUrls: RegExp[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,62 +48,52 @@ export class GrafanaJavascriptAgentBackend
|
|||||||
implements EchoBackend<GrafanaJavascriptAgentEchoEvent, GrafanaJavascriptAgentBackendOptions>
|
implements EchoBackend<GrafanaJavascriptAgentEchoEvent, GrafanaJavascriptAgentBackendOptions>
|
||||||
{
|
{
|
||||||
supportedEvents = [EchoEventType.GrafanaJavascriptAgent];
|
supportedEvents = [EchoEventType.GrafanaJavascriptAgent];
|
||||||
private faroInstance;
|
|
||||||
|
|
||||||
constructor(public options: GrafanaJavascriptAgentBackendOptions) {
|
constructor(public options: GrafanaJavascriptAgentBackendOptions) {
|
||||||
// configure instrumentations.
|
// configure instrumentations.
|
||||||
const instrumentations: Instrumentation[] = [];
|
const instrumentations: Instrumentation[] = [
|
||||||
|
...getWebInstrumentations({
|
||||||
const ignoreUrls = [
|
captureConsole: options.consoleInstrumentalizationEnabled,
|
||||||
new RegExp(`.*${escapeRegex(options.customEndpoint)}.*`),
|
enablePerformanceInstrumentation: options.performanceInstrumentalizationEnabled,
|
||||||
...TRACKING_URLS,
|
enableContentSecurityPolicyInstrumentation: options.cspInstrumentalizationEnabled,
|
||||||
...options.ignoreUrls,
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (options.tracingInstrumentalizationEnabled) {
|
||||||
|
instrumentations.push(new TracingInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
const ignoreUrls = [...TRACKING_URLS, ...options.ignoreUrls];
|
||||||
|
if (options.customEndpoint) {
|
||||||
|
ignoreUrls.unshift(new RegExp(`.*${escapeRegex(options.customEndpoint)}.*`));
|
||||||
|
}
|
||||||
|
|
||||||
const transports: BaseTransport[] = [new EchoSrvTransport({ ignoreUrls })];
|
const transports: BaseTransport[] = [new EchoSrvTransport({ ignoreUrls })];
|
||||||
const consoleInstrumentationOptions: Config['consoleInstrumentation'] =
|
|
||||||
options.allInstrumentationsEnabled || options.consoleInstrumentalizationEnabled
|
|
||||||
? {
|
|
||||||
serializeErrors: true,
|
|
||||||
}
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// If in cross origin iframe, default to writing to instance logging endpoint
|
// If in cross origin iframe, default to writing to instance logging endpoint
|
||||||
if (options.customEndpoint && !isCrossOriginIframe()) {
|
if (options.customEndpoint && !isCrossOriginIframe()) {
|
||||||
transports.push(new FetchTransport({ url: options.customEndpoint, apiKey: options.apiKey }));
|
transports.push(new FetchTransport({ url: options.customEndpoint, apiKey: options.apiKey }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.errorInstrumentalizationEnabled) {
|
|
||||||
instrumentations.push(new ErrorsInstrumentation());
|
|
||||||
}
|
|
||||||
if (options.consoleInstrumentalizationEnabled) {
|
|
||||||
instrumentations.push(new ConsoleInstrumentation());
|
|
||||||
}
|
|
||||||
if (options.webVitalsInstrumentalizationEnabled) {
|
|
||||||
instrumentations.push(new WebVitalsInstrumentation());
|
|
||||||
}
|
|
||||||
if (options.tracingInstrumentalizationEnabled) {
|
|
||||||
instrumentations.push(new TracingInstrumentation());
|
|
||||||
}
|
|
||||||
|
|
||||||
// session instrumentation must be added!
|
|
||||||
instrumentations.push(new SessionInstrumentation());
|
|
||||||
|
|
||||||
// initialize GrafanaJavascriptAgent so it can set up its hooks and start collecting errors
|
// initialize GrafanaJavascriptAgent so it can set up its hooks and start collecting errors
|
||||||
const grafanaJavaScriptAgentOptions: BrowserConfig = {
|
const grafanaJavaScriptAgentOptions: BrowserConfig = {
|
||||||
globalObjectKey: options.globalObjectKey || 'faro',
|
|
||||||
preventGlobalExposure: options.preventGlobalExposure || false,
|
|
||||||
app: {
|
app: {
|
||||||
name: 'grafana-frontend',
|
name: 'grafana-frontend',
|
||||||
version: options.buildInfo.version,
|
version: options.buildInfo.version,
|
||||||
environment: options.buildInfo.env,
|
environment: options.buildInfo.env,
|
||||||
},
|
},
|
||||||
instrumentations: options.allInstrumentationsEnabled
|
|
||||||
? [...getWebInstrumentations(), new TracingInstrumentation()]
|
user: {
|
||||||
: instrumentations,
|
id: options.userIdentifier,
|
||||||
consoleInstrumentation: consoleInstrumentationOptions,
|
},
|
||||||
trackWebVitalsAttribution: options.webVitalsInstrumentalizationEnabled || options.allInstrumentationsEnabled,
|
|
||||||
|
instrumentations: instrumentations,
|
||||||
transports,
|
transports,
|
||||||
|
|
||||||
|
consoleInstrumentation: {
|
||||||
|
serializeErrors: true,
|
||||||
|
},
|
||||||
|
trackWebVitalsAttribution: options.webVitalsAttribution,
|
||||||
ignoreErrors: [
|
ignoreErrors: [
|
||||||
'ResizeObserver loop limit exceeded',
|
'ResizeObserver loop limit exceeded',
|
||||||
'ResizeObserver loop completed',
|
'ResizeObserver loop completed',
|
||||||
@@ -118,19 +107,11 @@ export class GrafanaJavascriptAgentBackend
|
|||||||
batching: {
|
batching: {
|
||||||
sendTimeout: 1000,
|
sendTimeout: 1000,
|
||||||
},
|
},
|
||||||
internalLoggerLevel: options.internalLoggerLevel || defaultInternalLoggerLevel,
|
|
||||||
beforeSend: beforeSendHandler,
|
beforeSend: beforeSendHandler,
|
||||||
|
internalLoggerLevel: options.internalLoggerLevel ?? defaultInternalLoggerLevel,
|
||||||
};
|
};
|
||||||
this.faroInstance = initializeFaro(grafanaJavaScriptAgentOptions);
|
|
||||||
|
|
||||||
if (options.user) {
|
initializeFaro(grafanaJavaScriptAgentOptions);
|
||||||
this.faroInstance.api.setUser({
|
|
||||||
id: options.user.id,
|
|
||||||
attributes: {
|
|
||||||
orgId: String(options.user.orgId) || '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// noop because the EchoSrvTransport registered in Faro will already broadcast all signals emitted by the Faro API
|
// noop because the EchoSrvTransport registered in Faro will already broadcast all signals emitted by the Faro API
|
||||||
|
|||||||
@@ -97,17 +97,18 @@ async function initFaroBackend() {
|
|||||||
|
|
||||||
registerEchoBackend(
|
registerEchoBackend(
|
||||||
new GrafanaJavascriptAgentBackend({
|
new GrafanaJavascriptAgentBackend({
|
||||||
...config.grafanaJavascriptAgent,
|
|
||||||
app: {
|
|
||||||
version: config.buildInfo.version,
|
|
||||||
environment: config.buildInfo.env,
|
|
||||||
},
|
|
||||||
buildInfo: config.buildInfo,
|
buildInfo: config.buildInfo,
|
||||||
user: {
|
userIdentifier: contextSrv.user.analytics.identifier,
|
||||||
id: String(contextSrv.user?.id),
|
|
||||||
email: contextSrv.user?.email,
|
|
||||||
},
|
|
||||||
ignoreUrls: rudderstackUrls,
|
ignoreUrls: rudderstackUrls,
|
||||||
|
|
||||||
|
apiKey: config.grafanaJavascriptAgent.apiKey,
|
||||||
|
customEndpoint: config.grafanaJavascriptAgent.customEndpoint,
|
||||||
|
consoleInstrumentalizationEnabled: config.grafanaJavascriptAgent.consoleInstrumentalizationEnabled,
|
||||||
|
performanceInstrumentalizationEnabled: config.grafanaJavascriptAgent.performanceInstrumentalizationEnabled,
|
||||||
|
cspInstrumentalizationEnabled: config.grafanaJavascriptAgent.cspInstrumentalizationEnabled,
|
||||||
|
tracingInstrumentalizationEnabled: config.grafanaJavascriptAgent.tracingInstrumentalizationEnabled,
|
||||||
|
webVitalsAttribution: config.grafanaJavascriptAgent.webVitalsAttribution,
|
||||||
|
internalLoggerLevel: config.grafanaJavascriptAgent.internalLoggerLevel,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user