Telemetry: Emit messagesJson compressed chunks as messagesJSONChunk (#328815)

* Telemetry: override chunk property name

* test update
This commit is contained in:
Vijay Upadya
2026-08-03 20:22:40 +00:00
committed by GitHub
parent c52f6d5e3e
commit 7a76a605df
2 changed files with 26 additions and 3 deletions
@@ -219,6 +219,11 @@ const COMPRESSED_CHUNK_SUFFIX = 'Chunk';
// value from instead of having to branch on whether the value happened to be chunked.
const ALWAYS_COMPRESSED_CHUNK_KEYS = new Set<string>(['messagesJson', 'diffsJSON']);
// Overrides for the base name of the compressed chunk family. By default the chunk family is named
// `<key>Chunk`, but some backend mappings expect a different casing. For `messagesJson` the backend
// expects `messagesJSONChunk` (uppercased JSON), while the original `<key>` column keeps its casing.
const COMPRESSED_CHUNK_KEY_OVERRIDES: { readonly [key: string]: string } = { messagesJson: 'messagesJSON' };
// Compressor used by multiplexProperties to gzip + base64 encode oversized property values. It is
// registered once by the Node layer (via setTelemetryPropertyCompressor) because Node's `zlib` is
// unavailable in the common layer; until then multiplexProperties falls back to plain chunking. It
@@ -273,8 +278,9 @@ export async function multiplexProperties(
// padding). No redundant plain continuation family is produced.
newProperties[key] = value!.slice(0, MAX_PROPERTY_LENGTH);
const compressed = await compress(value!);
const chunkKey = COMPRESSED_CHUNK_KEY_OVERRIDES[key] ?? key;
for (let offset = 0, index = 1; offset < compressed.length && index <= MAX_CONCATENATED_PROPERTIES; offset += MAX_PROPERTY_LENGTH, index++) {
const columnName = index === 1 ? `${key}${COMPRESSED_CHUNK_SUFFIX}` : `${key}${COMPRESSED_CHUNK_SUFFIX}_${index}`;
const columnName = index === 1 ? `${chunkKey}${COMPRESSED_CHUNK_SUFFIX}` : `${chunkKey}${COMPRESSED_CHUNK_SUFFIX}_${index}`;
newProperties[columnName] = compressed.slice(offset, offset + MAX_PROPERTY_LENGTH);
}
continue;
@@ -384,9 +384,11 @@ suite('multiplexProperties compression', function () {
// Known-large fields are always chunked in compressed form for backend uniformity.
expect(result.diffsJSONChunk).toBeDefined();
expect(result.messagesJsonChunk).toBeDefined();
// messagesJson uses the uppercase-JSON chunk family name expected by the backend.
expect(result.messagesJSONChunk).toBeDefined();
expect(result.messagesJsonChunk).toBeUndefined();
expect(gunzipFromBase64(joinCompressedChunks(result, 'diffsJSONChunk'))).toBe('small');
expect(gunzipFromBase64(joinCompressedChunks(result, 'messagesJsonChunk'))).toBe('tiny');
expect(gunzipFromBase64(joinCompressedChunks(result, 'messagesJSONChunk'))).toBe('tiny');
// The original columns still carry the (short) uncompressed value.
expect(result.diffsJSON).toBe('small');
expect(result.messagesJson).toBe('tiny');
@@ -395,6 +397,21 @@ suite('multiplexProperties compression', function () {
expect(result.otherChunk).toBeUndefined();
});
test('emits the messagesJSONChunk family (with numbered suffixes) for large messagesJson', async () => {
const original = pseudoRandomString(60000); // Poorly compressible -> compressed base64 > 8192.
const result = await multiplexProperties({ messagesJson: original }, gzipBase64) as { [key: string]: string };
// The original column carries just the first uncompressed chunk; no plain continuation family.
expect(result.messagesJson).toBe(original.slice(0, 8192));
expect(result.messagesJson_02).toBeUndefined();
// Compressed family uses the uppercase-JSON name, including numbered suffixes.
expect(result.messagesJSONChunk).toBeDefined();
expect(result.messagesJSONChunk_2).toBeDefined();
expect(result.messagesJsonChunk).toBeUndefined();
expect(result.messagesJsonChunk_2).toBeUndefined();
expect(gunzipFromBase64(joinCompressedChunks(result, 'messagesJSONChunk'))).toBe(original);
});
test('falls back to the plain continuation family when no compressor is provided', async () => {
const original = 'x'.repeat(20000);
const result = await multiplexProperties({ diffsJSON: original });