Skip to content

Commit 89967ee

Browse files
authored
feat: Add browser-telemetry API types. (#669)
Add API surface for browser telemetry. Review after: #659
1 parent 37920e5 commit 89967ee

File tree

8 files changed

+479
-0
lines changed

8 files changed

+479
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/**
2+
* Defines the 'class' of the breadcrumb.
3+
*/
4+
export type BreadcrumbClass =
5+
| 'custom'
6+
| 'log'
7+
| 'navigation'
8+
| 'feature-management'
9+
| 'ui'
10+
| 'http';
11+
12+
/**
13+
* Indicates the severity of the breadcrumb.
14+
*/
15+
export type BreadcrumbLevel = 'error' | 'warning' | 'info' | 'debug';
16+
17+
/**
18+
* Types of data support with breadcrumbs.
19+
*/
20+
export type BreadcrumbDataValue = boolean | number | string;
21+
22+
/**
23+
* Defines arbitrary data that may be associated with a breadcrumb.
24+
*/
25+
export type BreadcrumbData = Record<string, BreadcrumbDataValue>;
26+
27+
/**
28+
* Interface which defines a breadcrumb.
29+
*/
30+
export interface Breadcrumb {
31+
/**
32+
* The class of the breadcrumb. This is the top level categorization of breadcrumbs.
33+
*/
34+
class: BreadcrumbClass;
35+
36+
/**
37+
* When the event associated with the breadcrumb happened. The timestamp is in milliseconds since January 1, 1970
38+
* Universal Coordinated Time (UTC)
39+
*
40+
* For most breadcrumbs this will not be different than the time of breadcrumb creation, but if there is a delay
41+
* between the event and breadcrumb capture, then the time of the event should be used instead.
42+
*/
43+
timestamp: number;
44+
45+
/**
46+
* The level of severity of the breadcrumb. The default choice of level should be `info` if there isn't a clear
47+
* reason to use a different level.
48+
*/
49+
level: BreadcrumbLevel;
50+
51+
/**
52+
* The type of the breadcrumb. Each class may be split into multiple types with the type more specifically
53+
* categorizing the type of event.
54+
*/
55+
type?: string;
56+
57+
/**
58+
* A message associated with the breadcrumb.
59+
*/
60+
message?: string;
61+
62+
/**
63+
* Any data associated with the breadcrumb.
64+
*/
65+
data?: BreadcrumbData;
66+
}
67+
68+
/**
69+
* Utility type which allows for easy extension of base breadcrumb type.
70+
*/
71+
type ImplementsCrumb<U extends Breadcrumb> = U;
72+
73+
/**
74+
* Type for custom breadcrumbs.
75+
*/
76+
export type CustomBreadcrumb = ImplementsCrumb<{
77+
class: 'custom';
78+
timestamp: number;
79+
level: BreadcrumbLevel;
80+
type?: string;
81+
message?: string;
82+
data?: BreadcrumbData;
83+
}>;
84+
85+
/**
86+
* Type for log breadcrumbs.
87+
*/
88+
export type LogBreadcrumb = ImplementsCrumb<{
89+
class: 'log';
90+
timestamp: number;
91+
level: BreadcrumbLevel;
92+
message: string;
93+
data?: BreadcrumbData;
94+
}>;
95+
96+
/**
97+
* Type for navigation breadcrumbs.
98+
*/
99+
export type NavigationBreadcrumb = ImplementsCrumb<{
100+
class: 'navigation';
101+
timestamp: number;
102+
level: 'info';
103+
type?: string;
104+
data?: {
105+
/**
106+
* The location being navigated from. In a web application this would typically be a URL.
107+
*/
108+
from?: string;
109+
/**
110+
* The location being navigated to. In a web application this would typically be a URL.
111+
*/
112+
to?: string;
113+
};
114+
}>;
115+
116+
/**
117+
* Type for feature management breadcrumbs.
118+
*/
119+
export type FeatureManagementBreadcrumb = ImplementsCrumb<{
120+
class: 'feature-management';
121+
timestamp: number;
122+
level: 'info';
123+
type: 'flag-evaluated' | 'flag-detail-changed';
124+
data?: {
125+
/**
126+
* The flag key.
127+
*/
128+
key?: string;
129+
// Not supporting JSON flags in breadcrumbs. As noted in design we may want to eventually support none of the
130+
// values in the breadcrumb.
131+
/**
132+
* The evaluated value for simple types.
133+
*/
134+
value?: boolean | string | number;
135+
};
136+
}>;
137+
138+
/**
139+
* Type for UI breadcrumbs.
140+
*/
141+
export type UiBreadcrumb = ImplementsCrumb<{
142+
class: 'ui';
143+
timestamp: number;
144+
level: 'info';
145+
type: 'click' | 'input';
146+
message: string;
147+
}>;
148+
149+
/**
150+
* Type for HTTP breadcrumbs.
151+
*/
152+
export type HttpBreadcrumb = ImplementsCrumb<{
153+
class: 'http';
154+
timestamp: number;
155+
level: 'error' | 'info'; // Error if an error status code?
156+
type: 'xhr' | 'fetch';
157+
data?: {
158+
url?: string;
159+
method?: string;
160+
statusCode: number;
161+
statusText: string;
162+
};
163+
}>;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { LDClient, LDInspection } from 'launchdarkly-js-client-sdk';
2+
3+
import { Recorder } from './Recorder';
4+
5+
/**
6+
* Interface LaunchDarkly browser telemetry.
7+
*/
8+
export interface BrowserTelemetry extends Recorder {
9+
/**
10+
* Get inspectors to use with the LaunchDarkly client.
11+
*/
12+
inspectors(): LDInspection[];
13+
14+
// TODO: Consider hooks as well. Hooks will allow registration to happen in a
15+
// single step.
16+
17+
/**
18+
* Register the telemetry instance with the LaunchDarkly client.
19+
*
20+
* @param client The LaunchDarkly client.
21+
*/
22+
register(client: LDClient): void;
23+
24+
/**
25+
* Close the telemetry client.
26+
*/
27+
close(): void;
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Recorder } from './Recorder';
2+
3+
/**
4+
* Interface to be implemented by collectors.
5+
*
6+
* Collectors collect data and inform the client of events.
7+
*
8+
* For instance a collector may notify the telemetry instance of HTTP navigation
9+
* or of UI events. A collector can be created independently of a {@link Recorder}
10+
* and can begin collecting immediately. It may queue information until it can
11+
* be registered with a recorder.
12+
*/
13+
export interface Collector {
14+
/**
15+
* Register the collector with a recorder.
16+
* @param recorder Recorder to report events or breadcrumbs to.
17+
* @param sessionId The current session ID.
18+
*/
19+
register(recorder: Recorder, sessionId: string): void;
20+
21+
/**
22+
* Unregister the collector. It will stop sending events to the recorder.
23+
*/
24+
unregister(): void;
25+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Breadcrumb } from './Breadcrumb';
2+
import StackTrace from './stack/StackTrace';
3+
4+
/**
5+
* Interface representing error data.
6+
*/
7+
export interface ErrorData {
8+
/**
9+
* The type of the error.
10+
*/
11+
12+
type: string;
13+
/**
14+
* A message associated with the error.
15+
*/
16+
17+
message: string;
18+
/**
19+
* The stack trace for the error.
20+
*/
21+
22+
stack: StackTrace;
23+
/**
24+
* Breadcrumbs leading up to the error.
25+
*/
26+
27+
breadcrumbs: Breadcrumb[];
28+
/**
29+
* The ID of the session during which the error occurred.
30+
*/
31+
sessionId: string;
32+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { Collector } from './Collector';
2+
3+
/**
4+
* Interface for URL filters.
5+
*
6+
* Given a URL the filter may return a different string to represent that URL.
7+
* This string will be included in the telemetry events instead of the original.
8+
*
9+
* The URL will be filtered by SDK internal filters before this function is called.
10+
*
11+
* To redact a URL entirely return an empty string.
12+
*
13+
* Example:
14+
* customUrlFilter: (url) => {
15+
* if (url.includes('secret')) {
16+
* return ''
17+
* }
18+
* return url;
19+
* }
20+
*/
21+
export interface UrlFilter {
22+
(url: string): string;
23+
}
24+
25+
export interface HttpBreadCrumbOptions {
26+
/**
27+
* If fetch should be instrumented and breadcrumbs included for fetch requests.
28+
*
29+
* Defaults to true.
30+
*/
31+
instrumentFetch?: boolean;
32+
33+
/**
34+
* If XMLHttpRequests should be instrumented and breadcrumbs included for XMLHttpRequests.
35+
*
36+
* Defaults to true.
37+
*/
38+
instrumentXhr?: boolean;
39+
40+
/**
41+
* Customize URL filtering. This will be applied in addition to some baseline filtering included
42+
* which redacts components of LaunchDarkly URLs.
43+
*/
44+
customUrlFilter?: UrlFilter;
45+
}
46+
47+
export interface StackOptions {
48+
/**
49+
* Configuration that controls how source is captured.
50+
*/
51+
source?: {
52+
/**
53+
* The number of lines captured before the originating line.
54+
*
55+
* Defaults to 3.
56+
*/
57+
beforeLines?: number;
58+
/**
59+
* The number of lines captured after the originating line.
60+
*
61+
* Defaults to 3.
62+
*/
63+
afterLines?: number;
64+
65+
/**
66+
* The maximum length of source line to include. Lines longer than this will be
67+
* trimmed.
68+
*
69+
* Defaults to 280.
70+
*/
71+
maxLineLength?: number;
72+
};
73+
}
74+
75+
/**
76+
* Options for configuring browser telemetry.
77+
*/
78+
export interface Options {
79+
/**
80+
* The maximum number of pending events. Events may be captured before the LaunchDarkly
81+
* SDK is initialized and these are stored until they can be sent. This only affects the
82+
* events captured during initialization.
83+
*/
84+
maxPendingEvents?: number;
85+
/**
86+
* Properties related to automatic breadcrumb collection.
87+
*/
88+
breadcrumbs?: {
89+
/**
90+
* Set the maximum number of breadcrumbs. Defaults to 50.
91+
*/
92+
maxBreadcrumbs?: number;
93+
94+
/**
95+
* True to enable automatic evaluation breadcrumbs. Defaults to true.
96+
*/
97+
evaluations?: boolean;
98+
99+
/**
100+
* True to enable flag change breadcrumbs. Defaults to true.
101+
*/
102+
flagChange?: boolean;
103+
104+
/**
105+
* True to enable click breadcrumbs. Defaults to true.
106+
*/
107+
click?: boolean;
108+
109+
/**
110+
* True to enable input breadcrumbs for keypresses. Defaults to true.
111+
*
112+
* Input breadcrumbs do not include entered text, just that text was entered.
113+
*/
114+
keyboardInput?: boolean;
115+
116+
/**
117+
* Controls instrumentation and breadcrumbs for HTTP requests.
118+
* The default is to instrument XMLHttpRequests and fetch requests.
119+
*
120+
* `false` to disable all HTTP breadcrumbs and instrumentation.
121+
*
122+
* Example:
123+
* ```
124+
* // This would instrument only XmlHttpRequests
125+
* http: {
126+
* instrumentFetch: false
127+
* instrumentXhr: true
128+
* }
129+
*
130+
* // Disable all HTTP instrumentation:
131+
* http: false
132+
* ```
133+
*/
134+
http?: HttpBreadCrumbOptions | false;
135+
};
136+
137+
/**
138+
* Additional, or custom, collectors.
139+
*/
140+
collectors?: Collector[];
141+
142+
/**
143+
* Configuration that controls the capture of the stack trace.
144+
*/
145+
stack?: StackOptions;
146+
}

0 commit comments

Comments
 (0)