surface growthbook flags in sentry
This commit is contained in:
@@ -9,6 +9,7 @@ import {Platform} from 'react-native'
|
|||||||
import {type Result, type WidenPrimitives} from '@growthbook/growthbook-react'
|
import {type Result, type WidenPrimitives} from '@growthbook/growthbook-react'
|
||||||
|
|
||||||
import {Logger} from '#/logger'
|
import {Logger} from '#/logger'
|
||||||
|
import {recordFeatureFlagEvaluation} from '#/logger/sentry/featureFlags'
|
||||||
import {
|
import {
|
||||||
Features,
|
Features,
|
||||||
features as feats,
|
features as feats,
|
||||||
@@ -313,6 +314,7 @@ export function AnalyticsFeaturesContext({
|
|||||||
? sessionMetadataForResult(parentContext, result.experimentResult)
|
? sessionMetadataForResult(parentContext, result.experimentResult)
|
||||||
: undefined,
|
: undefined,
|
||||||
)
|
)
|
||||||
|
recordFeatureFlagEvaluation(feature, result.value)
|
||||||
})
|
})
|
||||||
setAttributes(parentContext.metadata)
|
setAttributes(parentContext.metadata)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import {beforeEach, describe, expect, it, jest} from '@jest/globals'
|
||||||
|
|
||||||
|
import {
|
||||||
|
featureFlagsIntegration,
|
||||||
|
recordFeatureFlagEvaluation,
|
||||||
|
} from '#/logger/sentry/featureFlags'
|
||||||
|
|
||||||
|
jest.mock('#/logger/sentry/lib', () => ({
|
||||||
|
Sentry: {
|
||||||
|
featureFlagsIntegration: jest.fn(() => ({
|
||||||
|
addFeatureFlag: jest.fn(),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('recordFeatureFlagEvaluation', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('records boolean feature flags', () => {
|
||||||
|
recordFeatureFlagEvaluation('enabled-flag', true)
|
||||||
|
recordFeatureFlagEvaluation('disabled-flag', false)
|
||||||
|
|
||||||
|
expect(featureFlagsIntegration.addFeatureFlag).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
'enabled-flag',
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
expect(featureFlagsIntegration.addFeatureFlag).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
'disabled-flag',
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it.each([['value'], [1], [['value']], [{value: true}], [null], [undefined]])(
|
||||||
|
'ignores unsupported value %p',
|
||||||
|
value => {
|
||||||
|
recordFeatureFlagEvaluation('non-boolean-flag', value)
|
||||||
|
|
||||||
|
expect(featureFlagsIntegration.addFeatureFlag).not.toHaveBeenCalled()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import {Sentry} from '#/logger/sentry/lib'
|
||||||
|
|
||||||
|
export const featureFlagsIntegration = Sentry.featureFlagsIntegration()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records a feature flag evaluation on Sentry error events and active spans.
|
||||||
|
* Sentry currently only supports boolean feature flag values.
|
||||||
|
*/
|
||||||
|
export function recordFeatureFlagEvaluation(name: string, value: unknown) {
|
||||||
|
if (typeof value === 'boolean') {
|
||||||
|
featureFlagsIntegration.addFeatureFlag(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import {getGlobalScope, init} from '@sentry/react-native'
|
import {getGlobalScope, init} from '@sentry/react-native'
|
||||||
|
|
||||||
|
import {featureFlagsIntegration} from '#/logger/sentry/featureFlags'
|
||||||
import * as env from '#/env'
|
import * as env from '#/env'
|
||||||
|
|
||||||
init({
|
init({
|
||||||
@@ -10,6 +11,7 @@ init({
|
|||||||
environment: env.ENV,
|
environment: env.ENV,
|
||||||
dist: env.BUNDLE_IDENTIFIER,
|
dist: env.BUNDLE_IDENTIFIER,
|
||||||
release: env.RELEASE_VERSION,
|
release: env.RELEASE_VERSION,
|
||||||
|
integrations: [featureFlagsIntegration],
|
||||||
ignoreErrors: [
|
ignoreErrors: [
|
||||||
/*
|
/*
|
||||||
* Unknown internals errors
|
* Unknown internals errors
|
||||||
|
|||||||
Reference in New Issue
Block a user