Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a413f76
polish(sentry): Cleanup browser.ts and tests
dschom Feb 12, 2026
efe9436
polish(shared): Move fxa-shared/monitoring to libs
dschom Feb 12, 2026
35d84e0
polish(shared): Clean up browser.ts
dschom Feb 12, 2026
fac7352
polish(shared/sentry): Fix duplicate typedef for SentryConfigOpts
dschom Feb 13, 2026
4805500
polish(shared): Output cjs and esm for otel package
dschom Feb 14, 2026
0e5bf29
chore(admin): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
b289bfb
chore(auth): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
c5f3fa3
chore(content): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
ec90272
chore(customs): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
0f0093e
chore(event-broker): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
bd111cf
chore(payments): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
0fd0adc
chore(profile): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
3034d13
chore(settings): Update refs to use libs instead of fxa-shared
dschom Feb 14, 2026
17be973
chore(admin): Delete unused code from fxa-shared
dschom Mar 18, 2026
6c0662a
fix(sentry): Update stale fxa-shared/sentry imports to @fxa/shared/se…
dschom Apr 16, 2026
231003a
chore: Remove stray .claude/scheduled_tasks.lock
dschom Apr 16, 2026
66b57e2
fix(admin-server): Add @fxa/shared/sentry-node path to tsconfig.build…
dschom Apr 16, 2026
8874675
fix(profile-server): Add tsconfig path resolution to jest config
dschom Apr 17, 2026
e0b63a2
fix(auth-server): Restore fxa-shared/* jest moduleNameMapper
dschom Apr 17, 2026
7d6f83d
fix(content-server): Enable esbuild-register for server-side @fxa/sha…
dschom Apr 17, 2026
fb17564
fix(shared/sentry-utils): Break circular import in before-send.browser
dschom Apr 17, 2026
161afb3
fix(content-server): Add explicit webpack alias for @fxa/shared/sentr…
dschom Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions libs/shared/monitoring/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
14 changes: 14 additions & 0 deletions libs/shared/monitoring/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"jsc": {
"target": "es2017",
"parser": {
"syntax": "typescript",
"decorators": true,
"dynamicImport": true
},
"transform": {
"decoratorMetadata": true,
"legacyDecorator": true
}
}
}
28 changes: 28 additions & 0 deletions libs/shared/monitoring/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# shared-monitoring

This library provides monitoring functionality including error tracking with Sentry and distributed tracing.

It exports the `initMonitoring` function which initializes both error monitoring (Sentry) and performance monitoring (tracing) for server applications.

## Usage

```typescript
import { initMonitoring } from '@fxa/shared/monitoring';

initMonitoring({
log: logger,
config: {
tracing: {
/* tracing config */
},
sentry: {
/* sentry config */
},
},
});
```

## Exported APIs

- `initMonitoring(opts: MonitoringConfig)` - Initialize monitoring components
- `MonitoringConfig` - Type definition for monitoring configuration
42 changes: 42 additions & 0 deletions libs/shared/monitoring/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Config } from 'jest';
/* eslint-disable */
import { readFileSync } from 'fs';

// Reading the SWC compilation config and remove the "exclude"
// for the test files to be compiled by SWC
const { exclude: _, ...swcJestConfig } = JSON.parse(
readFileSync(`${__dirname}/.swcrc`, 'utf-8')
);

// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves.
// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude"
if (swcJestConfig.swcrc === undefined) {
swcJestConfig.swcrc = false;
}

// Uncomment if using global setup/teardown files being transformed via swc
// https://nx.dev/packages/jest/documents/overview#global-setup/teardown-with-nx-libraries
// jest needs EsModule Interop to find the default exported setup/teardown functions
// swcJestConfig.module.noInterop = false;

const config: Config = {
displayName: 'shared-monitoring',
preset: '../../../jest.preset.js',
transform: {
'^.+\\.[tj]s$': ['@swc/jest', swcJestConfig],
},
moduleFileExtensions: ['ts', 'js', 'html'],
testEnvironment: 'node',
coverageDirectory: '../../../coverage/libs/shared/monitoring',
reporters: [
'default',
[
'jest-junit',
{
outputDirectory: 'artifacts/tests/shared-monitoring',
outputName: 'shared-monitoring-jest-unit-results.xml',
},
],
],
};
export default config;
4 changes: 4 additions & 0 deletions libs/shared/monitoring/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "@fxa/shared/monitoring",
"version": "0.0.0"
}
56 changes: 56 additions & 0 deletions libs/shared/monitoring/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "shared-monitoring",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/shared/monitoring/src",
"projectType": "library",
"tags": ["scope:shared:lib"],
"targets": {
"build": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"main": "libs/shared/monitoring/src/index.ts",
"outputPath": "dist/libs/shared/monitoring",
"outputFileName": "main.js",
"tsConfig": "libs/shared/monitoring/tsconfig.lib.json",
"declaration": true,
"external": [
"@nestjs/websockets/socket-module",
"@nestjs/microservices/microservices-module",
"@nestjs/microservices"
],
"assets": [
{
"glob": "libs/shared/monitoring/README.md",
"input": ".",
"output": "."
}
],
"platform": "node"
},
"configurations": {
"development": {
"minify": false
},
"production": {
"minify": true
}
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/shared/monitoring/**/*.ts"]
}
},
"test-unit": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/shared/monitoring/jest.config.ts"
}
}
}
}
95 changes: 95 additions & 0 deletions libs/shared/monitoring/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { initTracing } from '@fxa/shared/otel';
import { initSentry } from '@fxa/shared/sentry-node';
import { initMonitoring } from './index';

jest.mock('@fxa/shared/otel', () => ({ initTracing: jest.fn() }));
jest.mock('@fxa/shared/sentry-node', () => ({ initSentry: jest.fn() }));

describe('shared-monitoring', () => {
beforeEach(() => {
jest.resetAllMocks();
jest.resetModules();
});

it('initializes tracing and sentry when config contains them', () => {
const log = {
info: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
debug: jest.fn(),
};
const opts = {
log,
config: {
sentry: { dsn: 'https://example.com' },
tracing: {
enabled: true,
serviceName: 'test',
batchSpanProcessor: true,
clientName: 'test-client',
corsUrls: 'http://localhost:\\d*/',
filterPii: true,
sampleRate: 1,
batchProcessor: false,
},
},
};

initMonitoring(opts);

expect(initTracing).toHaveBeenCalledWith(opts.config.tracing, log);
expect(initSentry).toHaveBeenCalledWith(opts.config, log);
});

it('does not call tracing or sentry when not configured', () => {
const log = {
warn: jest.fn(),
error: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
};
const opts = { log, config: {} };

initMonitoring(opts);

expect(initTracing).not.toHaveBeenCalled();
expect(initSentry).not.toHaveBeenCalled();
});

it('warns and skips when initialized more than once', () => {
const log = {
warn: jest.fn(),
error: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
};
const opts = {
log,
config: {
sentry: { dsn: 'https://example.com' },
tracing: {
enabled: true,
serviceName: 'test',
batchSpanProcessor: true,
clientName: 'test-client',
corsUrls: 'http://localhost:\\d*/',
filterPii: true,
sampleRate: 1,
batchProcessor: false,
},
},
};

initMonitoring(opts);
initMonitoring(opts);

expect(log.warn).toHaveBeenCalledWith(
'monitoring',
'Monitoring can only be initialized once'
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { initTracing } from '../tracing/node-tracing';
import { InitSentryOpts, initSentry } from '../sentry/node';
import { TracingOpts } from '../tracing/config';
import { ILogger } from '../log';
import { initTracing } from '@fxa/shared/otel';
import { initSentry } from '@fxa/shared/sentry-node';
import { TracingOpts } from '@fxa/shared/otel';
import { ILogger } from '@fxa/shared/log';
import { InitSentryOpts } from '@fxa/shared/sentry-utils';

export type MonitoringConfig = {
log?: ILogger;
config: InitSentryOpts & { tracing: TracingOpts };
config: InitSentryOpts & { tracing?: TracingOpts };
};

let initialized = false;

/**
* IMPORTANT! This initialization function must be called first thing when a server starts. If it's called after server
* frameworks initialized instrumentation might not work properly.
*/

/**
* Initializes modules related to error monitoring, performance monitoring, and tracing.
* @param opts - Initialization options. See underlying implementations for more details.
*
* IMPORTANT: This function must be called as early as possible during server startup, before
* any server framework (e.g. Hapi, Express) registers its own instrumentation. Calling it
* after framework initialization may result in incomplete or broken tracing.
*
* Initialization is guarded so that calling this function more than once is a no-op (a
* warning is emitted on subsequent calls).
*
* @param opts - Monitoring initialization options, including an optional logger and a config
* object that may contain both Sentry and tracing settings.
*/
export function initMonitoring(opts: MonitoringConfig) {
const { log: logger, config } = opts;
Expand Down Expand Up @@ -62,7 +67,7 @@ export function initMonitoring(opts: MonitoringConfig) {
nodeTracingInitialized = !!initTracing(config.tracing, log);
}

// Important! Order matters here. If otel is configured, this shoudl be done after OTEL initialization!
// Important! Order matters here. If OTEL is configured, Sentry must be initialized after OTEL.
if (config && config.sentry) {
if (nodeTracingInitialized) {
config.sentry.skipOpenTelemetrySetup = true;
Expand Down
16 changes: 16 additions & 0 deletions libs/shared/monitoring/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs"
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
11 changes: 11 additions & 0 deletions libs/shared/monitoring/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}
14 changes: 14 additions & 0 deletions libs/shared/monitoring/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
23 changes: 20 additions & 3 deletions libs/shared/otel/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,30 @@
"build": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/libs/shared/otel",
"main": "libs/shared/otel/src/index.ts",
"outputPath": "dist/libs/shared/otel",
"outputFileName": "main.js",
"tsConfig": "libs/shared/otel/tsconfig.lib.json",
"assets": ["libs/shared/otel/*.md"],
"declaration": true,
"platform": "node"
"assets": [
{
"glob": "libs/shared/otel/README.md",
"input": ".",
"output": "."
}
],
"platform": "node",
"format": ["cjs", "esm"]
},
"configurations": {
"development": {
"minify": false
},
"production": {
"minify": true
}
}
},
"test-unit": {
Expand Down
Loading
Loading