Skip to content

Commit 3a2a443

Browse files
committed
Try to make it more robust
1 parent 1416017 commit 3a2a443

File tree

1 file changed

+48
-37
lines changed
  • packages/node/src/integrations/tracing/firebase/otel/patches

1 file changed

+48
-37
lines changed

packages/node/src/integrations/tracing/firebase/otel/patches/firestore.ts

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as net from 'node:net';
12
import type { Span, Tracer } from '@opentelemetry/api';
23
import { context, diag, SpanKind, trace } from '@opentelemetry/api';
34
import {
@@ -251,67 +252,77 @@ function startDBSpan<AppModelType, DbModelType extends DocumentData>(
251252
return span;
252253
}
253254

254-
function addAttributes<AppModelType, DbModelType extends DocumentData>(
255-
span: Span,
256-
reference: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>,
257-
): void {
258-
const firestoreApp: FirebaseApp = reference.firestore.app;
259-
const firestoreOptions: FirebaseOptions = firestoreApp.options;
260-
const json: { settings?: FirestoreSettings } = reference.firestore.toJSON() || {};
261-
const settings: FirestoreSettings = json.settings || {};
262-
263-
const attributes: SpanAttributes = {
264-
[ATTR_DB_COLLECTION_NAME]: reference.path,
265-
[ATTR_DB_NAMESPACE]: firestoreApp.name,
266-
[ATTR_DB_SYSTEM_NAME]: 'firebase.firestore',
267-
'firebase.firestore.type': reference.type,
268-
'firebase.firestore.options.projectId': firestoreOptions.projectId,
269-
'firebase.firestore.options.appId': firestoreOptions.appId,
270-
'firebase.firestore.options.messagingSenderId': firestoreOptions.messagingSenderId,
271-
'firebase.firestore.options.storageBucket': firestoreOptions.storageBucket,
272-
};
273-
255+
/**
256+
* Sets the server address and port attributes on the span based on the Firestore settings.
257+
* It's best effort to extract the address and port from the settings, especially for IPv6.
258+
* @param span - The span to set attributes on.
259+
* @param settings - The Firestore settings containing host information.
260+
*/
261+
function setPortAndAddress(span: Span, settings: FirestoreSettings): void {
274262
if (typeof settings.host === 'string') {
275263
let address: string | undefined;
276264
let port: string | undefined;
277265

278266
if (settings.host.startsWith('[')) {
267+
// IPv6 addresses can be enclosed in square brackets, e.g., [2001:db8::1]:8080
279268
if (settings.host.endsWith(']')) {
280-
// Theres no port, just the address
269+
// IPv6 with square brackets without port
281270
address = settings.host.slice(1, -1);
282271
} else {
283-
// Handling IPv6 addresses with port
272+
// IPv6 with square brackets with port
284273
const lastColonIndex = settings.host.lastIndexOf(':');
285274
if (lastColonIndex !== -1) {
286275
address = settings.host.slice(1, lastColonIndex);
287276
port = settings.host.slice(lastColonIndex + 1);
288277
}
289278
}
290279
} else {
291-
if (settings.host.includes('::')) {
292-
// Handling IPv6 addresses with port
293-
const parts = settings.host.split(':');
294-
address = parts.slice(0, -1).join(':');
295-
port = parts[parts.length - 1];
296-
} else if (settings.host.includes(':')) {
297-
// Handling IPv4 addresses with port
298-
const parts = settings.host.split(':');
299-
address = parts[0];
300-
port = parts[1];
301-
} else {
302-
// Handling IPv4 addresses without port
280+
// IPv4 or IPv6 without square brackets
281+
// If it's an IPv6 address without square brackets, we assume it does not have a port.
282+
if (net.isIPv6(settings.host)) {
303283
address = settings.host;
304284
}
285+
// If it's an IPv4 address, we can extract the port if it exists.
286+
else {
287+
const lastColonIndex = settings.host.lastIndexOf(':');
288+
if (lastColonIndex !== -1) {
289+
address = settings.host.slice(0, lastColonIndex);
290+
port = settings.host.slice(lastColonIndex + 1);
291+
} else {
292+
address = settings.host;
293+
}
294+
}
305295
}
306-
307296
if (address) {
308-
attributes[ATTR_SERVER_ADDRESS] = address;
297+
span.setAttribute(ATTR_SERVER_ADDRESS, address);
309298
}
310299

311300
if (port !== undefined) {
312-
attributes[ATTR_SERVER_PORT] = Number(port);
301+
span.setAttribute(ATTR_SERVER_PORT, Number(port));
313302
}
314303
}
304+
}
305+
306+
function addAttributes<AppModelType, DbModelType extends DocumentData>(
307+
span: Span,
308+
reference: CollectionReference<AppModelType, DbModelType> | DocumentReference<AppModelType, DbModelType>,
309+
): void {
310+
const firestoreApp: FirebaseApp = reference.firestore.app;
311+
const firestoreOptions: FirebaseOptions = firestoreApp.options;
312+
const json: { settings?: FirestoreSettings } = reference.firestore.toJSON() || {};
313+
const settings: FirestoreSettings = json.settings || {};
314+
315+
const attributes: SpanAttributes = {
316+
[ATTR_DB_COLLECTION_NAME]: reference.path,
317+
[ATTR_DB_NAMESPACE]: firestoreApp.name,
318+
[ATTR_DB_SYSTEM_NAME]: 'firebase.firestore',
319+
'firebase.firestore.type': reference.type,
320+
'firebase.firestore.options.projectId': firestoreOptions.projectId,
321+
'firebase.firestore.options.appId': firestoreOptions.appId,
322+
'firebase.firestore.options.messagingSenderId': firestoreOptions.messagingSenderId,
323+
'firebase.firestore.options.storageBucket': firestoreOptions.storageBucket,
324+
};
315325

316326
span.setAttributes(attributes);
327+
setPortAndAddress(span, settings);
317328
}

0 commit comments

Comments
 (0)