@crimson-education/browser-logger 5.0.3 → 5.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/lib/reporters/analyticsNoise.d.ts +2 -0
- package/lib/reporters/analyticsNoise.d.ts.map +1 -0
- package/lib/reporters/analyticsNoise.js +13 -0
- package/lib/reporters/analyticsNoise.js.map +1 -0
- package/lib/reporters/datadogReporter.d.ts +10 -0
- package/lib/reporters/datadogReporter.d.ts.map +1 -1
- package/lib/reporters/datadogReporter.js +99 -36
- package/lib/reporters/datadogReporter.js.map +1 -1
- package/lib/reporters/datadogReporter.test.d.ts +2 -0
- package/lib/reporters/datadogReporter.test.d.ts.map +1 -0
- package/lib/reporters/datadogReporter.test.js +163 -0
- package/lib/reporters/datadogReporter.test.js.map +1 -0
- package/lib/reporters/posthogReporter.d.ts.map +1 -1
- package/lib/reporters/posthogReporter.js +26 -3
- package/lib/reporters/posthogReporter.js.map +1 -1
- package/lib/reporters/posthogReporter.test.js +116 -0
- package/lib/reporters/posthogReporter.test.js.map +1 -1
- package/lib/types/reporter.d.ts +5 -0
- package/lib/types/reporter.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/reporters/analyticsNoise.ts +15 -0
- package/src/reporters/datadogReporter.test.ts +229 -0
- package/src/reporters/datadogReporter.ts +117 -44
- package/src/reporters/posthogReporter.test.ts +154 -0
- package/src/reporters/posthogReporter.ts +31 -4
- package/src/types/reporter.ts +6 -0
|
@@ -14,6 +14,7 @@ import { datadogLogs, HandlerType, LogsInitConfiguration } from '@datadog/browse
|
|
|
14
14
|
import { datadogRum, DefaultPrivacyLevel, RumInitConfiguration } from '@datadog/browser-rum';
|
|
15
15
|
import { logTransports } from '../logger';
|
|
16
16
|
import { DatadogLogTransportConfig, datadogTransport } from '../logger/datadogTransport';
|
|
17
|
+
import { shouldSuppressAnalyticsEvent } from './analyticsNoise';
|
|
17
18
|
|
|
18
19
|
// User frustration detection for Datadog Gen2
|
|
19
20
|
class DatadogFrustrationDetector {
|
|
@@ -105,6 +106,16 @@ class DatadogFrustrationDetector {
|
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
export interface DatadogReporterConfig extends ReporterConfigBase {
|
|
109
|
+
/**
|
|
110
|
+
* Enable Datadog Browser Logs initialization and log transport wiring.
|
|
111
|
+
* Defaults to true.
|
|
112
|
+
*/
|
|
113
|
+
logsEnabled?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Enable Datadog Browser RUM initialization.
|
|
116
|
+
* Defaults to true.
|
|
117
|
+
*/
|
|
118
|
+
rumEnabled?: boolean;
|
|
108
119
|
/** The RUM application ID. */
|
|
109
120
|
applicationId: string;
|
|
110
121
|
/** A Datadog client token (Generated in the RUM Page) */
|
|
@@ -241,6 +252,8 @@ export interface DatadogReporterConfig extends ReporterConfigBase {
|
|
|
241
252
|
|
|
242
253
|
export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig): IReporter {
|
|
243
254
|
const isLocalhost = window.location.hostname === 'localhost';
|
|
255
|
+
const logsEnabled = config.logsEnabled ?? true;
|
|
256
|
+
const rumEnabled = config.rumEnabled ?? true;
|
|
244
257
|
|
|
245
258
|
// Don't forward error logs by default, do enable the log transport by default
|
|
246
259
|
// forwardErrorsToLogs incorrectly is called forwardConsoleLogs, this is for backwards compatibility
|
|
@@ -248,7 +261,7 @@ export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig
|
|
|
248
261
|
const enableLogTransport = config.logTransport !== false;
|
|
249
262
|
|
|
250
263
|
// Only init datadog logs if something is using it.
|
|
251
|
-
if (forwardErrorsToLogs === true || enableLogTransport === true) {
|
|
264
|
+
if (logsEnabled && (forwardErrorsToLogs === true || enableLogTransport === true)) {
|
|
252
265
|
datadogLogs.init({
|
|
253
266
|
site: config.site as any,
|
|
254
267
|
clientToken: config.clientToken,
|
|
@@ -270,45 +283,67 @@ export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig
|
|
|
270
283
|
}
|
|
271
284
|
|
|
272
285
|
// Add the datadog log transport
|
|
273
|
-
if (enableLogTransport) {
|
|
286
|
+
if (logsEnabled && enableLogTransport) {
|
|
274
287
|
logTransports.push(datadogTransport(typeof config.logTransport === 'boolean' ? {} : config.logTransport));
|
|
275
288
|
}
|
|
276
289
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
290
|
+
if (rumEnabled) {
|
|
291
|
+
datadogRum.init({
|
|
292
|
+
enableExperimentalFeatures: ['feature_flags'],
|
|
293
|
+
site: config.site as any,
|
|
294
|
+
clientToken: config.clientToken,
|
|
295
|
+
applicationId: config.applicationId,
|
|
296
|
+
service: info.service,
|
|
297
|
+
env: info.environment,
|
|
298
|
+
version: config.version ?? info.version,
|
|
299
|
+
|
|
300
|
+
usePartitionedCrossSiteSessionCookie: config.usePartitionedCrossSiteSessionCookie,
|
|
301
|
+
// Use correct Datadog v6 SDK options
|
|
302
|
+
sessionSampleRate: config.sessionSampleRate ?? config.rumSampleRate ?? config.sampleRate ?? 100,
|
|
303
|
+
sessionReplaySampleRate: config.sessionReplaySampleRate ?? config.replaySampleRate ?? 100,
|
|
304
|
+
|
|
305
|
+
// Track interactions (Note: trackFrustrations is not available in Datadog v6)
|
|
306
|
+
trackUserInteractions: config.trackUserInteractions ?? config.trackInteractions ?? false,
|
|
307
|
+
|
|
308
|
+
useSecureSessionCookie: config.useSecureSessionCookie ?? !isLocalhost,
|
|
309
|
+
// Note: useCrossSiteSessionCookie is not available in newer Datadog versions
|
|
310
|
+
trackSessionAcrossSubdomains: config.trackSessionAcrossSubdomains,
|
|
311
|
+
trackViewsManually: config.trackViewsManually ?? false,
|
|
312
|
+
actionNameAttribute: config.actionNameAttribute ?? 'data-analytics-name',
|
|
313
|
+
beforeSend: config.beforeSend,
|
|
314
|
+
|
|
315
|
+
defaultPrivacyLevel: config.defaultPrivacyLevel ?? 'mask-user-input',
|
|
316
|
+
allowedTracingUrls: config.allowedTracingUrls ?? config.allowedTrackingOrigins,
|
|
317
|
+
|
|
318
|
+
excludedActivityUrls: config.excludedActivityUrls,
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Initialize frustration detector
|
|
322
|
+
new DatadogFrustrationDetector(config);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function normalizeErrorForLogs(error: ReportError) {
|
|
326
|
+
if (error instanceof Error) {
|
|
327
|
+
return {
|
|
328
|
+
message: error.message,
|
|
329
|
+
name: error.name,
|
|
330
|
+
stack: error.stack,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
message: String(error),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
309
338
|
|
|
310
339
|
const reporter: IReporter = {
|
|
311
340
|
trackEvent: function (event: ReporterEvent): void {
|
|
341
|
+
if (!rumEnabled) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (shouldSuppressAnalyticsEvent(event.message, config.ignoreTrackEventPatterns)) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
312
347
|
datadogRum.addAction(event.message, {
|
|
313
348
|
level: event.level,
|
|
314
349
|
...event.metadata,
|
|
@@ -317,6 +352,9 @@ export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig
|
|
|
317
352
|
});
|
|
318
353
|
},
|
|
319
354
|
addBreadcrumb: function (breadcrumb: ReporterBreadcrumb): void {
|
|
355
|
+
if (!rumEnabled) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
320
358
|
datadogRum.addAction(breadcrumb.message, {
|
|
321
359
|
...breadcrumb.metadata,
|
|
322
360
|
category: breadcrumb.category,
|
|
@@ -325,20 +363,29 @@ export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig
|
|
|
325
363
|
addMetadata: function (metadata: Metadata): void {
|
|
326
364
|
for (const [key, value] of Object.entries(metadata)) {
|
|
327
365
|
if (value !== null) {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
366
|
+
if (rumEnabled) {
|
|
367
|
+
datadogRum.setGlobalContextProperty(key, value);
|
|
368
|
+
}
|
|
369
|
+
if (logsEnabled) {
|
|
370
|
+
// Note, this will add duplicate context data in logs.
|
|
371
|
+
// But this is valuable for logs ingested outside of the browser logger.
|
|
372
|
+
datadogLogs.setGlobalContextProperty(key, value);
|
|
373
|
+
}
|
|
333
374
|
} else {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
375
|
+
if (rumEnabled) {
|
|
376
|
+
datadogRum.removeGlobalContextProperty(key);
|
|
377
|
+
}
|
|
378
|
+
if (logsEnabled) {
|
|
379
|
+
// But this is valuable for logs ingested outside of the browser logger.
|
|
380
|
+
datadogLogs.removeGlobalContextProperty(key);
|
|
381
|
+
}
|
|
338
382
|
}
|
|
339
383
|
}
|
|
340
384
|
},
|
|
341
385
|
setUser: function (user: ReportUser | null): void {
|
|
386
|
+
if (!rumEnabled) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
342
389
|
if (user) {
|
|
343
390
|
datadogRum.setUser({
|
|
344
391
|
...user,
|
|
@@ -351,9 +398,15 @@ export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig
|
|
|
351
398
|
}
|
|
352
399
|
},
|
|
353
400
|
setRouteName: function (routeName: string): void {
|
|
401
|
+
if (!rumEnabled) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
354
404
|
reporter.addMetadata({ routeName });
|
|
355
405
|
},
|
|
356
406
|
setPageName: function (pageName: string): void {
|
|
407
|
+
if (!rumEnabled) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
357
410
|
if (config.trackViewsManually) {
|
|
358
411
|
datadogRum.startView(pageName);
|
|
359
412
|
} else {
|
|
@@ -361,15 +414,35 @@ export function datadogReporter(info: ServiceInfo, config: DatadogReporterConfig
|
|
|
361
414
|
}
|
|
362
415
|
},
|
|
363
416
|
reportError: function (error: ReportError, metadata?: Metadata): void {
|
|
364
|
-
|
|
417
|
+
if (rumEnabled) {
|
|
418
|
+
datadogRum.addError(error, metadata);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (logsEnabled) {
|
|
422
|
+
const normalized = normalizeErrorForLogs(error);
|
|
423
|
+
datadogLogs.logger.error(normalized.message, {
|
|
424
|
+
...metadata,
|
|
425
|
+
errorName: normalized.name,
|
|
426
|
+
errorStack: normalized.stack,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
365
429
|
},
|
|
366
430
|
reportFeatureFlag: function (flag: ReporterFlag): void {
|
|
431
|
+
if (!rumEnabled) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
367
434
|
datadogRum.addFeatureFlagEvaluation(flag.name, flag.value);
|
|
368
435
|
},
|
|
369
436
|
recordSession: function (): void {
|
|
437
|
+
if (!rumEnabled) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
370
440
|
datadogRum.startSessionReplayRecording();
|
|
371
441
|
},
|
|
372
442
|
recordSessionStop: function (): void {
|
|
443
|
+
if (!rumEnabled) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
373
446
|
datadogRum.stopSessionReplayRecording();
|
|
374
447
|
},
|
|
375
448
|
};
|
|
@@ -154,6 +154,64 @@ describe('posthogReporter', () => {
|
|
|
154
154
|
expect(posthogMock.stopSessionRecording).toHaveBeenCalled();
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
+
it('suppresses configured trackEvent messages from PostHog analytics', () => {
|
|
158
|
+
const reporter = posthogReporter(
|
|
159
|
+
{
|
|
160
|
+
service: 'crimson-app-frontend',
|
|
161
|
+
application: 'crimson-app',
|
|
162
|
+
environment: 'production',
|
|
163
|
+
version: '1.2.3',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
apiKey: 'ph_key',
|
|
167
|
+
apiHost: 'https://eu.i.posthog.com',
|
|
168
|
+
ignoreTrackEventPatterns: ['feedback fetch success'],
|
|
169
|
+
},
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
reporter.trackEvent({
|
|
173
|
+
message: 'feedback fetch success',
|
|
174
|
+
level: LogLevel.Info,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
expect(posthogMock.capture).not.toHaveBeenCalled();
|
|
178
|
+
|
|
179
|
+
reporter.trackEvent({
|
|
180
|
+
message: 'message-sent',
|
|
181
|
+
level: LogLevel.Info,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(posthogMock.capture).toHaveBeenCalledWith('message-sent', {
|
|
185
|
+
message: 'message-sent',
|
|
186
|
+
level: LogLevel.Info,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('does not suppress trackEvent messages unless configured', () => {
|
|
191
|
+
const reporter = posthogReporter(
|
|
192
|
+
{
|
|
193
|
+
service: 'crimson-app-frontend',
|
|
194
|
+
application: 'crimson-app',
|
|
195
|
+
environment: 'production',
|
|
196
|
+
version: '1.2.3',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
apiKey: 'ph_key',
|
|
200
|
+
apiHost: 'https://eu.i.posthog.com',
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
reporter.trackEvent({
|
|
205
|
+
message: 'feedback fetch success',
|
|
206
|
+
level: LogLevel.Info,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
expect(posthogMock.capture).toHaveBeenCalledWith('feedback fetch success', {
|
|
210
|
+
message: 'feedback fetch success',
|
|
211
|
+
level: LogLevel.Info,
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
157
215
|
it('adds compatibility properties in before_send', () => {
|
|
158
216
|
const beforeSend = jest.fn((captureResult) => captureResult);
|
|
159
217
|
|
|
@@ -198,6 +256,102 @@ describe('posthogReporter', () => {
|
|
|
198
256
|
expect(beforeSend).toHaveBeenCalledWith(captureResult);
|
|
199
257
|
});
|
|
200
258
|
|
|
259
|
+
it('uses the current URL for automatic pageviews instead of stale page metadata', () => {
|
|
260
|
+
const reporter = posthogReporter(
|
|
261
|
+
{
|
|
262
|
+
service: 'crimson-app-frontend',
|
|
263
|
+
application: 'crimson-app',
|
|
264
|
+
environment: 'production',
|
|
265
|
+
version: '1.2.3',
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
apiKey: 'ph_key',
|
|
269
|
+
apiHost: 'https://us.i.posthog.com',
|
|
270
|
+
},
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
reporter.setPageName('/calendar/schedule');
|
|
274
|
+
reporter.setRouteName('/calendar');
|
|
275
|
+
|
|
276
|
+
const initConfig = posthogMock.init.mock.calls[0]?.[1];
|
|
277
|
+
const captureResult = initConfig.before_send({
|
|
278
|
+
uuid: 'event-uuid',
|
|
279
|
+
event: '$pageview',
|
|
280
|
+
properties: {
|
|
281
|
+
$current_url: 'https://app.crimsoneducation.org/messages',
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
expect(captureResult.properties).toEqual(
|
|
286
|
+
expect.objectContaining({
|
|
287
|
+
url_path: '/messages',
|
|
288
|
+
url_path_group: '/messages',
|
|
289
|
+
view_name: '/messages',
|
|
290
|
+
}),
|
|
291
|
+
);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it('keeps a matching route template as the automatic pageview path group', () => {
|
|
295
|
+
const reporter = posthogReporter(
|
|
296
|
+
{
|
|
297
|
+
service: 'crimson-app-frontend',
|
|
298
|
+
application: 'crimson-app',
|
|
299
|
+
environment: 'production',
|
|
300
|
+
version: '1.2.3',
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
apiKey: 'ph_key',
|
|
304
|
+
apiHost: 'https://us.i.posthog.com',
|
|
305
|
+
},
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
reporter.setRouteName('/users/:id/roadmap');
|
|
309
|
+
|
|
310
|
+
const initConfig = posthogMock.init.mock.calls[0]?.[1];
|
|
311
|
+
const captureResult = initConfig.before_send({
|
|
312
|
+
uuid: 'event-uuid',
|
|
313
|
+
event: '$pageview',
|
|
314
|
+
properties: {
|
|
315
|
+
$current_url: 'https://app.crimsoneducation.org/users/123/roadmap',
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
expect(captureResult.properties).toEqual(
|
|
320
|
+
expect.objectContaining({
|
|
321
|
+
url_path: '/users/123/roadmap',
|
|
322
|
+
url_path_group: '/users/:id/roadmap',
|
|
323
|
+
view_name: '/users/123/roadmap',
|
|
324
|
+
}),
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('updates page metadata before capturing manual pageviews', () => {
|
|
329
|
+
const reporter = posthogReporter(
|
|
330
|
+
{
|
|
331
|
+
service: 'crimson-app-frontend',
|
|
332
|
+
application: 'crimson-app',
|
|
333
|
+
environment: 'production',
|
|
334
|
+
version: '1.2.3',
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
apiKey: 'ph_key',
|
|
338
|
+
apiHost: 'https://us.i.posthog.com',
|
|
339
|
+
trackViewsManually: true,
|
|
340
|
+
},
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
reporter.setRouteName('/users/:id/roadmap');
|
|
344
|
+
reporter.setPageName('/users/123/roadmap');
|
|
345
|
+
|
|
346
|
+
expect(posthogMock.register).toHaveBeenLastCalledWith({
|
|
347
|
+
pageName: '/users/123/roadmap',
|
|
348
|
+
});
|
|
349
|
+
expect(posthogMock.capture).toHaveBeenCalledWith('$pageview', {
|
|
350
|
+
pageName: '/users/123/roadmap',
|
|
351
|
+
routeName: '/users/:id/roadmap',
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
|
|
201
355
|
it('preserves registered metadata when clearing the user', () => {
|
|
202
356
|
const reporter = posthogReporter(
|
|
203
357
|
{
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
ReportUser,
|
|
11
11
|
ServiceInfo,
|
|
12
12
|
} from '../types';
|
|
13
|
+
import { shouldSuppressAnalyticsEvent } from './analyticsNoise';
|
|
13
14
|
|
|
14
15
|
type PostHogValue = Properties[string];
|
|
15
16
|
|
|
@@ -106,6 +107,20 @@ function getCurrentUrl(captureResult: CaptureResult): string | undefined {
|
|
|
106
107
|
return undefined;
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
function getStringProperty(properties: Properties | undefined, key: string): string | undefined {
|
|
111
|
+
const value = properties?.[key];
|
|
112
|
+
return typeof value === 'string' && value ? value : undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function routeMatchesPath(routeName: string, urlPath: string): boolean {
|
|
116
|
+
const escapedRoute = routeName
|
|
117
|
+
.split('/')
|
|
118
|
+
.map((segment) => (segment.startsWith(':') ? '[^/]+' : segment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
|
|
119
|
+
.join('/');
|
|
120
|
+
|
|
121
|
+
return new RegExp(`^${escapedRoute}/?$`).test(urlPath);
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
function getUserRoleValue(user: CompatibilityUser | null, metadata: Metadata): PostHogValue | undefined {
|
|
110
125
|
const candidate =
|
|
111
126
|
user?.userRole ?? user?.role ?? user?.userRoles ?? user?.roles ?? metadata.userRole ?? metadata.userRoles;
|
|
@@ -123,7 +138,15 @@ function buildCompatibilityProperties(
|
|
|
123
138
|
const baseOrigin = typeof window !== 'undefined' ? window.location.origin : 'https://example.invalid';
|
|
124
139
|
const urlObject = url ? new URL(url, baseOrigin) : null;
|
|
125
140
|
const urlPath = urlObject?.pathname;
|
|
126
|
-
const
|
|
141
|
+
const isPageview = captureResult.event === '$pageview';
|
|
142
|
+
const capturedPageName = getStringProperty(captureResult.properties, 'pageName');
|
|
143
|
+
const metadataPageName = typeof metadata.pageName === 'string' ? metadata.pageName : undefined;
|
|
144
|
+
const pageName = isPageview ? capturedPageName ?? urlPath : metadataPageName;
|
|
145
|
+
const capturedRouteName = getStringProperty(captureResult.properties, 'routeName');
|
|
146
|
+
const metadataRouteName = typeof metadata.routeName === 'string' ? metadata.routeName : undefined;
|
|
147
|
+
const routeName =
|
|
148
|
+
capturedRouteName ??
|
|
149
|
+
(urlPath && metadataRouteName && routeMatchesPath(metadataRouteName, urlPath) ? metadataRouteName : undefined);
|
|
127
150
|
|
|
128
151
|
return {
|
|
129
152
|
app_name: String(metadata.application ?? info.application ?? info.service),
|
|
@@ -139,6 +162,7 @@ function buildCompatibilityProperties(
|
|
|
139
162
|
user_role: getUserRoleValue(user, metadata),
|
|
140
163
|
url,
|
|
141
164
|
url_path: urlPath,
|
|
165
|
+
url_path_group: routeName ?? (isPageview ? urlPath : undefined),
|
|
142
166
|
view_id: posthog.getPageViewId(),
|
|
143
167
|
view_name: pageName,
|
|
144
168
|
browser: captureResult.properties?.$browser,
|
|
@@ -283,6 +307,9 @@ export function posthogReporter(info: ServiceInfo, config: PostHogReporterConfig
|
|
|
283
307
|
const reporter: IReporter = {
|
|
284
308
|
...config,
|
|
285
309
|
trackEvent: function (event: ReporterEvent): void {
|
|
310
|
+
if (shouldSuppressAnalyticsEvent(event.message, config.ignoreTrackEventPatterns)) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
286
313
|
posthog.capture(event.message, {
|
|
287
314
|
message: event.message,
|
|
288
315
|
level: event.level,
|
|
@@ -342,14 +369,14 @@ export function posthogReporter(info: ServiceInfo, config: PostHogReporterConfig
|
|
|
342
369
|
reporter.addMetadata({ routeName });
|
|
343
370
|
},
|
|
344
371
|
setPageName: function (pageName: string): void {
|
|
372
|
+
reporter.addMetadata({ pageName });
|
|
373
|
+
|
|
345
374
|
if (manualPageviews) {
|
|
346
375
|
posthog.capture('$pageview', {
|
|
347
376
|
pageName,
|
|
377
|
+
routeName: typeof currentMetadata.routeName === 'string' ? currentMetadata.routeName : undefined,
|
|
348
378
|
});
|
|
349
|
-
return;
|
|
350
379
|
}
|
|
351
|
-
|
|
352
|
-
reporter.addMetadata({ pageName });
|
|
353
380
|
},
|
|
354
381
|
reportError: function (error: ReportError, metadata?: Metadata): void {
|
|
355
382
|
posthog.captureException(error, {
|
package/src/types/reporter.ts
CHANGED
|
@@ -163,6 +163,12 @@ export interface ReporterConfigBase {
|
|
|
163
163
|
* This is useful to prevent data of no use for the reporter, or if the data keys are too long.
|
|
164
164
|
*/
|
|
165
165
|
ignoreMetadataPatterns?: (string | RegExp)[];
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Ignore specific trackEvent messages from analytics-style reporters.
|
|
169
|
+
* This keeps technical log noise out of product analytics/RUM while preserving log reporter output.
|
|
170
|
+
*/
|
|
171
|
+
ignoreTrackEventPatterns?: (string | RegExp)[];
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
/**
|