expensify-common 2.0.190 → 2.0.191
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Logger.d.ts +21 -1
- package/dist/Logger.js +118 -15
- package/dist/esm/Logger.d.ts +21 -1
- package/dist/esm/Logger.js +115 -15
- package/package.json +1 -1
package/dist/Logger.d.ts
CHANGED
|
@@ -21,6 +21,26 @@ type LoggerOptions = {
|
|
|
21
21
|
maxLogLinesBeforeFlush?: number;
|
|
22
22
|
getContextEmail?: () => string | null;
|
|
23
23
|
};
|
|
24
|
+
declare const MAX_LOG_LINE_BYTES = 1000000;
|
|
25
|
+
/**
|
|
26
|
+
* Gets the total UTF-8 byte length of a string.
|
|
27
|
+
*/
|
|
28
|
+
declare function utf8ByteLength(input: string): number;
|
|
29
|
+
/**
|
|
30
|
+
* Truncates `message` so that the SERIALIZED `line` fits within maxSize bytes. The serialized
|
|
31
|
+
* line is `overhead(empty message) + JSON-escaped bytes of the message`, so we measure the
|
|
32
|
+
* message's escaped size directly (single pass) instead of repeatedly re-serializing the whole
|
|
33
|
+
* line. This is exact for JSON.stringify's escaping and avoids the cost of a binary search.
|
|
34
|
+
*/
|
|
35
|
+
declare function truncateMessageToFitLine(line: LogLine, message: string, maxSize: number): string;
|
|
36
|
+
/**
|
|
37
|
+
* Serializes a log line while enforcing the per-line byte limit on the *serialized* line — what
|
|
38
|
+
* the server measures — covering the message, parameters and metadata plus JSON-escaping
|
|
39
|
+
* overhead. Returns the JSON string for the line (reused to build the packet, so each line is
|
|
40
|
+
* serialized only once). Oversized `parameters` (structured data we can't safely truncate
|
|
41
|
+
* mid-JSON) are replaced with a size marker; the message is then truncated to fit the remainder.
|
|
42
|
+
*/
|
|
43
|
+
declare function serializeLineWithinByteLimit(line: LogLine, maxSize: number): string;
|
|
24
44
|
export default class Logger {
|
|
25
45
|
logLines: LogLine[];
|
|
26
46
|
serverLoggingCallback: ServerLoggingCallback;
|
|
@@ -79,4 +99,4 @@ export default class Logger {
|
|
|
79
99
|
*/
|
|
80
100
|
client(message: string, extraData?: Parameters): void;
|
|
81
101
|
}
|
|
82
|
-
export {};
|
|
102
|
+
export { truncateMessageToFitLine, serializeLineWithinByteLimit, utf8ByteLength, MAX_LOG_LINE_BYTES };
|
package/dist/Logger.js
CHANGED
|
@@ -1,11 +1,115 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_LOG_LINE_BYTES = void 0;
|
|
4
|
+
exports.truncateMessageToFitLine = truncateMessageToFitLine;
|
|
5
|
+
exports.serializeLineWithinByteLimit = serializeLineWithinByteLimit;
|
|
6
|
+
exports.utf8ByteLength = utf8ByteLength;
|
|
3
7
|
const MAX_LOG_LINES_BEFORE_FLUSH = 50;
|
|
4
|
-
// The server
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
const
|
|
8
|
-
|
|
8
|
+
// The server rejects any single serialized log line larger than 1,048,576 bytes (1 MiB).
|
|
9
|
+
// We enforce a lower cap on the JSON-serialized line (message + parameters + metadata, with
|
|
10
|
+
// escaping) so it stays comfortably under the server limit.
|
|
11
|
+
const MAX_LOG_LINE_BYTES = 1000000;
|
|
12
|
+
exports.MAX_LOG_LINE_BYTES = MAX_LOG_LINE_BYTES;
|
|
13
|
+
/**
|
|
14
|
+
* Gets the UTF-8 byte length of a single unicode code point.
|
|
15
|
+
*/
|
|
16
|
+
function codePointByteSize(code) {
|
|
17
|
+
if (code >= 0x10000) {
|
|
18
|
+
return 4;
|
|
19
|
+
}
|
|
20
|
+
if (code >= 0x800) {
|
|
21
|
+
return 3;
|
|
22
|
+
}
|
|
23
|
+
if (code >= 0x80) {
|
|
24
|
+
return 2;
|
|
25
|
+
}
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Gets the total UTF-8 byte length of a string.
|
|
30
|
+
*/
|
|
31
|
+
function utf8ByteLength(input) {
|
|
32
|
+
return Array.from(input).reduce((sum, char) => { var _a; return sum + codePointByteSize((_a = char.codePointAt(0)) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* UTF-8 byte length of a single code point *after JSON string escaping*, matching the output of
|
|
36
|
+
* JSON.stringify: `"` `\` and the short control escapes are 2 bytes, other control characters
|
|
37
|
+
* and lone surrogates become `\uXXXX` (6 bytes), everything else is its plain UTF-8 size.
|
|
38
|
+
*/
|
|
39
|
+
function jsonEscapedByteSize(code) {
|
|
40
|
+
if (code === 0x22 || code === 0x5c || code === 0x08 || code === 0x09 || code === 0x0a || code === 0x0c || code === 0x0d) {
|
|
41
|
+
return 2;
|
|
42
|
+
}
|
|
43
|
+
if (code < 0x20 || (code >= 0xd800 && code <= 0xdfff)) {
|
|
44
|
+
return 6;
|
|
45
|
+
}
|
|
46
|
+
return codePointByteSize(code);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Truncates `message` so that the SERIALIZED `line` fits within maxSize bytes. The serialized
|
|
50
|
+
* line is `overhead(empty message) + JSON-escaped bytes of the message`, so we measure the
|
|
51
|
+
* message's escaped size directly (single pass) instead of repeatedly re-serializing the whole
|
|
52
|
+
* line. This is exact for JSON.stringify's escaping and avoids the cost of a binary search.
|
|
53
|
+
*/
|
|
54
|
+
function truncateMessageToFitLine(line, message, maxSize) {
|
|
55
|
+
var _a;
|
|
56
|
+
const overhead = utf8ByteLength(JSON.stringify(Object.assign(Object.assign({}, line), { message: '' })));
|
|
57
|
+
const totalRawBytes = utf8ByteLength(message);
|
|
58
|
+
// Marker "...[truncated N bytes]" is escape-free ASCII, so its serialized size equals its
|
|
59
|
+
// raw size = 21 + digits(N). Reserve for the max possible N so the final line never overflows.
|
|
60
|
+
const MARKER_STATIC_BYTES = 21;
|
|
61
|
+
const reservedMarkerBytes = MARKER_STATIC_BYTES + String(totalRawBytes).length;
|
|
62
|
+
const contentBudget = maxSize - overhead - reservedMarkerBytes;
|
|
63
|
+
if (contentBudget <= 0) {
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
// Keep whole code points until the escaped budget is exhausted (never splits a character).
|
|
67
|
+
let keptUnits = 0;
|
|
68
|
+
let keptEscapedBytes = 0;
|
|
69
|
+
let keptRawBytes = 0;
|
|
70
|
+
for (let i = 0; i < message.length;) {
|
|
71
|
+
const code = (_a = message.codePointAt(i)) !== null && _a !== void 0 ? _a : 0;
|
|
72
|
+
const escapedBytes = jsonEscapedByteSize(code);
|
|
73
|
+
if (keptEscapedBytes + escapedBytes > contentBudget) {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
keptEscapedBytes += escapedBytes;
|
|
77
|
+
keptRawBytes += codePointByteSize(code);
|
|
78
|
+
const units = code > 0xffff ? 2 : 1;
|
|
79
|
+
i += units;
|
|
80
|
+
keptUnits += units;
|
|
81
|
+
}
|
|
82
|
+
if (keptRawBytes >= totalRawBytes) {
|
|
83
|
+
return message;
|
|
84
|
+
}
|
|
85
|
+
const removed = totalRawBytes - keptRawBytes;
|
|
86
|
+
return `${message.slice(0, keptUnits)}...[truncated ${removed} bytes]`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Serializes a log line while enforcing the per-line byte limit on the *serialized* line — what
|
|
90
|
+
* the server measures — covering the message, parameters and metadata plus JSON-escaping
|
|
91
|
+
* overhead. Returns the JSON string for the line (reused to build the packet, so each line is
|
|
92
|
+
* serialized only once). Oversized `parameters` (structured data we can't safely truncate
|
|
93
|
+
* mid-JSON) are replaced with a size marker; the message is then truncated to fit the remainder.
|
|
94
|
+
*/
|
|
95
|
+
function serializeLineWithinByteLimit(line, maxSize) {
|
|
96
|
+
var _a;
|
|
97
|
+
const serialized = JSON.stringify(line);
|
|
98
|
+
// Cheap fast path: at most 3 UTF-8 bytes per UTF-16 code unit, so if 3 * length fits the
|
|
99
|
+
// line is definitely under the limit and we avoid the exact byte count entirely.
|
|
100
|
+
if (serialized.length * 3 <= maxSize || utf8ByteLength(serialized) <= maxSize) {
|
|
101
|
+
return serialized;
|
|
102
|
+
}
|
|
103
|
+
const result = Object.assign({}, line);
|
|
104
|
+
// If the line is over the limit even with an empty message, the bulk is in `parameters` —
|
|
105
|
+
// replace it with a marker so the (human-readable) message is what we keep room for.
|
|
106
|
+
if (utf8ByteLength(JSON.stringify(Object.assign(Object.assign({}, result), { message: '' }))) > maxSize) {
|
|
107
|
+
const parametersByteSize = utf8ByteLength(JSON.stringify((_a = result.parameters) !== null && _a !== void 0 ? _a : ''));
|
|
108
|
+
result.parameters = { truncated: true, originalByteSize: parametersByteSize };
|
|
109
|
+
}
|
|
110
|
+
result.message = truncateMessageToFitLine(result, line.message, maxSize);
|
|
111
|
+
return JSON.stringify(result);
|
|
112
|
+
}
|
|
9
113
|
class Logger {
|
|
10
114
|
constructor({ serverLoggingCallback, isDebug, clientLoggingCallback, maxLogLinesBeforeFlush, getContextEmail }) {
|
|
11
115
|
// An array of log lines that limits itself to a certain number of entries (deleting the oldest)
|
|
@@ -31,16 +135,20 @@ class Logger {
|
|
|
31
135
|
if (!this.logLines.length || ((_a = this.logLines) === null || _a === void 0 ? void 0 : _a.every((l) => l.onlyFlushWithOthers))) {
|
|
32
136
|
return;
|
|
33
137
|
}
|
|
34
|
-
// We don't care about log setting web cookies so let's define it as false
|
|
35
|
-
|
|
138
|
+
// We don't care about log setting web cookies so let's define it as false.
|
|
139
|
+
// Serialize each line while bounding it to the server's per-line size limit (covers
|
|
140
|
+
// message, parameters and JSON-escaping overhead). Building the packet by joining the
|
|
141
|
+
// per-line JSON keeps each line serialized only once — identical output to
|
|
142
|
+
// JSON.stringify(array) with no extra pass.
|
|
143
|
+
const serializedLines = (_b = this.logLines) === null || _b === void 0 ? void 0 : _b.map((l) => {
|
|
36
144
|
// eslint-disable-next-line no-param-reassign
|
|
37
145
|
delete l.onlyFlushWithOthers;
|
|
38
|
-
return l;
|
|
146
|
+
return serializeLineWithinByteLimit(l, MAX_LOG_LINE_BYTES);
|
|
39
147
|
});
|
|
40
148
|
this.logLines = [];
|
|
41
149
|
const promise = this.serverLoggingCallback(this, {
|
|
42
150
|
api_setCookie: false,
|
|
43
|
-
logPacket:
|
|
151
|
+
logPacket: `[${serializedLines.join(',')}]`,
|
|
44
152
|
});
|
|
45
153
|
if (!promise) {
|
|
46
154
|
return;
|
|
@@ -68,13 +176,8 @@ class Logger {
|
|
|
68
176
|
catch (_a) {
|
|
69
177
|
// Silently fail if getContextEmail throws - logging should not crash
|
|
70
178
|
}
|
|
71
|
-
let cappedMessage = message;
|
|
72
|
-
if (message.length > MAX_LOG_MESSAGE_LENGTH) {
|
|
73
|
-
const omittedCount = message.length - MAX_LOG_MESSAGE_LENGTH;
|
|
74
|
-
cappedMessage = `${message.slice(0, MAX_LOG_MESSAGE_LENGTH)}…[truncated ${omittedCount} characters]`;
|
|
75
|
-
}
|
|
76
179
|
const length = this.logLines.push({
|
|
77
|
-
message
|
|
180
|
+
message,
|
|
78
181
|
parameters,
|
|
79
182
|
onlyFlushWithOthers,
|
|
80
183
|
timestamp: new Date(),
|
package/dist/esm/Logger.d.ts
CHANGED
|
@@ -21,6 +21,26 @@ type LoggerOptions = {
|
|
|
21
21
|
maxLogLinesBeforeFlush?: number;
|
|
22
22
|
getContextEmail?: () => string | null;
|
|
23
23
|
};
|
|
24
|
+
declare const MAX_LOG_LINE_BYTES = 1000000;
|
|
25
|
+
/**
|
|
26
|
+
* Gets the total UTF-8 byte length of a string.
|
|
27
|
+
*/
|
|
28
|
+
declare function utf8ByteLength(input: string): number;
|
|
29
|
+
/**
|
|
30
|
+
* Truncates `message` so that the SERIALIZED `line` fits within maxSize bytes. The serialized
|
|
31
|
+
* line is `overhead(empty message) + JSON-escaped bytes of the message`, so we measure the
|
|
32
|
+
* message's escaped size directly (single pass) instead of repeatedly re-serializing the whole
|
|
33
|
+
* line. This is exact for JSON.stringify's escaping and avoids the cost of a binary search.
|
|
34
|
+
*/
|
|
35
|
+
declare function truncateMessageToFitLine(line: LogLine, message: string, maxSize: number): string;
|
|
36
|
+
/**
|
|
37
|
+
* Serializes a log line while enforcing the per-line byte limit on the *serialized* line — what
|
|
38
|
+
* the server measures — covering the message, parameters and metadata plus JSON-escaping
|
|
39
|
+
* overhead. Returns the JSON string for the line (reused to build the packet, so each line is
|
|
40
|
+
* serialized only once). Oversized `parameters` (structured data we can't safely truncate
|
|
41
|
+
* mid-JSON) are replaced with a size marker; the message is then truncated to fit the remainder.
|
|
42
|
+
*/
|
|
43
|
+
declare function serializeLineWithinByteLimit(line: LogLine, maxSize: number): string;
|
|
24
44
|
export default class Logger {
|
|
25
45
|
logLines: LogLine[];
|
|
26
46
|
serverLoggingCallback: ServerLoggingCallback;
|
|
@@ -79,4 +99,4 @@ export default class Logger {
|
|
|
79
99
|
*/
|
|
80
100
|
client(message: string, extraData?: Parameters): void;
|
|
81
101
|
}
|
|
82
|
-
export {};
|
|
102
|
+
export { truncateMessageToFitLine, serializeLineWithinByteLimit, utf8ByteLength, MAX_LOG_LINE_BYTES };
|
package/dist/esm/Logger.js
CHANGED
|
@@ -1,9 +1,108 @@
|
|
|
1
1
|
const MAX_LOG_LINES_BEFORE_FLUSH = 50;
|
|
2
|
-
// The server
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
const
|
|
6
|
-
|
|
2
|
+
// The server rejects any single serialized log line larger than 1,048,576 bytes (1 MiB).
|
|
3
|
+
// We enforce a lower cap on the JSON-serialized line (message + parameters + metadata, with
|
|
4
|
+
// escaping) so it stays comfortably under the server limit.
|
|
5
|
+
const MAX_LOG_LINE_BYTES = 1000000;
|
|
6
|
+
/**
|
|
7
|
+
* Gets the UTF-8 byte length of a single unicode code point.
|
|
8
|
+
*/
|
|
9
|
+
function codePointByteSize(code) {
|
|
10
|
+
if (code >= 0x10000) {
|
|
11
|
+
return 4;
|
|
12
|
+
}
|
|
13
|
+
if (code >= 0x800) {
|
|
14
|
+
return 3;
|
|
15
|
+
}
|
|
16
|
+
if (code >= 0x80) {
|
|
17
|
+
return 2;
|
|
18
|
+
}
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Gets the total UTF-8 byte length of a string.
|
|
23
|
+
*/
|
|
24
|
+
function utf8ByteLength(input) {
|
|
25
|
+
return Array.from(input).reduce((sum, char) => { var _a; return sum + codePointByteSize((_a = char.codePointAt(0)) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* UTF-8 byte length of a single code point *after JSON string escaping*, matching the output of
|
|
29
|
+
* JSON.stringify: `"` `\` and the short control escapes are 2 bytes, other control characters
|
|
30
|
+
* and lone surrogates become `\uXXXX` (6 bytes), everything else is its plain UTF-8 size.
|
|
31
|
+
*/
|
|
32
|
+
function jsonEscapedByteSize(code) {
|
|
33
|
+
if (code === 0x22 || code === 0x5c || code === 0x08 || code === 0x09 || code === 0x0a || code === 0x0c || code === 0x0d) {
|
|
34
|
+
return 2;
|
|
35
|
+
}
|
|
36
|
+
if (code < 0x20 || (code >= 0xd800 && code <= 0xdfff)) {
|
|
37
|
+
return 6;
|
|
38
|
+
}
|
|
39
|
+
return codePointByteSize(code);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Truncates `message` so that the SERIALIZED `line` fits within maxSize bytes. The serialized
|
|
43
|
+
* line is `overhead(empty message) + JSON-escaped bytes of the message`, so we measure the
|
|
44
|
+
* message's escaped size directly (single pass) instead of repeatedly re-serializing the whole
|
|
45
|
+
* line. This is exact for JSON.stringify's escaping and avoids the cost of a binary search.
|
|
46
|
+
*/
|
|
47
|
+
function truncateMessageToFitLine(line, message, maxSize) {
|
|
48
|
+
var _a;
|
|
49
|
+
const overhead = utf8ByteLength(JSON.stringify(Object.assign(Object.assign({}, line), { message: '' })));
|
|
50
|
+
const totalRawBytes = utf8ByteLength(message);
|
|
51
|
+
// Marker "...[truncated N bytes]" is escape-free ASCII, so its serialized size equals its
|
|
52
|
+
// raw size = 21 + digits(N). Reserve for the max possible N so the final line never overflows.
|
|
53
|
+
const MARKER_STATIC_BYTES = 21;
|
|
54
|
+
const reservedMarkerBytes = MARKER_STATIC_BYTES + String(totalRawBytes).length;
|
|
55
|
+
const contentBudget = maxSize - overhead - reservedMarkerBytes;
|
|
56
|
+
if (contentBudget <= 0) {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
// Keep whole code points until the escaped budget is exhausted (never splits a character).
|
|
60
|
+
let keptUnits = 0;
|
|
61
|
+
let keptEscapedBytes = 0;
|
|
62
|
+
let keptRawBytes = 0;
|
|
63
|
+
for (let i = 0; i < message.length;) {
|
|
64
|
+
const code = (_a = message.codePointAt(i)) !== null && _a !== void 0 ? _a : 0;
|
|
65
|
+
const escapedBytes = jsonEscapedByteSize(code);
|
|
66
|
+
if (keptEscapedBytes + escapedBytes > contentBudget) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
keptEscapedBytes += escapedBytes;
|
|
70
|
+
keptRawBytes += codePointByteSize(code);
|
|
71
|
+
const units = code > 0xffff ? 2 : 1;
|
|
72
|
+
i += units;
|
|
73
|
+
keptUnits += units;
|
|
74
|
+
}
|
|
75
|
+
if (keptRawBytes >= totalRawBytes) {
|
|
76
|
+
return message;
|
|
77
|
+
}
|
|
78
|
+
const removed = totalRawBytes - keptRawBytes;
|
|
79
|
+
return `${message.slice(0, keptUnits)}...[truncated ${removed} bytes]`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Serializes a log line while enforcing the per-line byte limit on the *serialized* line — what
|
|
83
|
+
* the server measures — covering the message, parameters and metadata plus JSON-escaping
|
|
84
|
+
* overhead. Returns the JSON string for the line (reused to build the packet, so each line is
|
|
85
|
+
* serialized only once). Oversized `parameters` (structured data we can't safely truncate
|
|
86
|
+
* mid-JSON) are replaced with a size marker; the message is then truncated to fit the remainder.
|
|
87
|
+
*/
|
|
88
|
+
function serializeLineWithinByteLimit(line, maxSize) {
|
|
89
|
+
var _a;
|
|
90
|
+
const serialized = JSON.stringify(line);
|
|
91
|
+
// Cheap fast path: at most 3 UTF-8 bytes per UTF-16 code unit, so if 3 * length fits the
|
|
92
|
+
// line is definitely under the limit and we avoid the exact byte count entirely.
|
|
93
|
+
if (serialized.length * 3 <= maxSize || utf8ByteLength(serialized) <= maxSize) {
|
|
94
|
+
return serialized;
|
|
95
|
+
}
|
|
96
|
+
const result = Object.assign({}, line);
|
|
97
|
+
// If the line is over the limit even with an empty message, the bulk is in `parameters` —
|
|
98
|
+
// replace it with a marker so the (human-readable) message is what we keep room for.
|
|
99
|
+
if (utf8ByteLength(JSON.stringify(Object.assign(Object.assign({}, result), { message: '' }))) > maxSize) {
|
|
100
|
+
const parametersByteSize = utf8ByteLength(JSON.stringify((_a = result.parameters) !== null && _a !== void 0 ? _a : ''));
|
|
101
|
+
result.parameters = { truncated: true, originalByteSize: parametersByteSize };
|
|
102
|
+
}
|
|
103
|
+
result.message = truncateMessageToFitLine(result, line.message, maxSize);
|
|
104
|
+
return JSON.stringify(result);
|
|
105
|
+
}
|
|
7
106
|
export default class Logger {
|
|
8
107
|
constructor({ serverLoggingCallback, isDebug, clientLoggingCallback, maxLogLinesBeforeFlush, getContextEmail }) {
|
|
9
108
|
// An array of log lines that limits itself to a certain number of entries (deleting the oldest)
|
|
@@ -29,16 +128,20 @@ export default class Logger {
|
|
|
29
128
|
if (!this.logLines.length || ((_a = this.logLines) === null || _a === void 0 ? void 0 : _a.every((l) => l.onlyFlushWithOthers))) {
|
|
30
129
|
return;
|
|
31
130
|
}
|
|
32
|
-
// We don't care about log setting web cookies so let's define it as false
|
|
33
|
-
|
|
131
|
+
// We don't care about log setting web cookies so let's define it as false.
|
|
132
|
+
// Serialize each line while bounding it to the server's per-line size limit (covers
|
|
133
|
+
// message, parameters and JSON-escaping overhead). Building the packet by joining the
|
|
134
|
+
// per-line JSON keeps each line serialized only once — identical output to
|
|
135
|
+
// JSON.stringify(array) with no extra pass.
|
|
136
|
+
const serializedLines = (_b = this.logLines) === null || _b === void 0 ? void 0 : _b.map((l) => {
|
|
34
137
|
// eslint-disable-next-line no-param-reassign
|
|
35
138
|
delete l.onlyFlushWithOthers;
|
|
36
|
-
return l;
|
|
139
|
+
return serializeLineWithinByteLimit(l, MAX_LOG_LINE_BYTES);
|
|
37
140
|
});
|
|
38
141
|
this.logLines = [];
|
|
39
142
|
const promise = this.serverLoggingCallback(this, {
|
|
40
143
|
api_setCookie: false,
|
|
41
|
-
logPacket:
|
|
144
|
+
logPacket: `[${serializedLines.join(',')}]`,
|
|
42
145
|
});
|
|
43
146
|
if (!promise) {
|
|
44
147
|
return;
|
|
@@ -66,13 +169,8 @@ export default class Logger {
|
|
|
66
169
|
catch (_a) {
|
|
67
170
|
// Silently fail if getContextEmail throws - logging should not crash
|
|
68
171
|
}
|
|
69
|
-
let cappedMessage = message;
|
|
70
|
-
if (message.length > MAX_LOG_MESSAGE_LENGTH) {
|
|
71
|
-
const omittedCount = message.length - MAX_LOG_MESSAGE_LENGTH;
|
|
72
|
-
cappedMessage = `${message.slice(0, MAX_LOG_MESSAGE_LENGTH)}…[truncated ${omittedCount} characters]`;
|
|
73
|
-
}
|
|
74
172
|
const length = this.logLines.push({
|
|
75
|
-
message
|
|
173
|
+
message,
|
|
76
174
|
parameters,
|
|
77
175
|
onlyFlushWithOthers,
|
|
78
176
|
timestamp: new Date(),
|
|
@@ -146,3 +244,5 @@ export default class Logger {
|
|
|
146
244
|
this.clientLoggingCallback(message, extraData);
|
|
147
245
|
}
|
|
148
246
|
}
|
|
247
|
+
// Exported for unit testing.
|
|
248
|
+
export { truncateMessageToFitLine, serializeLineWithinByteLimit, utf8ByteLength, MAX_LOG_LINE_BYTES };
|