Crimson Education Browser Logger
A structured logger and analytics reporting utility for browser environments.
This library contains a number of reporters that is will send analytics to.
These must be enabled by calling Logger.init(), as seen below.
Note: This library has been upgraded to support Node.js 22. Some features have been removed or modified during the upgrade process. See the Upgrade Notes section for details.
Install
npm i @crimson-education/browser-logger
or
yarn add @crimson-education/browser-logger
Usage
Initialize
import * as Logger from '@crimson-education/browser-logger';
import { config } from '../configuration';
Logger.init({
service: 'test-project',
environment: config.environment,
version: config.version,
defaultMetadata: {
application: 'test',
},
reporters: {
log: true,
gtm: true,
datadog: {
applicationId: config.datadogApplicationId,
clientToken: config.datadogClientToken,
site: config.datadogSite,
proxyUrl: config.datadogTunnelProxyUrl,
version: config.datadogVersion,
sampleRate: config.environment === 'production' ? 50 : 0,
replaySampleRate: config.environment === 'production' ? 50 : 0,
forwardConsoleLogs: true,
logTransport: {
level: Logger.LogLevel.Info,
},
trackUserInteractions: true,
allowedTrackingOrigins: ['https://my.api.domain'],
},
amplify: {
region: config.awsRegion,
identityPoolId: config.pinpointIdentityPoolId,
analyticsAppId: config.pinpointAnalyticsAppId,
autoTrackEvents: true,
autoTrackPageViews: true,
autoTrackSessions: true,
},
},
});
Logger.setUser({
id: '123',
email: 'billy@brown.com',
name: 'Billy Brown',
});
Logger.recordSession();
Logger.trackEvent({
name: 'App Loaded',
metadata: {
type: 'SPA',
},
});
export const logger = Logger.createLogger();
logger.info('WOW!', {
id: 1,
});
Structured Logging
Structured logging in this library is loosely based on Winston, and follows roughly the same interface as @crimson-education/node-logger.
Call Logger.createLogger() to create a logger instance, it is recommended to re-use this as a global logger everywhere, and then call .child() to reuse metadata.
Global metadata about the service will be added for transport usage after calling Logger.init().
You can add more Global Metadata at any time by calling addMetadata().
export const logger = Logger.createLogger();
const log = logger.child({
from: 'childLog',
});
log.info('My Log', { jobCount: jobs.length });
const timer = log.startTimer();
const result = await job(jobs);
timer.done({ message: 'Job Completed', metadata: { id: result.id } });
Reporting
Opting out of events
You can opt out of sending events to reporters on a global, or per call basis using the endpoints config.
E.g. On calls
Logger.trackEvent({
message: 'my-event',
toReporters: ['log', 'datadog'],
excludeReporters: ['datadog'],
});
E.g. Globally
Logger.init({
reporters: {
log: true,
datadog: {
...
endpoints: {
trackEvent: false,
}
}
}
});
These will only send to the log reporter, it is recommended to use toReporters or excludeReporters separately as they overlap.
Filtering out metadata
You can filter what metadata gets sent to each reporter in the reporter config.
This accepts a string for exact match metadata keys, or a RegExp.
You can use . to traverse metadata.
Logger.init({
reporters: {
log: {
ignoreMetadataPatterns: ['internalError', 'user.email', /error\.stack.*/g],
},
},
});
Filtering out Breadcrumb categories
You can filter what breadcrumbs get sent to reports in the reporter config.
Logger.init({
reporters: {
log: {
ignoreBreadcrumbCategories: [
'fetch'
]
}
}
});
Logger.addBreadcrumb({
...
category: 'fetch',
});
Configure Reporters
Proxies
Some reporters support taking a proxyUrl parameter in their config. When provided, the reporter will send events to the proxyUrl instead of the default destination. This can be useful to get around ad blockers users might have installed. Typically, proxyUrl should point to our internal proxy service--a shared service that forwards requests it receives to a third-party system.
Our internal proxy service is defined in our crimson-infrastructure repository.
Log
By default, the log reporter is enabled. This adds all reporter functions to logs. Set reporters.log to false to disable reporter logging.
import { config } from '../configuration';
import * as Logger from '@crimson-education/browser-logger';
Logger.init({
reporters: {
log: {
trackEventLevel: Logger.LogInfo.Debug,
endpoints: {
recordSession: false,
recordSessionStop: false,
},
},
},
});
Check out the DatadogReporterConfig for all of the configuration you can apply to Datadog reporting.
Datadog
To configure Datadog, this requires at least applicationId, clientToken and site (As we use an EU instance).
import { config } from '../configuration';
import * as Logger from '@crimson-education/browser-logger';
Logger.init({
reporters: {
datadog: {
applicationId: config.datadogApplicationId,
clientToken: config.datadogClientToken,
site: config.datadogSite,
proxyUrl: config.datadogTunnelProxyUrl,
version: config.datadogVersion,
sampleRate: config.environment === 'production' ? 50 : 0,
replaySampleRate: config.environment === 'production' ? 50 : 0,
forwardConsoleLogs: true,
logTransport: {
level: Logger.LogLevel.Info,
},
trackUserInteractions: true,
allowedTrackingOrigins: ['https://my.api.domain'],
},
},
});
Check out the DatadogReporterConfig for all of the configuration you can apply to Datadog reporting.
This automatically adds a Datadog Log Transport that transmits Log data to Datadog, this can be customized in DatadogReporterConfig with logTransport, or disabled by setting logTransport to false.
Amplify/Pinpoint
To configure Amplify, this requires at least region, identityPoolId and analyticsAppId.
Note: If you are setting up Browser Logger in a project that uses AWS Cognito or other AWS Amplify Features, you will want to set identityPoolId to false. This disables the reporter's call to Auth.configure, as you will have used that to configure your App already.
You will need to set identityPoolId in your Auth.configure function yourself, otherwise Pinpoint won't work.
Auto Auth.configure:
import { config } from '../configuration';
import * as Logger from '@crimson-education/browser-logger';
Logger.init({
reporters: {
amplify: {
region: config.amplifyAwsRegion,
analyticsAppId: config.pinpointAnalyticsAppId,
identityPoolId: config.amplifyIdentityPoolId,
autoTrackEvents: true,
autoTrackPageViews: true,
autoTrackSessions: true,
},
},
});
Manual Auth.configure:
import { Auth } from '@aws-amplify/auth';
import { config } from '../configuration';
import * as Logger from '@crimson-education/browser-logger';
Auth.configure({
region: config.cognitoRegion,
userPoolId: config.cognitoUserPoolId,
userPoolWebClientId: config.cognitoClientId,
identityPoolId: config.amplifyIdentityPoolId,
});
Logger.init({
reporters: {
amplify: {
region: config.amplifyAwsRegion,
analyticsAppId: config.pinpointAnalyticsAppId,
identityPoolId: false,
autoTrackEvents: true,
autoTrackPageViews: true,
autoTrackSessions: true,
},
},
});
Check out the AmplifyReporterConfig for all of the configuration you can apply to Amplify reporting.
Google Tag Manager
To configure GTM, you will need to have loaded the GTM script into your App.
See: https://support.google.com/tagmanager/answer/6103696?hl=en
import { config } from '../configuration';
import * as Logger from '@crimson-education/browser-logger';
Logger.init({
reporters: {
gtm: true,
},
});
Logger.init({
reporters: {
gtm: {
ignoreBreadcrumbCategories: ['fetch'],
},
},
});
Check out the GTMReporterConfig for all of the configuration you can apply to Google Tag Manager reporting.
Functions
See the src/logger/index.ts file for all exported functions of the Logger.
See the src/reporter/index.ts file for all exported functions of the Reporter.
Improve Session Tracking with Component names
You can improve the name of components in analytics tools like Datadog and Amplify use, instead of the content of a component.
This is valuable if the content is dynamic, e.g. a user's name:
<div data-analytics-name="MyUserName">Billy Brown</div>
This will result in the session saying something like, clicked on "MyUserName".
Upgrade Notes
Node.js 22 Upgrade Changes
This library has been upgraded to support Node.js 22. The following changes were made during the upgrade process:
Datadog Reporter Changes
trackInteractions → trackUserInteractions (renamed for clarity)
trackFrustrations → Removed (replaced with custom frustration detection implementation)
allowedTracingOrigins → allowedTrackingOrigins (corrected spelling)
Amplify Reporter Changes
- Updated to use Amplify Gen2 APIs (
@aws-amplify/analytics@7.x, @aws-amplify/auth@6.x)
- Enhanced auto-tracking capabilities for page views, user interactions, and session state
- Improved error handling and configuration validation
Removed Features
The following features were removed during the upgrade and have been replaced with custom implementations:
Configuration Updates Required
If you're upgrading from a previous version, update your configuration:
datadog: {
trackInteractions: true,
trackFrustrations: true,
allowedTracingOrigins: ['https://my.api.domain']
}
datadog: {
trackUserInteractions: true,
allowedTrackingOrigins: ['https://my.api.domain']
}
For more details about the upgrade process and custom implementations, see the individual reporter configuration files.