From e707960db343b4cad0977d727ac97f4e1e16a389 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 18 Oct 2023 16:01:36 +0200 Subject: [PATCH 1/5] fix(core): serialize bigint in metadata to string --- .../lib/segments/attributes/subsegment.d.ts | 2 ++ .../core/lib/segments/attributes/subsegment.js | 17 +++++++++++++++-- packages/core/lib/segments/segment.d.ts | 2 ++ packages/core/lib/segments/segment.js | 14 ++++++++++++-- .../unit/segments/attributes/subsegment.test.js | 6 ++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/packages/core/lib/segments/attributes/subsegment.d.ts b/packages/core/lib/segments/attributes/subsegment.d.ts index 64db3433..5e012e4f 100644 --- a/packages/core/lib/segments/attributes/subsegment.d.ts +++ b/packages/core/lib/segments/attributes/subsegment.d.ts @@ -61,6 +61,8 @@ declare class Subsegment { toString(): string; toJSON(): { [key: string]: any }; + + serialize(object?: Subsegment): string; } export = Subsegment; diff --git a/packages/core/lib/segments/attributes/subsegment.js b/packages/core/lib/segments/attributes/subsegment.js index a8644943..4101662e 100644 --- a/packages/core/lib/segments/attributes/subsegment.js +++ b/packages/core/lib/segments/attributes/subsegment.js @@ -401,7 +401,7 @@ Subsegment.prototype.format = function format() { this.trace_id = this.segment.trace_id; } - return JSON.stringify(this); + return this.serialize(); }; /** @@ -409,7 +409,7 @@ Subsegment.prototype.format = function format() { */ Subsegment.prototype.toString = function toString() { - return JSON.stringify(this); + return this.serialize(); }; Subsegment.prototype.toJSON = function toJSON() { @@ -428,4 +428,17 @@ Subsegment.prototype.toJSON = function toJSON() { return thisCopy; }; +/** + * Returns the serialized subsegment JSON string, replacing any BigInts with strings. + */ +Subsegment.prototype.serialize = function serialize(object) { + return JSON.stringify(object ?? this, (_, value) => { + if (typeof value === 'bigint') { + return value.toString(); + } + + return value; + }); +}; + module.exports = Subsegment; diff --git a/packages/core/lib/segments/segment.d.ts b/packages/core/lib/segments/segment.d.ts index 170b7f60..b9782556 100644 --- a/packages/core/lib/segments/segment.d.ts +++ b/packages/core/lib/segments/segment.d.ts @@ -64,6 +64,8 @@ declare class Segment { format(): string; toString(): string; + + serialize(object?: Segment): string; } export = Segment; diff --git a/packages/core/lib/segments/segment.js b/packages/core/lib/segments/segment.js index 92aae521..7dc3f90a 100644 --- a/packages/core/lib/segments/segment.js +++ b/packages/core/lib/segments/segment.js @@ -431,11 +431,21 @@ Segment.prototype.format = function format() { false ); - return JSON.stringify(thisCopy); + return this.serialize(thisCopy); }; Segment.prototype.toString = function toString() { - return JSON.stringify(this); + return this.serialize(); +}; + +Segment.prototype.serialize = function serialize(object) { + return JSON.stringify(object ?? this, (_, value) => { + if (typeof value === 'bigint') { + return value.toString(); + } + + return value; + }); }; module.exports = Segment; diff --git a/packages/core/test/unit/segments/attributes/subsegment.test.js b/packages/core/test/unit/segments/attributes/subsegment.test.js index f68cbe85..ab7188bc 100644 --- a/packages/core/test/unit/segments/attributes/subsegment.test.js +++ b/packages/core/test/unit/segments/attributes/subsegment.test.js @@ -332,6 +332,12 @@ describe('Subsegment', function() { child.flush(); emitStub.should.have.been.called; }); + + it('should stringify bigint objects correctly', function() { + child.addMetadata('key', BigInt(9007199254740991)); + child.flush(); + emitStub.should.have.been.calledOnce; + }); }); describe('#streamSubsegments', function() { From 00e98a8062187b558cbe5d0342a9b7d01f89d34d Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 18 Oct 2023 18:56:23 +0200 Subject: [PATCH 2/5] chore: extracted replacer into SegmentUtils --- packages/core/lib/segments/attributes/subsegment.js | 11 ++++------- packages/core/lib/segments/segment.js | 11 ++++------- packages/core/lib/segments/segment_utils.d.ts | 2 ++ packages/core/lib/segments/segment_utils.js | 8 ++++++++ .../core/test/unit/segments/segment_utils.test.js | 10 ++++++++++ 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/packages/core/lib/segments/attributes/subsegment.js b/packages/core/lib/segments/attributes/subsegment.js index 4101662e..b46a52f6 100644 --- a/packages/core/lib/segments/attributes/subsegment.js +++ b/packages/core/lib/segments/attributes/subsegment.js @@ -432,13 +432,10 @@ Subsegment.prototype.toJSON = function toJSON() { * Returns the serialized subsegment JSON string, replacing any BigInts with strings. */ Subsegment.prototype.serialize = function serialize(object) { - return JSON.stringify(object ?? this, (_, value) => { - if (typeof value === 'bigint') { - return value.toString(); - } - - return value; - }); + return JSON.stringify( + object ?? this, + SegmentUtils.getJsonStringifyReplacer() + ); }; module.exports = Subsegment; diff --git a/packages/core/lib/segments/segment.js b/packages/core/lib/segments/segment.js index 7dc3f90a..b8f24533 100644 --- a/packages/core/lib/segments/segment.js +++ b/packages/core/lib/segments/segment.js @@ -439,13 +439,10 @@ Segment.prototype.toString = function toString() { }; Segment.prototype.serialize = function serialize(object) { - return JSON.stringify(object ?? this, (_, value) => { - if (typeof value === 'bigint') { - return value.toString(); - } - - return value; - }); + return JSON.stringify( + object ?? this, + SegmentUtils.getJsonStringifyReplacer() + ); }; module.exports = Segment; diff --git a/packages/core/lib/segments/segment_utils.d.ts b/packages/core/lib/segments/segment_utils.d.ts index 197eb823..fd3a51f6 100644 --- a/packages/core/lib/segments/segment_utils.d.ts +++ b/packages/core/lib/segments/segment_utils.d.ts @@ -17,3 +17,5 @@ export function setStreamingThreshold(threshold: number): void; export function getStreamingThreshold(): number; export function getHttpResponseData(res: http.ServerResponse): object; + +export function getJsonStringifyReplacer(): (key: string, value: any) => any; diff --git a/packages/core/lib/segments/segment_utils.js b/packages/core/lib/segments/segment_utils.js index eb2cbb78..03514b68 100644 --- a/packages/core/lib/segments/segment_utils.js +++ b/packages/core/lib/segments/segment_utils.js @@ -67,6 +67,14 @@ var utils = { ret.content_length = safeParseInt(res.headers['content-length']); } return ret; + }, + + getJsonStringifyReplacer: () => (_, value) => { + if (typeof value === 'bigint') { + return value.toString(); + } + + return value; } }; diff --git a/packages/core/test/unit/segments/segment_utils.test.js b/packages/core/test/unit/segments/segment_utils.test.js index fb0b747d..8b8cefff 100644 --- a/packages/core/test/unit/segments/segment_utils.test.js +++ b/packages/core/test/unit/segments/segment_utils.test.js @@ -43,4 +43,14 @@ describe('SegmentUtils', function() { assert.deepEqual(emptyRes, {}); }); }); + + describe('#getJsonStringifyReplacer', () => { + it('should stringify BigInts', () => { + const obj = {foo: 1n, bar: BigInt(2)}; + const replacer = SegmentUtils.getJsonStringifyReplacer(); + const result = JSON.stringify(obj, replacer); + + assert.equal(result, '{"foo":"1","bar":"2"}'); + }); + }); }); From 5eed194e1e3d964704b4d7b9cd9b21ed4d38ecd9 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 18 Oct 2023 19:17:59 +0200 Subject: [PATCH 3/5] From 571e16f5fe8e80de7e05a50939636c90177a1bf8 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Fri, 20 Oct 2023 22:51:34 +0200 Subject: [PATCH 4/5] Update subsegment.d.ts Co-authored-by: Carol Abadeer <60774943+carolabadeer@users.noreply.github.com> --- packages/core/lib/segments/attributes/subsegment.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/lib/segments/attributes/subsegment.d.ts b/packages/core/lib/segments/attributes/subsegment.d.ts index 5e012e4f..b827e0ea 100644 --- a/packages/core/lib/segments/attributes/subsegment.d.ts +++ b/packages/core/lib/segments/attributes/subsegment.d.ts @@ -62,7 +62,7 @@ declare class Subsegment { toJSON(): { [key: string]: any }; - serialize(object?: Subsegment): string; + serialize(subsegment?: Subsegment): string; } export = Subsegment; From b3e35679d554c0b148a80cf450ec44ab084f0828 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Fri, 20 Oct 2023 22:51:40 +0200 Subject: [PATCH 5/5] Update segment.d.ts Co-authored-by: Carol Abadeer <60774943+carolabadeer@users.noreply.github.com> --- packages/core/lib/segments/segment.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/lib/segments/segment.d.ts b/packages/core/lib/segments/segment.d.ts index b9782556..34de5974 100644 --- a/packages/core/lib/segments/segment.d.ts +++ b/packages/core/lib/segments/segment.d.ts @@ -65,7 +65,7 @@ declare class Segment { toString(): string; - serialize(object?: Segment): string; + serialize(segment?: Segment): string; } export = Segment;