Skip to content

Commit b41c104

Browse files
committed
feat(rum): Capture browser navigator information
1 parent ce16e33 commit b41c104

File tree

3 files changed

+95
-1
lines changed

3 files changed

+95
-1
lines changed

packages/tracing/src/browser/metrics.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,23 @@ import { Transaction } from '../transaction';
88
import { msToSec } from '../utils';
99
import { getFID } from './web-vitals/getFID';
1010
import { getLCP } from './web-vitals/getLCP';
11+
import { NavigatorDeviceMemory, NavigatorNetworkInformation } from './web-vitals/types';
1112

1213
const global = getGlobalObject<Window>();
1314

15+
type FooNavigator = Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory;
16+
17+
type BrowserContext = {
18+
effectiveConnectionType?: string;
19+
deviceMemory?: number;
20+
// number of CPUs
21+
hardwareConcurrency?: number;
22+
};
23+
1424
/** Class tracking metrics */
1525
export class MetricsInstrumentation {
1626
private _measurements: Measurements = {};
27+
private _browserContext: BrowserContext = {};
1728

1829
private _performanceCursor: number = 0;
1930

@@ -25,6 +36,7 @@ export class MetricsInstrumentation {
2536

2637
this._trackLCP();
2738
this._trackFID();
39+
this._trackNavigator();
2840
}
2941
}
3042

@@ -122,10 +134,44 @@ export class MetricsInstrumentation {
122134

123135
// Measurements are only available for pageload transactions
124136
if (transaction.op === 'pageload') {
137+
this._trackNavigator();
138+
transaction.setContexts({ browser: this._browserContext });
125139
transaction.setMeasurements(this._measurements);
126140
}
127141
}
128142

143+
/**
144+
* Capture the information of the user agent.
145+
*/
146+
private _trackNavigator(): void {
147+
const navigator = window.navigator as null | FooNavigator;
148+
149+
// track network connectivity
150+
151+
const connection = navigator?.connection;
152+
if (connection) {
153+
if (connection.effectiveType) {
154+
this._browserContext.effectiveConnectionType = connection.effectiveType;
155+
}
156+
157+
if (typeof connection.rtt === 'number') {
158+
this._measurements['connection.rtt'] = { value: connection.rtt };
159+
}
160+
161+
if (typeof connection.downlink === 'number') {
162+
this._measurements['connection.downlink'] = { value: connection.downlink };
163+
}
164+
}
165+
166+
if (typeof navigator?.deviceMemory === 'number') {
167+
this._browserContext.deviceMemory = navigator.deviceMemory;
168+
}
169+
170+
if (typeof navigator?.hardwareConcurrency === 'number') {
171+
this._browserContext.hardwareConcurrency = navigator.hardwareConcurrency;
172+
}
173+
}
174+
129175
/** Starts tracking the Largest Contentful Paint on the current page. */
130176
private _trackLCP(): void {
131177
getLCP(metric => {

packages/tracing/src/browser/web-vitals/types.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,42 @@ export interface Metric {
4343
export interface ReportHandler {
4444
(metric: Metric): void;
4545
}
46+
47+
// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface
48+
export interface NavigatorNetworkInformation {
49+
readonly connection?: NetworkInformation;
50+
}
51+
52+
// http://wicg.github.io/netinfo/#connection-types
53+
type ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';
54+
55+
// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum
56+
type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';
57+
58+
// http://wicg.github.io/netinfo/#dom-megabit
59+
type Megabit = number;
60+
// http://wicg.github.io/netinfo/#dom-millisecond
61+
type Millisecond = number;
62+
63+
// http://wicg.github.io/netinfo/#networkinformation-interface
64+
interface NetworkInformation extends EventTarget {
65+
// http://wicg.github.io/netinfo/#type-attribute
66+
readonly type?: ConnectionType;
67+
// http://wicg.github.io/netinfo/#effectivetype-attribute
68+
readonly effectiveType?: EffectiveConnectionType;
69+
// http://wicg.github.io/netinfo/#downlinkmax-attribute
70+
readonly downlinkMax?: Megabit;
71+
// http://wicg.github.io/netinfo/#downlink-attribute
72+
readonly downlink?: Megabit;
73+
// http://wicg.github.io/netinfo/#rtt-attribute
74+
readonly rtt?: Millisecond;
75+
// http://wicg.github.io/netinfo/#savedata-attribute
76+
readonly saveData?: boolean;
77+
// http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection
78+
onchange?: EventListener;
79+
}
80+
81+
// https://w3c.github.io/device-memory/#sec-device-memory-js-api
82+
export interface NavigatorDeviceMemory {
83+
readonly deviceMemory?: number;
84+
}

packages/tracing/src/transaction.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getCurrentHub, Hub } from '@sentry/hub';
2-
import { Event, Measurements, Transaction as TransactionInterface, TransactionContext } from '@sentry/types';
2+
import { Contexts, Event, Measurements, Transaction as TransactionInterface, TransactionContext } from '@sentry/types';
33
import { isInstanceOf, logger } from '@sentry/utils';
44

55
import { Span as SpanClass, SpanRecorder } from './span';
@@ -8,6 +8,7 @@ import { Span as SpanClass, SpanRecorder } from './span';
88
export class Transaction extends SpanClass implements TransactionInterface {
99
public name: string;
1010
private _measurements: Measurements = {};
11+
private _contexts: Contexts = {};
1112

1213
/**
1314
* The reference to the current hub.
@@ -64,6 +65,13 @@ export class Transaction extends SpanClass implements TransactionInterface {
6465
this._measurements = { ...measurements };
6566
}
6667

68+
/**
69+
*
70+
*/
71+
public setContexts(contexts: Contexts): void {
72+
this._contexts = contexts;
73+
}
74+
6775
/**
6876
* @inheritDoc
6977
*/
@@ -100,6 +108,7 @@ export class Transaction extends SpanClass implements TransactionInterface {
100108

101109
const transaction: Event = {
102110
contexts: {
111+
...this._contexts,
103112
trace: this.getTraceContext(),
104113
},
105114
spans: finishedSpans,

0 commit comments

Comments
 (0)