Skip to content

Commit 470defb

Browse files
committed
Attach fid to captureError in telemetry
1 parent faee34d commit 470defb

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

packages/telemetry/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"peerDependencies": {
7272
"@firebase/app": "0.x",
7373
"@firebase/app-types": "0.x",
74+
"@firebase/installations": "0.x",
7475
"@types/react": "17.x || 18.x || 19.x",
7576
"react": "17.x || 18.x || 19.x"
7677
},

packages/telemetry/src/api.test.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ const fakeTelemetry: Telemetry = {
6767
appId: APP_ID
6868
}
6969
},
70-
loggerProvider: fakeLoggerProvider
70+
loggerProvider: fakeLoggerProvider,
71+
fid: 'fid-1234'
7172
};
7273

7374
describe('Top level API', () => {
@@ -123,6 +124,7 @@ describe('Top level API', () => {
123124
expect(log.severityNumber).to.equal(SeverityNumber.ERROR);
124125
expect(log.body).to.equal('This is a test error');
125126
expect(log.attributes).to.deep.equal({
127+
'user.id': 'fid-1234',
126128
'error.type': 'TestError',
127129
'error.stack': '...stack trace...'
128130
});
@@ -139,6 +141,7 @@ describe('Top level API', () => {
139141
expect(log.severityNumber).to.equal(SeverityNumber.ERROR);
140142
expect(log.body).to.equal('error with no stack');
141143
expect(log.attributes).to.deep.equal({
144+
'user.id': 'fid-1234',
142145
'error.type': 'Error',
143146
'error.stack': 'No stack trace available'
144147
});
@@ -151,7 +154,9 @@ describe('Top level API', () => {
151154
const log = emittedLogs[0];
152155
expect(log.severityNumber).to.equal(SeverityNumber.ERROR);
153156
expect(log.body).to.equal('a string error');
154-
expect(log.attributes).to.deep.equal({});
157+
expect(log.attributes).to.deep.equal({
158+
"user.id": "fid-1234"
159+
});
155160
});
156161

157162
it('should capture an unknown error type correctly', () => {
@@ -161,7 +166,9 @@ describe('Top level API', () => {
161166
const log = emittedLogs[0];
162167
expect(log.severityNumber).to.equal(SeverityNumber.ERROR);
163168
expect(log.body).to.equal('Unknown error type: number');
164-
expect(log.attributes).to.deep.equal({});
169+
expect(log.attributes).to.deep.equal({
170+
"user.id": "fid-1234"
171+
});
165172
});
166173

167174
it('should propagate trace context', async () => {
@@ -185,6 +192,7 @@ describe('Top level API', () => {
185192
await provider.shutdown();
186193

187194
expect(emittedLogs[0].attributes).to.deep.equal({
195+
'user.id': 'fid-1234',
188196
'error.type': 'TestError',
189197
'error.stack': '...stack trace...',
190198
'logging.googleapis.com/trace': `projects/${PROJECT_ID}/traces/my-trace`,
@@ -209,6 +217,7 @@ describe('Top level API', () => {
209217
expect(emittedLogs.length).to.equal(1);
210218
const log = emittedLogs[0];
211219
expect(log.attributes).to.deep.equal({
220+
'user.id': 'fid-1234',
212221
'error.type': 'TestError',
213222
'error.stack': '...stack trace...',
214223
strAttr: 'string attribute',
@@ -237,6 +246,16 @@ describe('Top level API', () => {
237246

238247
function getFakeApp(): FirebaseApp {
239248
registerTelemetry();
249+
_registerComponent(
250+
new Component(
251+
'installations-internal',
252+
() => ({
253+
getId: () => Promise.resolve('fid-1234'),
254+
getToken: () => Promise.resolve('token-5678')
255+
}),
256+
ComponentType.PRIVATE
257+
)
258+
);
240259
_registerComponent(
241260
new Component(
242261
'app-check-internal',

packages/telemetry/src/api.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ export function captureError(
8787

8888
const customAttributes = attributes || {};
8989

90+
// Set firebase installation ID ("FID") if available, which
91+
// represents the "user" who experienced the error.
92+
if (telemetry.fid) {
93+
customAttributes['user.id'] = telemetry.fid;
94+
}
95+
9096
if (error instanceof Error) {
9197
logger.emit({
9298
severityNumber: SeverityNumber.ERROR,

packages/telemetry/src/public-types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ export interface Telemetry {
3333

3434
/** The {@link LoggerProvider} this {@link Telemetry} instance uses. */
3535
loggerProvider: LoggerProvider;
36+
37+
/**
38+
* The Firebase Installation ID.
39+
*
40+
* @internal
41+
*/
42+
fid?: string;
3643
}
3744

3845
/**

packages/telemetry/src/service.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,19 @@
1818
import { _FirebaseService, FirebaseApp } from '@firebase/app';
1919
import { Telemetry } from './public-types';
2020
import { LoggerProvider } from '@opentelemetry/sdk-logs';
21+
import { getInstallations, getId } from '@firebase/installations';
2122

2223
export class TelemetryService implements Telemetry, _FirebaseService {
23-
constructor(public app: FirebaseApp, public loggerProvider: LoggerProvider) {}
24+
fid?: string;
25+
26+
constructor(public app: FirebaseApp, public loggerProvider: LoggerProvider) {
27+
this._getFid().catch(console.error);
28+
}
29+
30+
private async _getFid(): Promise<void> {
31+
const installations = getInstallations(this.app);
32+
this.fid = await getId(installations);
33+
}
2434

2535
_delete(): Promise<void> {
2636
return Promise.resolve();

0 commit comments

Comments
 (0)