@fluid-tools/fetch-tool 0.54.1 → 0.55.1
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/.eslintrc.js +1 -2
- package/dist/fluidAnalyzeMessages.d.ts.map +1 -1
- package/dist/fluidAnalyzeMessages.js +97 -58
- package/dist/fluidAnalyzeMessages.js.map +1 -1
- package/dist/fluidFetchArgs.d.ts.map +1 -1
- package/dist/fluidFetchArgs.js +1 -0
- package/dist/fluidFetchArgs.js.map +1 -1
- package/package.json +26 -25
- package/src/fluidAnalyzeMessages.ts +58 -17
- package/src/fluidFetchArgs.ts +1 -0
package/.eslintrc.js
CHANGED
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
module.exports = {
|
|
7
7
|
"extends": [
|
|
8
|
-
"@fluidframework/eslint-config-fluid
|
|
8
|
+
"@fluidframework/eslint-config-fluid"
|
|
9
9
|
],
|
|
10
10
|
"rules": {
|
|
11
11
|
"@typescript-eslint/no-use-before-define": "off",
|
|
12
12
|
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
13
13
|
"no-null/no-null": "off",
|
|
14
|
-
"prefer-arrow/prefer-arrow-functions": "off",
|
|
15
14
|
"import/no-internal-modules": "off"
|
|
16
15
|
}
|
|
17
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidAnalyzeMessages.d.ts","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"fluidAnalyzeMessages.d.ts","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyEH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,MAA8D,CAAC;AAgW1G,wBAAsB,iBAAiB,CACnC,SAAS,KAAA,EAAE,+CAA+C;AAC1D,gBAAgB,EAAE,OAAO,EACzB,YAAY,EAAE,OAAO,EACrB,iBAAiB,GAAE,GAAG,CAAC,MAAM,CAAqB,iBAwCrD"}
|
|
@@ -18,13 +18,13 @@ const container_runtime_1 = require("@fluidframework/container-runtime");
|
|
|
18
18
|
const datastore_1 = require("@fluidframework/datastore");
|
|
19
19
|
const noClientName = "No Client";
|
|
20
20
|
const objectTypePrefix = "https://graph.microsoft.com/types/";
|
|
21
|
-
function incr(map, key, size) {
|
|
21
|
+
function incr(map, key, size, count = 1) {
|
|
22
22
|
const value = map.get(key);
|
|
23
23
|
if (value === undefined) {
|
|
24
|
-
map.set(key, [
|
|
24
|
+
map.set(key, [count, size]);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
|
-
value[0]
|
|
27
|
+
value[0] += count;
|
|
28
28
|
value[1] += size;
|
|
29
29
|
map.set(key, value);
|
|
30
30
|
}
|
|
@@ -180,10 +180,11 @@ class DataStructureAnalyzer {
|
|
|
180
180
|
this.dataType = new Map();
|
|
181
181
|
this.dataTypeStats = new Map();
|
|
182
182
|
this.objectStats = new Map();
|
|
183
|
+
this.chunkMap = new Map();
|
|
183
184
|
}
|
|
184
185
|
processOp(message, msgSize, skipMessage) {
|
|
185
186
|
if (!skipMessage) {
|
|
186
|
-
processOp(message, this.dataType, this.objectStats, msgSize, this.dataTypeStats, this.messageTypeStats);
|
|
187
|
+
processOp(message, this.dataType, this.objectStats, msgSize, this.dataTypeStats, this.messageTypeStats, this.chunkMap);
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
reportAnalyzes(lastOp) {
|
|
@@ -412,77 +413,115 @@ dumpMessageStats, dumpMessages, messageTypeFilter = new Set()) {
|
|
|
412
413
|
console.log("");
|
|
413
414
|
}
|
|
414
415
|
exports.printMessageStats = printMessageStats;
|
|
415
|
-
function processOp(message, dataType, objectStats, msgSize, dataTypeStats, messageTypeStats) {
|
|
416
|
+
function processOp(message, dataType, objectStats, msgSize, dataTypeStats, messageTypeStats, chunkMap) {
|
|
416
417
|
let type = message.type;
|
|
417
418
|
let recorded = false;
|
|
419
|
+
let totalMsgSize = msgSize;
|
|
420
|
+
let opCount = 1;
|
|
418
421
|
if (container_runtime_1.isRuntimeMessage(message)) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
+
let runtimeMessage = container_runtime_1.unpackRuntimeMessage(message);
|
|
423
|
+
const messageType = runtimeMessage.type;
|
|
424
|
+
switch (messageType) {
|
|
425
|
+
case container_runtime_1.RuntimeMessage.Attach: {
|
|
422
426
|
const attachMessage = runtimeMessage.contents;
|
|
423
427
|
processDataStoreAttachOp(attachMessage, dataType);
|
|
424
428
|
break;
|
|
425
429
|
}
|
|
426
430
|
// skip for now because these ops do not have contents
|
|
427
|
-
case container_runtime_1.
|
|
431
|
+
case container_runtime_1.RuntimeMessage.BlobAttach: {
|
|
428
432
|
break;
|
|
429
433
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
envelope = JSON.parse(envelope);
|
|
434
|
+
case container_runtime_1.RuntimeMessage.ChunkedOp: {
|
|
435
|
+
const chunk = runtimeMessage.contents;
|
|
436
|
+
if (!chunkMap.has(runtimeMessage.clientId)) {
|
|
437
|
+
chunkMap.set(runtimeMessage.clientId, { chunks: new Array(chunk.totalChunks), totalSize: 0 });
|
|
435
438
|
}
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
439
|
+
const value = chunkMap.get(runtimeMessage.clientId);
|
|
440
|
+
common_utils_1.assert(value !== undefined, 0x2b8 /* "Chunk should be set in map" */);
|
|
441
|
+
const chunks = value.chunks;
|
|
442
|
+
const chunkIndex = chunk.chunkId - 1;
|
|
443
|
+
if (chunks[chunkIndex] !== undefined) {
|
|
444
|
+
throw new Error("Chunk already assigned");
|
|
445
|
+
}
|
|
446
|
+
chunks[chunkIndex] = chunk.contents;
|
|
447
|
+
value.totalSize += msgSize;
|
|
448
|
+
if (chunk.chunkId === chunk.totalChunks) {
|
|
449
|
+
opCount = chunk.totalChunks; // 1 op for each chunk.
|
|
450
|
+
runtimeMessage = Object.create(runtimeMessage);
|
|
451
|
+
runtimeMessage.contents = chunks.join("");
|
|
452
|
+
runtimeMessage.type = chunk.originalType;
|
|
453
|
+
type = chunk.originalType;
|
|
454
|
+
totalMsgSize = value.totalSize;
|
|
455
|
+
chunkMap.delete(runtimeMessage.clientId);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
// eslint-disable-next-line no-fallthrough
|
|
461
|
+
}
|
|
462
|
+
case container_runtime_1.RuntimeMessage.FluidDataStoreOp:
|
|
463
|
+
case container_runtime_1.RuntimeMessage.Alias:
|
|
464
|
+
case container_runtime_1.RuntimeMessage.Rejoin:
|
|
465
|
+
case container_runtime_1.RuntimeMessage.Operation:
|
|
466
|
+
{
|
|
467
|
+
let envelope = runtimeMessage.contents;
|
|
468
|
+
// TODO: Legacy?
|
|
469
|
+
if (envelope && typeof envelope === "string") {
|
|
470
|
+
envelope = JSON.parse(envelope);
|
|
448
471
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
dataType.set(objectId, objectId);
|
|
459
|
-
objectType = objectId;
|
|
460
|
-
}
|
|
461
|
-
incr(dataTypeStats, objectType, msgSize);
|
|
462
|
-
recorded = true;
|
|
463
|
-
let subType = innerContent2.type;
|
|
464
|
-
if (innerContent2.type === "set" &&
|
|
465
|
-
typeof innerContent2.value === "object" &&
|
|
466
|
-
innerContent2.value !== null) {
|
|
467
|
-
type = `${type}/${subType}`;
|
|
468
|
-
subType = innerContent2.value.type;
|
|
469
|
-
}
|
|
470
|
-
else if (objectType === "mergeTree" && subType !== undefined) {
|
|
471
|
-
const types = ["insert", "remove", "annotate", "group"];
|
|
472
|
-
if (types[subType]) {
|
|
473
|
-
subType = types[subType];
|
|
472
|
+
const innerContent = envelope.contents;
|
|
473
|
+
const address = envelope.address;
|
|
474
|
+
type = `${type}/${innerContent.type}`;
|
|
475
|
+
switch (innerContent.type) {
|
|
476
|
+
case datastore_1.DataStoreMessageType.Attach: {
|
|
477
|
+
const attachMessage = innerContent.content;
|
|
478
|
+
let objectType = attachMessage.type;
|
|
479
|
+
if (objectType.startsWith(objectTypePrefix)) {
|
|
480
|
+
objectType = objectType.substring(objectTypePrefix.length);
|
|
474
481
|
}
|
|
482
|
+
dataType.set(getObjectId(address, attachMessage.id), objectType);
|
|
483
|
+
break;
|
|
475
484
|
}
|
|
476
|
-
|
|
477
|
-
|
|
485
|
+
case datastore_1.DataStoreMessageType.ChannelOp:
|
|
486
|
+
default: {
|
|
487
|
+
const innerEnvelope = innerContent.content;
|
|
488
|
+
const innerContent2 = innerEnvelope.contents;
|
|
489
|
+
const objectId = getObjectId(address, innerEnvelope.address);
|
|
490
|
+
incr(objectStats, objectId, totalMsgSize, opCount);
|
|
491
|
+
let objectType = dataType.get(objectId);
|
|
492
|
+
if (objectType === undefined) {
|
|
493
|
+
// Somehow we do not have data...
|
|
494
|
+
dataType.set(objectId, objectId);
|
|
495
|
+
objectType = objectId;
|
|
496
|
+
}
|
|
497
|
+
incr(dataTypeStats, objectType, totalMsgSize, opCount);
|
|
498
|
+
recorded = true;
|
|
499
|
+
let subType = innerContent2.type;
|
|
500
|
+
if (innerContent2.type === "set" &&
|
|
501
|
+
typeof innerContent2.value === "object" &&
|
|
502
|
+
innerContent2.value !== null) {
|
|
503
|
+
type = `${type}/${subType}`;
|
|
504
|
+
subType = innerContent2.value.type;
|
|
505
|
+
}
|
|
506
|
+
else if (objectType === "mergeTree" && subType !== undefined) {
|
|
507
|
+
const types = ["insert", "remove", "annotate", "group"];
|
|
508
|
+
if (types[subType]) {
|
|
509
|
+
subType = types[subType];
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (subType !== undefined) {
|
|
513
|
+
type = `${type}/${subType}`;
|
|
514
|
+
}
|
|
515
|
+
type = `${type} (${objectType})`;
|
|
478
516
|
}
|
|
479
|
-
type = `${type} (${objectType})`;
|
|
480
517
|
}
|
|
518
|
+
break;
|
|
481
519
|
}
|
|
482
|
-
|
|
520
|
+
default:
|
|
521
|
+
common_utils_1.unreachableCase(messageType, "Message type not recognized!");
|
|
483
522
|
}
|
|
484
523
|
}
|
|
485
|
-
incr(messageTypeStats, type,
|
|
524
|
+
incr(messageTypeStats, type, totalMsgSize, opCount);
|
|
486
525
|
if (!recorded) {
|
|
487
526
|
// const objectId = `${type} (system)`;
|
|
488
527
|
const objectId = `(system messages)`;
|
|
@@ -490,8 +529,8 @@ function processOp(message, dataType, objectStats, msgSize, dataTypeStats, messa
|
|
|
490
529
|
if (dataType.get(objectId) === undefined) {
|
|
491
530
|
dataType.set(objectId, objectId);
|
|
492
531
|
}
|
|
493
|
-
incr(objectStats, objectId,
|
|
494
|
-
incr(dataTypeStats, objectType,
|
|
532
|
+
incr(objectStats, objectId, totalMsgSize, opCount);
|
|
533
|
+
incr(dataTypeStats, objectType, totalMsgSize, opCount);
|
|
495
534
|
}
|
|
496
535
|
}
|
|
497
536
|
function processDataStoreAttachOp(attachMessage, dataType) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n ISequencedDocumentMessage,\n ISummaryProposal,\n MessageType,\n TreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions\";\nimport {\n ContainerMessageType,\n isRuntimeMessage,\n unpackRuntimeMessage,\n} from \"@fluidframework/container-runtime\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number) {\n const value = map.get(key);\n if (value === undefined) {\n map.set(key, [1, size]);\n } else {\n value[0]++;\n value[1] += size;\n map.set(key, value);\n }\n}\n\ninterface ISessionInfo {\n startSeq: number;\n opCount: number;\n email: string;\n duration: number;\n}\n\ninterface IMessageAnalyzer {\n processOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n reportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n public static create(email: string, message: ISequencedDocumentMessage) {\n return new ActiveSession(email, message);\n }\n\n private opCount = 0;\n\n constructor(private readonly email: string, private readonly startMessage: ISequencedDocumentMessage) {\n }\n\n public reportOp(timestamp: number) {\n this.opCount++;\n }\n\n public leave(timestamp: number): ISessionInfo {\n return {\n opCount: this.opCount,\n email: this.email,\n startSeq: this.startMessage.sequenceNumber,\n duration: timestamp - this.startMessage.timestamp,\n };\n }\n}\n\n// Format a number separating 3 digits by comma\n// eslint-disable-next-line unicorn/no-unsafe-regex\nexport const formatNumber = (num: number): string => num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n map: Map<string, [number, number]>,\n props: {\n title: string;\n headers: [string, string];\n lines?: number;\n orderByFirstColumn?: boolean;\n reverseColumnsInUI?: boolean;\n removeTotals?: boolean;\n reverseSort?: boolean;\n }) {\n const fieldSizes = [10, 14];\n const nameLength = 72;\n const fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n let headers = props.headers;\n\n let recordsToShow = props.lines ? props.lines : 10;\n if (map.size !== recordsToShow && !props.removeTotals && recordsToShow > 1) {\n recordsToShow--;\n }\n\n let sorted: [string, [number, number]][];\n const sortIndex = props.orderByFirstColumn ? 0 : 1;\n let add: string;\n if (props.reverseSort) {\n sorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n add = \"↑\";\n } else {\n sorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n add = \"↓\";\n }\n headers[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n if (props.reverseColumnsInUI) {\n headers = [headers[1], headers[0]];\n const sorted2: [string, [number, number]][] = [];\n for (const [name, [count, size]] of sorted) {\n sorted2.push([name, [size, count]]);\n }\n sorted = sorted2;\n }\n\n let totalCount = 0;\n let sizeTotal = 0;\n\n props.title = `${props.title} (${sorted.length})`;\n const header0 = headers[0].padStart(fieldSizes[0]);\n let overflow = header0.length - fieldSizes[0];\n console.log(`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(fieldSizes[1] - overflow)}`);\n\n console.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n let index = 0;\n let allOtherCount = 0;\n let allOtherSize = 0;\n for (const [name, [count, size]] of sorted) {\n index++;\n totalCount += count;\n sizeTotal += size;\n if (index <= recordsToShow) {\n const item = name.padEnd(nameLength);\n overflow = item.length - nameLength;\n const col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n overflow += col1.length - fieldSizes[0];\n const col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n console.log(`${item} │ ${col1} ${col2}`);\n } else {\n allOtherCount += count;\n allOtherSize += size;\n }\n }\n\n if (!props.removeTotals) {\n if (allOtherCount || allOtherSize) {\n // eslint-disable-next-line max-len\n console.log(`${`All Others (${sorted.length - recordsToShow})`.padEnd(nameLength)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(allOtherSize).padStart(fieldSizes[1])}`);\n }\n console.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n // eslint-disable-next-line max-len\n console.log(`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(fieldSizes[0])} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`);\n }\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n private readonly sessionsInProgress = new Map<string, ActiveSession>();\n private readonly sessions = new Map<string, [number, number]>();\n private readonly users = new Map<string, [number, number]>();\n\n private first = true;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (this.first) {\n this.first = false;\n // Start of the road.\n const noNameSession = ActiveSession.create(noClientName, message);\n this.sessionsInProgress.set(noClientName, noNameSession);\n }\n const session = processQuorumMessages(\n message,\n skipMessage,\n this.sessionsInProgress,\n this.sessions,\n this.users);\n if (!skipMessage && session) {\n session.reportOp(message.timestamp);\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n // Close any open sessions\n reportOpenSessions(\n lastOp.timestamp,\n this.sessionsInProgress,\n this.sessions,\n this.users);\n dumpStats(this.users, {\n title: \"Users\",\n headers: [\"Sessions\", \"Op count\"],\n reverseColumnsInUI: true,\n lines: 6,\n });\n dumpStats(this.sessions, {\n title: \"Sessions\",\n headers: [\"Duration(s)\", \"Op count\"],\n reverseColumnsInUI: true,\n lines: 6,\n });\n dumpStats(this.sessions, {\n title: \"Sessions\",\n headers: [\"Duration(s)\", \"Op count\"],\n orderByFirstColumn: true,\n reverseColumnsInUI: true,\n removeTotals: true,\n lines: 5,\n });\n }\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n private readonly messageTypeStats = new Map<string, [number, number]>();\n private readonly dataType = new Map<string, string>();\n private readonly dataTypeStats = new Map<string, [number, number]>();\n private readonly objectStats = new Map<string, [number, number]>();\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (!skipMessage) {\n processOp(\n message,\n this.dataType,\n this.objectStats,\n msgSize,\n this.dataTypeStats,\n this.messageTypeStats);\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n dumpStats(this.messageTypeStats, {\n title: \"Message Type\",\n headers: [\"Op count\", \"Bytes\"],\n lines: 20,\n });\n dumpStats(calcChannelStats(this.dataType, this.objectStats), {\n title: \"Channel name\",\n headers: [\"Op count\", \"Bytes\"],\n lines: 7,\n });\n /*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n }\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n private sizeTotal = 0;\n private opsTotal = 0;\n private sizeFiltered = 0;\n private opsFiltered = 0;\n private filtered = false;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n this.sizeTotal += msgSize;\n this.opsTotal++;\n if (!skipMessage) {\n this.sizeFiltered += msgSize;\n this.opsFiltered++;\n } else {\n this.filtered = true;\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n if (this.filtered) {\n // eslint-disable-next-line max-len\n console.log(`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`);\n }\n if (this.opsTotal === 0) {\n console.error(\"No ops were found\");\n }\n }\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n private readonly opChunk = 1000;\n private opLimit = 1;\n private size = 0;\n private timeStart = 0;\n private doctimerStart = 0;\n private readonly ranges = new Map<string, [number, number]>();\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (message.sequenceNumber >= this.opLimit) {\n if (message.sequenceNumber !== 1) {\n const timeDiff = durationFromTime(message.timestamp - this.timeStart);\n const opsString = `ops = [${this.opLimit - this.opChunk}, ${this.opLimit - 1}]`.padEnd(26);\n // eslint-disable-next-line max-len\n const timeString = `time = [${durationFromTime(this.timeStart - this.doctimerStart)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n this.ranges.set(\n `${opsString} ${timeString}`,\n [timeDiff, this.size]);\n } else {\n this.doctimerStart = message.timestamp;\n }\n this.opLimit += this.opChunk;\n this.size = 0;\n this.timeStart = message.timestamp;\n }\n if (!skipMessage) {\n this.size += msgSize;\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n dumpStats(this.ranges, {\n title: \"Fastest 1000 op ranges\",\n headers: [\"Duration(s)\", \"Bytes\"],\n orderByFirstColumn: true,\n reverseSort: true,\n removeTotals: true,\n lines: 3,\n });\n }\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n private maxCollabWindow = 0;\n private opSeq = 0;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n const value = message.sequenceNumber - message.minimumSequenceNumber;\n if (value > this.maxCollabWindow) {\n this.maxCollabWindow = value;\n this.opSeq = message.sequenceNumber;\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n console.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n }\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n private lastSummaryOp = 0;\n private maxDistance = 0;\n private maxSeq = 0;\n private minDistance = Number.MAX_SAFE_INTEGER;\n private minSeq = 0;\n private maxResponse = 0;\n private maxResponseSeq = 0;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (message.type === MessageType.SummaryAck) {\n const distance = message.sequenceNumber - this.lastSummaryOp - 1;\n if (this.maxDistance < distance) {\n this.maxDistance = distance;\n this.maxSeq = message.sequenceNumber;\n }\n if (this.minDistance > distance) {\n this.minDistance = distance;\n this.minSeq = message.sequenceNumber;\n }\n\n this.lastSummaryOp = message.sequenceNumber;\n }\n if (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n const contents: ISummaryProposal = message.contents.summaryProposal;\n const distance = message.sequenceNumber - contents.summarySequenceNumber;\n if (distance > this.maxResponse) {\n this.maxResponse = distance;\n this.maxResponseSeq = message.sequenceNumber;\n }\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n const distance = lastOp.sequenceNumber - this.lastSummaryOp;\n if (this.maxDistance < distance) {\n this.maxDistance = distance;\n this.maxSeq = lastOp.sequenceNumber + 1;\n }\n\n console.log(\"\");\n if (this.minDistance === Number.MAX_SAFE_INTEGER) {\n console.log(\"No summaries found in this document\");\n } else {\n console.log(`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`);\n console.log(`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`);\n console.log(`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`);\n }\n }\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (!skipMessage) {\n console.log(JSON.stringify(message, undefined, 2));\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n }\n}\n\nexport async function printMessageStats(\n generator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n dumpMessageStats: boolean,\n dumpMessages: boolean,\n messageTypeFilter: Set<string> = new Set<string>()) {\n let lastMessage: ISequencedDocumentMessage | undefined;\n\n const analyzers: IMessageAnalyzer[] = [\n new FilteredMessageAnalyzer(), // Should come first\n new SessionAnalyzer(),\n new DataStructureAnalyzer(),\n new MessageDensityAnalyzer(),\n new CollabWindowSizeAnalyzer(),\n new SummaryAnalyzer(),\n ];\n\n if (dumpMessages) {\n analyzers.push(new MessageDumper());\n }\n\n for await (const messages of generator) {\n for (const message of (messages as ISequencedDocumentMessage[])) {\n const msgSize = JSON.stringify(message).length;\n lastMessage = message;\n\n const skipMessage = messageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n for (const analyzer of analyzers) {\n analyzer.processOp(message, msgSize, skipMessage);\n }\n }\n }\n\n if (lastMessage !== undefined) {\n if (dumpMessageStats) {\n for (const analyzer of analyzers) {\n analyzer.reportAnalyzes(lastMessage);\n }\n } else {\n // Warn about filtered messages\n analyzers[0].reportAnalyzes(lastMessage);\n }\n }\n console.log(\"\");\n}\n\nfunction processOp(\n message: ISequencedDocumentMessage,\n dataType: Map<string, string>,\n objectStats: Map<string, [number, number]>,\n msgSize: number,\n dataTypeStats: Map<string, [number, number]>,\n messageTypeStats: Map<string, [number, number]>) {\n let type = message.type;\n let recorded = false;\n if (isRuntimeMessage(message)) {\n const runtimeMessage = unpackRuntimeMessage(message);\n switch (runtimeMessage.type) {\n case ContainerMessageType.Attach: {\n const attachMessage = runtimeMessage.contents as IAttachMessage;\n processDataStoreAttachOp(attachMessage, dataType);\n break;\n }\n // skip for now because these ops do not have contents\n case ContainerMessageType.BlobAttach: {\n break;\n }\n default: {\n let envelope = runtimeMessage.contents as IEnvelope;\n // TODO: Legacy?\n if (envelope && typeof envelope === \"string\") {\n envelope = JSON.parse(envelope);\n }\n const innerContent = envelope.contents as {\n content: any;\n type: string;\n };\n const address = envelope.address;\n type = `${type}/${innerContent.type}`;\n switch (innerContent.type) {\n case DataStoreMessageType.Attach: {\n const attachMessage = innerContent.content as IAttachMessage;\n let objectType = attachMessage.type;\n if (objectType.startsWith(objectTypePrefix)) {\n objectType = objectType.substring(objectTypePrefix.length);\n }\n dataType.set(getObjectId(address, attachMessage.id), objectType);\n break;\n }\n case DataStoreMessageType.ChannelOp:\n default: {\n const innerEnvelope = innerContent.content as IEnvelope;\n const innerContent2 = innerEnvelope.contents as {\n type?: string;\n value?: any;\n };\n\n const objectId = getObjectId(address, innerEnvelope.address);\n incr(objectStats, objectId, msgSize);\n let objectType = dataType.get(objectId);\n if (objectType === undefined) {\n // Somehow we do not have data...\n dataType.set(objectId, objectId);\n objectType = objectId;\n }\n incr(dataTypeStats, objectType, msgSize);\n recorded = true;\n\n let subType = innerContent2.type;\n if (innerContent2.type === \"set\" &&\n typeof innerContent2.value === \"object\" &&\n innerContent2.value !== null) {\n type = `${type}/${subType}`;\n subType = innerContent2.value.type;\n } else if (objectType === \"mergeTree\" && subType !== undefined) {\n const types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n if (types[subType]) {\n subType = types[subType];\n }\n }\n if (subType !== undefined) {\n type = `${type}/${subType}`;\n }\n\n type = `${type} (${objectType})`;\n }\n }\n }\n }\n }\n\n incr(messageTypeStats, type, msgSize);\n if (!recorded) {\n // const objectId = `${type} (system)`;\n const objectId = `(system messages)`;\n const objectType = objectId;\n if (dataType.get(objectId) === undefined) {\n dataType.set(objectId, objectId);\n }\n incr(objectStats, objectId, msgSize);\n incr(dataTypeStats, objectType, msgSize);\n }\n}\n\nfunction processDataStoreAttachOp(\n attachMessage: IAttachMessage | string,\n dataType: Map<string, string>) {\n // dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n // That's data store, and it brings a bunch of data structures.\n // Let's try to crack it.\n let parsedAttachMessage: IAttachMessage;\n if (typeof attachMessage === \"string\") {\n parsedAttachMessage = JSON.parse(attachMessage);\n } else {\n parsedAttachMessage = attachMessage;\n }\n for (const entry of parsedAttachMessage.snapshot.entries) {\n if (entry.type === TreeEntry.Tree) {\n for (const entry2 of entry.value.entries) {\n if (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n const attrib = JSON.parse(entry2.value.contents);\n let objectType = attrib.type;\n if (objectType.startsWith(objectTypePrefix)) {\n objectType = objectType.substring(objectTypePrefix.length);\n }\n dataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n }\n }\n }\n }\n}\n\nfunction reportOpenSessions(\n lastOpTimestamp: number,\n sessionsInProgress: Map<string, ActiveSession>,\n sessions: Map<string, [number, number]>,\n users: Map<string, [number, number]>) {\n const activeSessions = new Map<string, [number, number]>();\n\n for (const [clientId, ses] of sessionsInProgress) {\n const sessionInfo = ses.leave(lastOpTimestamp);\n if (clientId !== noClientName) {\n const sessionName = `${clientId} (${sessionInfo.email})`;\n const sessionPayload: [number, number] = [durationFromTime(sessionInfo.duration), sessionInfo.opCount];\n sessions.set(sessionName, sessionPayload);\n activeSessions.set(sessionName, sessionPayload);\n } else {\n sessions.set(\n `Full file lifespan (noClient messages)`,\n [durationFromTime(sessionInfo.duration), sessionInfo.opCount]);\n }\n incr(users, sessionInfo.email, sessionInfo.opCount);\n }\n\n if (activeSessions.size > 0) {\n dumpStats(activeSessions, {\n title: \"Active sessions\",\n headers: [\"Duration\", \"Op count\"],\n lines: 6,\n orderByFirstColumn: true,\n removeTotals: true,\n });\n }\n}\n\nfunction calcChannelStats(dataType: Map<string, string>, objectStats: Map<string, [number, number]>) {\n const channelStats = new Map<string, [number, number]>();\n for (const [objectId, type] of dataType) {\n let value = objectStats.get(objectId);\n if (value === undefined) {\n value = [0, 0];\n }\n if (type === objectId) {\n channelStats.set(`${objectId}`, value);\n } else {\n channelStats.set(`${objectId} (${type})`, value);\n }\n }\n return channelStats;\n}\n\nfunction processQuorumMessages(\n message: ISequencedDocumentMessage,\n skipMessage: boolean,\n sessionsInProgress: Map<string, ActiveSession>,\n sessions: Map<string, [number, number]>,\n users: Map<string, [number, number]>) {\n let session: ActiveSession | undefined;\n const dataString = (message as any).data;\n if (message.type === \"join\") {\n const data = JSON.parse(dataString);\n session = ActiveSession.create(data.detail.user.id, message);\n sessionsInProgress.set(data.clientId, session);\n } else if (message.type === \"leave\") {\n const clientId = JSON.parse(dataString);\n session = sessionsInProgress.get(clientId);\n sessionsInProgress.delete(clientId);\n assert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n if (session) {\n if (!skipMessage) {\n session.reportOp(message.timestamp);\n }\n const sessionInfo: ISessionInfo = session.leave(message.timestamp);\n sessions.set(\n `${clientId} (${sessionInfo.email})`,\n [durationFromTime(sessionInfo.duration), sessionInfo.opCount]);\n incr(users, sessionInfo.email, sessionInfo.opCount);\n session = undefined; // Do not record it second time\n }\n } else {\n // message.clientId can be null\n session = sessionsInProgress.get(message.clientId);\n if (session === undefined) {\n session = sessionsInProgress.get(noClientName);\n assert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n }\n }\n return session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
|
|
1
|
+
{"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport {\n ISequencedDocumentMessage,\n ISummaryProposal,\n MessageType,\n TreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions\";\nimport {\n IChunkedOp,\n isRuntimeMessage,\n RuntimeMessage,\n unpackRuntimeMessage,\n} from \"@fluidframework/container-runtime\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n const value = map.get(key);\n if (value === undefined) {\n map.set(key, [count, size]);\n } else {\n value[0] += count;\n value[1] += size;\n map.set(key, value);\n }\n}\n\ninterface ISessionInfo {\n startSeq: number;\n opCount: number;\n email: string;\n duration: number;\n}\n\ninterface IMessageAnalyzer {\n processOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n reportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n public static create(email: string, message: ISequencedDocumentMessage) {\n return new ActiveSession(email, message);\n }\n\n private opCount = 0;\n\n constructor(private readonly email: string, private readonly startMessage: ISequencedDocumentMessage) {\n }\n\n public reportOp(timestamp: number) {\n this.opCount++;\n }\n\n public leave(timestamp: number): ISessionInfo {\n return {\n opCount: this.opCount,\n email: this.email,\n startSeq: this.startMessage.sequenceNumber,\n duration: timestamp - this.startMessage.timestamp,\n };\n }\n}\n\n// Format a number separating 3 digits by comma\n// eslint-disable-next-line unicorn/no-unsafe-regex\nexport const formatNumber = (num: number): string => num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n map: Map<string, [number, number]>,\n props: {\n title: string;\n headers: [string, string];\n lines?: number;\n orderByFirstColumn?: boolean;\n reverseColumnsInUI?: boolean;\n removeTotals?: boolean;\n reverseSort?: boolean;\n }) {\n const fieldSizes = [10, 14];\n const nameLength = 72;\n const fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n let headers = props.headers;\n\n let recordsToShow = props.lines ? props.lines : 10;\n if (map.size !== recordsToShow && !props.removeTotals && recordsToShow > 1) {\n recordsToShow--;\n }\n\n let sorted: [string, [number, number]][];\n const sortIndex = props.orderByFirstColumn ? 0 : 1;\n let add: string;\n if (props.reverseSort) {\n sorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n add = \"↑\";\n } else {\n sorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n add = \"↓\";\n }\n headers[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n if (props.reverseColumnsInUI) {\n headers = [headers[1], headers[0]];\n const sorted2: [string, [number, number]][] = [];\n for (const [name, [count, size]] of sorted) {\n sorted2.push([name, [size, count]]);\n }\n sorted = sorted2;\n }\n\n let totalCount = 0;\n let sizeTotal = 0;\n\n props.title = `${props.title} (${sorted.length})`;\n const header0 = headers[0].padStart(fieldSizes[0]);\n let overflow = header0.length - fieldSizes[0];\n console.log(`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(fieldSizes[1] - overflow)}`);\n\n console.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n let index = 0;\n let allOtherCount = 0;\n let allOtherSize = 0;\n for (const [name, [count, size]] of sorted) {\n index++;\n totalCount += count;\n sizeTotal += size;\n if (index <= recordsToShow) {\n const item = name.padEnd(nameLength);\n overflow = item.length - nameLength;\n const col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n overflow += col1.length - fieldSizes[0];\n const col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n console.log(`${item} │ ${col1} ${col2}`);\n } else {\n allOtherCount += count;\n allOtherSize += size;\n }\n }\n\n if (!props.removeTotals) {\n if (allOtherCount || allOtherSize) {\n // eslint-disable-next-line max-len\n console.log(`${`All Others (${sorted.length - recordsToShow})`.padEnd(nameLength)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(allOtherSize).padStart(fieldSizes[1])}`);\n }\n console.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n // eslint-disable-next-line max-len\n console.log(`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(fieldSizes[0])} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`);\n }\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n private readonly sessionsInProgress = new Map<string, ActiveSession>();\n private readonly sessions = new Map<string, [number, number]>();\n private readonly users = new Map<string, [number, number]>();\n\n private first = true;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (this.first) {\n this.first = false;\n // Start of the road.\n const noNameSession = ActiveSession.create(noClientName, message);\n this.sessionsInProgress.set(noClientName, noNameSession);\n }\n const session = processQuorumMessages(\n message,\n skipMessage,\n this.sessionsInProgress,\n this.sessions,\n this.users);\n if (!skipMessage && session) {\n session.reportOp(message.timestamp);\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n // Close any open sessions\n reportOpenSessions(\n lastOp.timestamp,\n this.sessionsInProgress,\n this.sessions,\n this.users);\n dumpStats(this.users, {\n title: \"Users\",\n headers: [\"Sessions\", \"Op count\"],\n reverseColumnsInUI: true,\n lines: 6,\n });\n dumpStats(this.sessions, {\n title: \"Sessions\",\n headers: [\"Duration(s)\", \"Op count\"],\n reverseColumnsInUI: true,\n lines: 6,\n });\n dumpStats(this.sessions, {\n title: \"Sessions\",\n headers: [\"Duration(s)\", \"Op count\"],\n orderByFirstColumn: true,\n reverseColumnsInUI: true,\n removeTotals: true,\n lines: 5,\n });\n }\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n private readonly messageTypeStats = new Map<string, [number, number]>();\n private readonly dataType = new Map<string, string>();\n private readonly dataTypeStats = new Map<string, [number, number]>();\n private readonly objectStats = new Map<string, [number, number]>();\n private readonly chunkMap = new Map<string, {chunks: string[], totalSize: number}>();\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (!skipMessage) {\n processOp(\n message,\n this.dataType,\n this.objectStats,\n msgSize,\n this.dataTypeStats,\n this.messageTypeStats,\n this.chunkMap);\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n dumpStats(this.messageTypeStats, {\n title: \"Message Type\",\n headers: [\"Op count\", \"Bytes\"],\n lines: 20,\n });\n dumpStats(calcChannelStats(this.dataType, this.objectStats), {\n title: \"Channel name\",\n headers: [\"Op count\", \"Bytes\"],\n lines: 7,\n });\n /*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n }\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n private sizeTotal = 0;\n private opsTotal = 0;\n private sizeFiltered = 0;\n private opsFiltered = 0;\n private filtered = false;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n this.sizeTotal += msgSize;\n this.opsTotal++;\n if (!skipMessage) {\n this.sizeFiltered += msgSize;\n this.opsFiltered++;\n } else {\n this.filtered = true;\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n if (this.filtered) {\n // eslint-disable-next-line max-len\n console.log(`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`);\n }\n if (this.opsTotal === 0) {\n console.error(\"No ops were found\");\n }\n }\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n private readonly opChunk = 1000;\n private opLimit = 1;\n private size = 0;\n private timeStart = 0;\n private doctimerStart = 0;\n private readonly ranges = new Map<string, [number, number]>();\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (message.sequenceNumber >= this.opLimit) {\n if (message.sequenceNumber !== 1) {\n const timeDiff = durationFromTime(message.timestamp - this.timeStart);\n const opsString = `ops = [${this.opLimit - this.opChunk}, ${this.opLimit - 1}]`.padEnd(26);\n // eslint-disable-next-line max-len\n const timeString = `time = [${durationFromTime(this.timeStart - this.doctimerStart)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n this.ranges.set(\n `${opsString} ${timeString}`,\n [timeDiff, this.size]);\n } else {\n this.doctimerStart = message.timestamp;\n }\n this.opLimit += this.opChunk;\n this.size = 0;\n this.timeStart = message.timestamp;\n }\n if (!skipMessage) {\n this.size += msgSize;\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n dumpStats(this.ranges, {\n title: \"Fastest 1000 op ranges\",\n headers: [\"Duration(s)\", \"Bytes\"],\n orderByFirstColumn: true,\n reverseSort: true,\n removeTotals: true,\n lines: 3,\n });\n }\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n private maxCollabWindow = 0;\n private opSeq = 0;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n const value = message.sequenceNumber - message.minimumSequenceNumber;\n if (value > this.maxCollabWindow) {\n this.maxCollabWindow = value;\n this.opSeq = message.sequenceNumber;\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n console.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n }\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n private lastSummaryOp = 0;\n private maxDistance = 0;\n private maxSeq = 0;\n private minDistance = Number.MAX_SAFE_INTEGER;\n private minSeq = 0;\n private maxResponse = 0;\n private maxResponseSeq = 0;\n\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (message.type === MessageType.SummaryAck) {\n const distance = message.sequenceNumber - this.lastSummaryOp - 1;\n if (this.maxDistance < distance) {\n this.maxDistance = distance;\n this.maxSeq = message.sequenceNumber;\n }\n if (this.minDistance > distance) {\n this.minDistance = distance;\n this.minSeq = message.sequenceNumber;\n }\n\n this.lastSummaryOp = message.sequenceNumber;\n }\n if (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n const contents: ISummaryProposal = message.contents.summaryProposal;\n const distance = message.sequenceNumber - contents.summarySequenceNumber;\n if (distance > this.maxResponse) {\n this.maxResponse = distance;\n this.maxResponseSeq = message.sequenceNumber;\n }\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n const distance = lastOp.sequenceNumber - this.lastSummaryOp;\n if (this.maxDistance < distance) {\n this.maxDistance = distance;\n this.maxSeq = lastOp.sequenceNumber + 1;\n }\n\n console.log(\"\");\n if (this.minDistance === Number.MAX_SAFE_INTEGER) {\n console.log(\"No summaries found in this document\");\n } else {\n console.log(`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`);\n console.log(`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`);\n console.log(`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`);\n }\n }\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {\n if (!skipMessage) {\n console.log(JSON.stringify(message, undefined, 2));\n }\n }\n\n public reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n }\n}\n\nexport async function printMessageStats(\n generator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n dumpMessageStats: boolean,\n dumpMessages: boolean,\n messageTypeFilter: Set<string> = new Set<string>()) {\n let lastMessage: ISequencedDocumentMessage | undefined;\n\n const analyzers: IMessageAnalyzer[] = [\n new FilteredMessageAnalyzer(), // Should come first\n new SessionAnalyzer(),\n new DataStructureAnalyzer(),\n new MessageDensityAnalyzer(),\n new CollabWindowSizeAnalyzer(),\n new SummaryAnalyzer(),\n ];\n\n if (dumpMessages) {\n analyzers.push(new MessageDumper());\n }\n\n for await (const messages of generator) {\n for (const message of (messages as ISequencedDocumentMessage[])) {\n const msgSize = JSON.stringify(message).length;\n lastMessage = message;\n\n const skipMessage = messageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n for (const analyzer of analyzers) {\n analyzer.processOp(message, msgSize, skipMessage);\n }\n }\n }\n\n if (lastMessage !== undefined) {\n if (dumpMessageStats) {\n for (const analyzer of analyzers) {\n analyzer.reportAnalyzes(lastMessage);\n }\n } else {\n // Warn about filtered messages\n analyzers[0].reportAnalyzes(lastMessage);\n }\n }\n console.log(\"\");\n}\n\nfunction processOp(\n message: ISequencedDocumentMessage,\n dataType: Map<string, string>,\n objectStats: Map<string, [number, number]>,\n msgSize: number,\n dataTypeStats: Map<string, [number, number]>,\n messageTypeStats: Map<string, [number, number]>,\n chunkMap: Map<string, {chunks: string[], totalSize: number}>) {\n let type = message.type;\n let recorded = false;\n let totalMsgSize = msgSize;\n let opCount = 1;\n if (isRuntimeMessage(message)) {\n let runtimeMessage = unpackRuntimeMessage(message);\n const messageType = runtimeMessage.type as RuntimeMessage;\n switch (messageType) {\n case RuntimeMessage.Attach: {\n const attachMessage = runtimeMessage.contents as IAttachMessage;\n processDataStoreAttachOp(attachMessage, dataType);\n break;\n }\n // skip for now because these ops do not have contents\n case RuntimeMessage.BlobAttach: {\n break;\n }\n case RuntimeMessage.ChunkedOp: {\n const chunk = runtimeMessage.contents as IChunkedOp;\n if (!chunkMap.has(runtimeMessage.clientId)) {\n chunkMap.set(runtimeMessage.clientId, {chunks: new Array<string>(chunk.totalChunks), totalSize:0});\n }\n const value = chunkMap.get(runtimeMessage.clientId);\n assert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n const chunks = value.chunks;\n const chunkIndex = chunk.chunkId - 1;\n if (chunks[chunkIndex] !== undefined) {\n throw new Error(\"Chunk already assigned\");\n }\n chunks[chunkIndex] = chunk.contents;\n value.totalSize += msgSize;\n if (chunk.chunkId === chunk.totalChunks) {\n opCount = chunk.totalChunks; // 1 op for each chunk.\n runtimeMessage = Object.create(runtimeMessage);\n runtimeMessage.contents = chunks.join(\"\");\n runtimeMessage.type = chunk.originalType;\n type = chunk.originalType;\n totalMsgSize = value.totalSize;\n chunkMap.delete(runtimeMessage.clientId);\n } else {\n return;\n }\n // eslint-disable-next-line no-fallthrough\n }\n case RuntimeMessage.FluidDataStoreOp:\n case RuntimeMessage.Alias:\n case RuntimeMessage.Rejoin:\n case RuntimeMessage.Operation:\n {\n let envelope = runtimeMessage.contents as IEnvelope;\n // TODO: Legacy?\n if (envelope && typeof envelope === \"string\") {\n envelope = JSON.parse(envelope);\n }\n const innerContent = envelope.contents as {\n content: any;\n type: string;\n };\n const address = envelope.address;\n type = `${type}/${innerContent.type}`;\n switch (innerContent.type) {\n case DataStoreMessageType.Attach: {\n const attachMessage = innerContent.content as IAttachMessage;\n let objectType = attachMessage.type;\n if (objectType.startsWith(objectTypePrefix)) {\n objectType = objectType.substring(objectTypePrefix.length);\n }\n dataType.set(getObjectId(address, attachMessage.id), objectType);\n break;\n }\n case DataStoreMessageType.ChannelOp:\n default: {\n const innerEnvelope = innerContent.content as IEnvelope;\n const innerContent2 = innerEnvelope.contents as {\n type?: string;\n value?: any;\n };\n\n const objectId = getObjectId(address, innerEnvelope.address);\n incr(objectStats, objectId, totalMsgSize, opCount);\n let objectType = dataType.get(objectId);\n if (objectType === undefined) {\n // Somehow we do not have data...\n dataType.set(objectId, objectId);\n objectType = objectId;\n }\n incr(dataTypeStats, objectType, totalMsgSize, opCount);\n recorded = true;\n\n let subType = innerContent2.type;\n if (innerContent2.type === \"set\" &&\n typeof innerContent2.value === \"object\" &&\n innerContent2.value !== null) {\n type = `${type}/${subType}`;\n subType = innerContent2.value.type;\n } else if (objectType === \"mergeTree\" && subType !== undefined) {\n const types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n if (types[subType]) {\n subType = types[subType];\n }\n }\n if (subType !== undefined) {\n type = `${type}/${subType}`;\n }\n\n type = `${type} (${objectType})`;\n }\n }\n break;\n }\n default:\n unreachableCase(messageType, \"Message type not recognized!\");\n }\n }\n\n incr(messageTypeStats, type, totalMsgSize, opCount);\n if (!recorded) {\n // const objectId = `${type} (system)`;\n const objectId = `(system messages)`;\n const objectType = objectId;\n if (dataType.get(objectId) === undefined) {\n dataType.set(objectId, objectId);\n }\n incr(objectStats, objectId, totalMsgSize, opCount);\n incr(dataTypeStats, objectType, totalMsgSize, opCount);\n }\n}\n\nfunction processDataStoreAttachOp(\n attachMessage: IAttachMessage | string,\n dataType: Map<string, string>) {\n // dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n // That's data store, and it brings a bunch of data structures.\n // Let's try to crack it.\n let parsedAttachMessage: IAttachMessage;\n if (typeof attachMessage === \"string\") {\n parsedAttachMessage = JSON.parse(attachMessage);\n } else {\n parsedAttachMessage = attachMessage;\n }\n for (const entry of parsedAttachMessage.snapshot.entries) {\n if (entry.type === TreeEntry.Tree) {\n for (const entry2 of entry.value.entries) {\n if (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n const attrib = JSON.parse(entry2.value.contents);\n let objectType = attrib.type;\n if (objectType.startsWith(objectTypePrefix)) {\n objectType = objectType.substring(objectTypePrefix.length);\n }\n dataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n }\n }\n }\n }\n}\n\nfunction reportOpenSessions(\n lastOpTimestamp: number,\n sessionsInProgress: Map<string, ActiveSession>,\n sessions: Map<string, [number, number]>,\n users: Map<string, [number, number]>) {\n const activeSessions = new Map<string, [number, number]>();\n\n for (const [clientId, ses] of sessionsInProgress) {\n const sessionInfo = ses.leave(lastOpTimestamp);\n if (clientId !== noClientName) {\n const sessionName = `${clientId} (${sessionInfo.email})`;\n const sessionPayload: [number, number] = [durationFromTime(sessionInfo.duration), sessionInfo.opCount];\n sessions.set(sessionName, sessionPayload);\n activeSessions.set(sessionName, sessionPayload);\n } else {\n sessions.set(\n `Full file lifespan (noClient messages)`,\n [durationFromTime(sessionInfo.duration), sessionInfo.opCount]);\n }\n incr(users, sessionInfo.email, sessionInfo.opCount);\n }\n\n if (activeSessions.size > 0) {\n dumpStats(activeSessions, {\n title: \"Active sessions\",\n headers: [\"Duration\", \"Op count\"],\n lines: 6,\n orderByFirstColumn: true,\n removeTotals: true,\n });\n }\n}\n\nfunction calcChannelStats(dataType: Map<string, string>, objectStats: Map<string, [number, number]>) {\n const channelStats = new Map<string, [number, number]>();\n for (const [objectId, type] of dataType) {\n let value = objectStats.get(objectId);\n if (value === undefined) {\n value = [0, 0];\n }\n if (type === objectId) {\n channelStats.set(`${objectId}`, value);\n } else {\n channelStats.set(`${objectId} (${type})`, value);\n }\n }\n return channelStats;\n}\n\nfunction processQuorumMessages(\n message: ISequencedDocumentMessage,\n skipMessage: boolean,\n sessionsInProgress: Map<string, ActiveSession>,\n sessions: Map<string, [number, number]>,\n users: Map<string, [number, number]>) {\n let session: ActiveSession | undefined;\n const dataString = (message as any).data;\n if (message.type === \"join\") {\n const data = JSON.parse(dataString);\n session = ActiveSession.create(data.detail.user.id, message);\n sessionsInProgress.set(data.clientId, session);\n } else if (message.type === \"leave\") {\n const clientId = JSON.parse(dataString);\n session = sessionsInProgress.get(clientId);\n sessionsInProgress.delete(clientId);\n assert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n if (session) {\n if (!skipMessage) {\n session.reportOp(message.timestamp);\n }\n const sessionInfo: ISessionInfo = session.leave(message.timestamp);\n sessions.set(\n `${clientId} (${sessionInfo.email})`,\n [durationFromTime(sessionInfo.duration), sessionInfo.opCount]);\n incr(users, sessionInfo.email, sessionInfo.opCount);\n session = undefined; // Do not record it second time\n }\n } else {\n // message.clientId can be null\n session = sessionsInProgress.get(message.clientId);\n if (session === undefined) {\n session = sessionsInProgress.get(noClientName);\n assert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n }\n }\n return session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchArgs.d.ts","sourceRoot":"","sources":["../src/fluidFetchArgs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,IAAI,YAAY,SAAQ,CAAC;AAChC,eAAO,IAAI,gBAAgB,SAAQ,CAAC;AACpC,eAAO,IAAI,iBAAiB,SAAQ,CAAC;AACrC,eAAO,IAAI,iBAAiB,SAAQ,CAAC;AACrC,eAAO,IAAI,oBAAoB,SAAQ,CAAC;AACxC,eAAO,IAAI,SAAS,SAAQ,CAAC;AAC7B,eAAO,IAAI,yBAAyB,EAAE,MAAM,GAAG,SAAS,CAAC;AACzD,eAAO,IAAI,wBAAwB,QAAK,CAAC;AACzC,eAAO,IAAI,0BAA0B,SAAO,CAAC;AAC7C,eAAO,IAAI,qBAAqB,SAAQ,CAAC;AAKzC,wBAAgB,mBAAmB,YAIlC;AAED,eAAO,IAAI,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;AAC5C,eAAO,MAAM,iBAAiB,aAAoB,CAAC;AAEnD,eAAO,IAAI,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;AACxC,eAAO,IAAI,QAAQ,EAAE,MAAM,CAAC;AAC5B,eAAO,IAAI,aAAa,EAAE,MAAM,CAAC;AAEjC,eAAO,IAAI,kBAAkB,SAAQ,CAAC;AAEtC,eAAO,IAAI,aAAa,SAAQ,CAAC;AAEjC,eAAO,IAAI,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;AAuBzC,wBAAgB,UAAU,SAOzB;AAID,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,QAQxB;AAED,wBAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"fluidFetchArgs.d.ts","sourceRoot":"","sources":["../src/fluidFetchArgs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,IAAI,YAAY,SAAQ,CAAC;AAChC,eAAO,IAAI,gBAAgB,SAAQ,CAAC;AACpC,eAAO,IAAI,iBAAiB,SAAQ,CAAC;AACrC,eAAO,IAAI,iBAAiB,SAAQ,CAAC;AACrC,eAAO,IAAI,oBAAoB,SAAQ,CAAC;AACxC,eAAO,IAAI,SAAS,SAAQ,CAAC;AAC7B,eAAO,IAAI,yBAAyB,EAAE,MAAM,GAAG,SAAS,CAAC;AACzD,eAAO,IAAI,wBAAwB,QAAK,CAAC;AACzC,eAAO,IAAI,0BAA0B,SAAO,CAAC;AAC7C,eAAO,IAAI,qBAAqB,SAAQ,CAAC;AAKzC,wBAAgB,mBAAmB,YAIlC;AAED,eAAO,IAAI,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;AAC5C,eAAO,MAAM,iBAAiB,aAAoB,CAAC;AAEnD,eAAO,IAAI,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;AACxC,eAAO,IAAI,QAAQ,EAAE,MAAM,CAAC;AAC5B,eAAO,IAAI,aAAa,EAAE,MAAM,CAAC;AAEjC,eAAO,IAAI,kBAAkB,SAAQ,CAAC;AAEtC,eAAO,IAAI,aAAa,SAAQ,CAAC;AAEjC,eAAO,IAAI,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;AAuBzC,wBAAgB,UAAU,SAOzB;AAID,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,QAQxB;AAED,wBAAgB,cAAc,SAsF7B"}
|
package/dist/fluidFetchArgs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidFetchArgs.js","sourceRoot":"","sources":["../src/fluidFetchArgs.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\nimport { URL } from \"url\";\n\nexport let dumpMessages = false;\nexport let dumpMessageStats = false;\nexport let dumpSnapshotStats = false;\nexport let dumpSnapshotTrees = false;\nexport let dumpSnapshotVersions = false;\nexport let overWrite = false;\nexport let paramSnapshotVersionIndex: number | undefined;\nexport let paramNumSnapshotVersions = 10;\nexport let paramUnpackAggregatedBlobs = true;\nexport let paramActualFormatting = false;\n\nlet paramForceTokenReauth = false;\n\n// Only return true once, to reauth on first call.\nexport function getForceTokenReauth() {\n const result = paramForceTokenReauth;\n paramForceTokenReauth = false;\n return result;\n}\n\nexport let paramSaveDir: string | undefined;\nexport const messageTypeFilter = new Set<string>();\n\nexport let paramURL: string | undefined;\nexport let paramJWT: string;\nexport let paramAzureKey: string;\n\nexport let connectToWebSocket = false;\n\nexport let localDataOnly = false;\n\nexport let paramSite: string | undefined;\n\nconst optionsArray =\n [\n [\"--dump:rawmessage\", \"dump all messages\"],\n [\"--dump:snapshotVersion\", \"dump a list of snapshot version\"],\n [\"--dump:snapshotTree\", \"dump the snapshot trees\"],\n [\"--forceTokenReauth\", \"Force reauthorize token (SPO only)\"],\n [\"--stat:message\", \"show message type, channel type, data type statistics\"],\n [\"--stat:snapshot\", \"show a table of snapshot path and blob size\"],\n [\"--stat\", \"Show both messages & snapshot stats\"],\n [\"--filter:messageType <type>\", \"filter message by <type>\"],\n [\"--jwt <token>\", \"token to be used for routerlicious URLs\"],\n [\"--azureKey <key>\", \"secret key for Azure Fluid Relay instance\"],\n [\"--numSnapshotVersions <number>\", \"Number of versions to load (default:10)\"],\n [\"--noUnpack\", \"Do not unpack aggregated blobs\"],\n [\"--actualPayload\", \"Do not format json payloads nicely, preserve actual bytes / formatting in storage\"],\n [\"--saveDir <outdir>\", \"Save data of the snapshots and messages\"],\n [\"--snapshotVersionIndex <number>\", \"Index of the version to dump\"],\n [\"--websocket\", \"Connect to web socket to download initial messages\"],\n [\"--local\", \"Do not connect to storage, use earlier downloaded data. Requires --saveDir.\"],\n ];\n\nexport function printUsage() {\n console.log(\"Usage: fluid-fetch [options] URL\");\n console.log(\"URL: <ODSP URL>|<Routerlicious URL>\");\n console.log(\"Options:\");\n for (const i of optionsArray) {\n console.log(` ${i[0].padEnd(32)}: ${i[1]}`);\n }\n}\n\n// Can be used in unit test to pass in customized argument values\n// More argument options can be added when needed\nexport function setArguments(values: {\n saveDir: string,\n paramURL: string\n dumpMessages?: boolean,\n dumpMessageStats?: boolean,\n dumpSnapshotStats?: boolean,\n dumpSnapshotTrees?: boolean,\n overWrite?: boolean }) {\n paramSaveDir = values.saveDir;\n paramURL = values.paramURL;\n dumpMessages = values.dumpMessages ?? dumpMessages;\n dumpMessageStats = values.dumpMessageStats ?? dumpMessageStats;\n dumpSnapshotStats = values.dumpSnapshotStats ?? dumpSnapshotStats;\n dumpSnapshotTrees = values.dumpSnapshotTrees ?? dumpSnapshotTrees;\n overWrite = values.overWrite ?? overWrite;\n}\n\nexport function parseArguments() {\n for (let i = 2; i < process.argv.length; i++) {\n const arg = process.argv[i];\n switch (arg) {\n case \"--dump:rawmessage\":\n dumpMessages = true;\n break;\n case \"--dump:rawmessage:overwrite\":\n dumpMessages = true;\n overWrite = true;\n break;\n case \"--stat:message\":\n dumpMessageStats = true;\n break;\n case \"--stat\":\n dumpMessageStats = true;\n dumpSnapshotStats = true;\n break;\n case \"--filter:messageType\":\n messageTypeFilter.add(parseStrArg(i++, \"type name for messageType filter\"));\n break;\n case \"--stat:snapshot\":\n dumpSnapshotStats = true;\n break;\n case \"--dump:snapshotVersion\":\n dumpSnapshotVersions = true;\n break;\n case \"--dump:snapshotTree\":\n dumpSnapshotTrees = true;\n break;\n case \"--help\":\n printUsage();\n process.exit(0);\n case \"--jwt\":\n paramJWT = parseStrArg(i++, \"jwt token\");\n break;\n case \"--azureKey\":\n paramAzureKey = parseStrArg(i++, \"Azure Fluid Relay key\");\n break;\n case \"--forceTokenReauth\":\n paramForceTokenReauth = true;\n break;\n case \"--snapshotVersionIndex\":\n paramSnapshotVersionIndex = parseIntArg(i++, \"version index\", true);\n break;\n case \"--numSnapshotVersions\":\n paramNumSnapshotVersions = parseIntArg(i++, \"number of versions\", false);\n break;\n case \"--noUnpack\":\n paramUnpackAggregatedBlobs = false;\n break;\n case \"--actualPayload\":\n paramActualFormatting = true;\n break;\n case \"--saveDir\":\n paramSaveDir = parseStrArg(i++, \"save data path\");\n break;\n case \"--websocket\":\n connectToWebSocket = true;\n break;\n case \"--local\":\n localDataOnly = true;\n break;\n default:\n try {\n const url = new URL(arg);\n if (url.protocol === \"https:\") {\n paramURL = arg;\n break;\n }\n if (url.protocol === \"http:\" && url.hostname === \"localhost\") {\n paramURL = arg;\n break;\n }\n } catch (e) {\n console.error(e);\n }\n\n console.error(`ERROR: Invalid argument ${arg}`);\n printUsage();\n process.exit(-1);\n break;\n }\n }\n checkArgs();\n}\n\nfunction parseStrArg(i: number, name: string) {\n if (i + 1 >= process.argv.length) {\n console.error(`ERROR: Missing ${name}`);\n printUsage();\n process.exit(-1);\n }\n return process.argv[i + 1];\n}\nfunction parseIntArg(i: number, name: string, allowZero: boolean) {\n if (i + 1 >= process.argv.length) {\n console.error(`ERROR: Missing ${name}`);\n printUsage();\n process.exit(-1);\n }\n const numStr = process.argv[i + 1];\n const paramNumber = parseInt(numStr, 10);\n if (isNaN(paramNumber) || (allowZero ? paramNumber < 0 : paramNumber <= 0)) {\n console.error(`ERROR: Invalid ${name} ${numStr}`);\n printUsage();\n process.exit(-1);\n }\n return paramNumber;\n}\n\nfunction checkArgs() {\n if (paramSnapshotVersionIndex !== undefined) {\n paramNumSnapshotVersions = Math.max(paramSnapshotVersionIndex + 1, paramNumSnapshotVersions);\n }\n\n if (!paramURL) {\n if (paramSaveDir) {\n const file = `${paramSaveDir}/info.json`;\n if (fs.existsSync(file)) {\n const info = JSON.parse(fs.readFileSync(file, { encoding: \"utf-8\" }));\n paramURL = info.url;\n } else {\n console.log(`Can't find file ${file}`);\n }\n }\n\n if (!paramURL) {\n console.error(\"ERROR: Missing URL\");\n printUsage();\n process.exit(-1);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fluidFetchArgs.js","sourceRoot":"","sources":["../src/fluidFetchArgs.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport fs from \"fs\";\nimport { URL } from \"url\";\n\nexport let dumpMessages = false;\nexport let dumpMessageStats = false;\nexport let dumpSnapshotStats = false;\nexport let dumpSnapshotTrees = false;\nexport let dumpSnapshotVersions = false;\nexport let overWrite = false;\nexport let paramSnapshotVersionIndex: number | undefined;\nexport let paramNumSnapshotVersions = 10;\nexport let paramUnpackAggregatedBlobs = true;\nexport let paramActualFormatting = false;\n\nlet paramForceTokenReauth = false;\n\n// Only return true once, to reauth on first call.\nexport function getForceTokenReauth() {\n const result = paramForceTokenReauth;\n paramForceTokenReauth = false;\n return result;\n}\n\nexport let paramSaveDir: string | undefined;\nexport const messageTypeFilter = new Set<string>();\n\nexport let paramURL: string | undefined;\nexport let paramJWT: string;\nexport let paramAzureKey: string;\n\nexport let connectToWebSocket = false;\n\nexport let localDataOnly = false;\n\nexport let paramSite: string | undefined;\n\nconst optionsArray =\n [\n [\"--dump:rawmessage\", \"dump all messages\"],\n [\"--dump:snapshotVersion\", \"dump a list of snapshot version\"],\n [\"--dump:snapshotTree\", \"dump the snapshot trees\"],\n [\"--forceTokenReauth\", \"Force reauthorize token (SPO only)\"],\n [\"--stat:message\", \"show message type, channel type, data type statistics\"],\n [\"--stat:snapshot\", \"show a table of snapshot path and blob size\"],\n [\"--stat\", \"Show both messages & snapshot stats\"],\n [\"--filter:messageType <type>\", \"filter message by <type>\"],\n [\"--jwt <token>\", \"token to be used for routerlicious URLs\"],\n [\"--azureKey <key>\", \"secret key for Azure Fluid Relay instance\"],\n [\"--numSnapshotVersions <number>\", \"Number of versions to load (default:10)\"],\n [\"--noUnpack\", \"Do not unpack aggregated blobs\"],\n [\"--actualPayload\", \"Do not format json payloads nicely, preserve actual bytes / formatting in storage\"],\n [\"--saveDir <outdir>\", \"Save data of the snapshots and messages\"],\n [\"--snapshotVersionIndex <number>\", \"Index of the version to dump\"],\n [\"--websocket\", \"Connect to web socket to download initial messages\"],\n [\"--local\", \"Do not connect to storage, use earlier downloaded data. Requires --saveDir.\"],\n ];\n\nexport function printUsage() {\n console.log(\"Usage: fluid-fetch [options] URL\");\n console.log(\"URL: <ODSP URL>|<Routerlicious URL>\");\n console.log(\"Options:\");\n for (const i of optionsArray) {\n console.log(` ${i[0].padEnd(32)}: ${i[1]}`);\n }\n}\n\n// Can be used in unit test to pass in customized argument values\n// More argument options can be added when needed\nexport function setArguments(values: {\n saveDir: string,\n paramURL: string\n dumpMessages?: boolean,\n dumpMessageStats?: boolean,\n dumpSnapshotStats?: boolean,\n dumpSnapshotTrees?: boolean,\n overWrite?: boolean }) {\n paramSaveDir = values.saveDir;\n paramURL = values.paramURL;\n dumpMessages = values.dumpMessages ?? dumpMessages;\n dumpMessageStats = values.dumpMessageStats ?? dumpMessageStats;\n dumpSnapshotStats = values.dumpSnapshotStats ?? dumpSnapshotStats;\n dumpSnapshotTrees = values.dumpSnapshotTrees ?? dumpSnapshotTrees;\n overWrite = values.overWrite ?? overWrite;\n}\n\nexport function parseArguments() {\n for (let i = 2; i < process.argv.length; i++) {\n const arg = process.argv[i];\n switch (arg) {\n case \"--dump:rawmessage\":\n dumpMessages = true;\n break;\n case \"--dump:rawmessage:overwrite\":\n dumpMessages = true;\n overWrite = true;\n break;\n case \"--stat:message\":\n dumpMessageStats = true;\n break;\n case \"--stat\":\n dumpMessageStats = true;\n dumpSnapshotStats = true;\n break;\n case \"--filter:messageType\":\n messageTypeFilter.add(parseStrArg(i++, \"type name for messageType filter\"));\n break;\n case \"--stat:snapshot\":\n dumpSnapshotStats = true;\n break;\n case \"--dump:snapshotVersion\":\n dumpSnapshotVersions = true;\n break;\n case \"--dump:snapshotTree\":\n dumpSnapshotTrees = true;\n break;\n case \"--help\":\n printUsage();\n process.exit(0);\n // fallthrough\n case \"--jwt\":\n paramJWT = parseStrArg(i++, \"jwt token\");\n break;\n case \"--azureKey\":\n paramAzureKey = parseStrArg(i++, \"Azure Fluid Relay key\");\n break;\n case \"--forceTokenReauth\":\n paramForceTokenReauth = true;\n break;\n case \"--snapshotVersionIndex\":\n paramSnapshotVersionIndex = parseIntArg(i++, \"version index\", true);\n break;\n case \"--numSnapshotVersions\":\n paramNumSnapshotVersions = parseIntArg(i++, \"number of versions\", false);\n break;\n case \"--noUnpack\":\n paramUnpackAggregatedBlobs = false;\n break;\n case \"--actualPayload\":\n paramActualFormatting = true;\n break;\n case \"--saveDir\":\n paramSaveDir = parseStrArg(i++, \"save data path\");\n break;\n case \"--websocket\":\n connectToWebSocket = true;\n break;\n case \"--local\":\n localDataOnly = true;\n break;\n default:\n try {\n const url = new URL(arg);\n if (url.protocol === \"https:\") {\n paramURL = arg;\n break;\n }\n if (url.protocol === \"http:\" && url.hostname === \"localhost\") {\n paramURL = arg;\n break;\n }\n } catch (e) {\n console.error(e);\n }\n\n console.error(`ERROR: Invalid argument ${arg}`);\n printUsage();\n process.exit(-1);\n break;\n }\n }\n checkArgs();\n}\n\nfunction parseStrArg(i: number, name: string) {\n if (i + 1 >= process.argv.length) {\n console.error(`ERROR: Missing ${name}`);\n printUsage();\n process.exit(-1);\n }\n return process.argv[i + 1];\n}\nfunction parseIntArg(i: number, name: string, allowZero: boolean) {\n if (i + 1 >= process.argv.length) {\n console.error(`ERROR: Missing ${name}`);\n printUsage();\n process.exit(-1);\n }\n const numStr = process.argv[i + 1];\n const paramNumber = parseInt(numStr, 10);\n if (isNaN(paramNumber) || (allowZero ? paramNumber < 0 : paramNumber <= 0)) {\n console.error(`ERROR: Invalid ${name} ${numStr}`);\n printUsage();\n process.exit(-1);\n }\n return paramNumber;\n}\n\nfunction checkArgs() {\n if (paramSnapshotVersionIndex !== undefined) {\n paramNumSnapshotVersions = Math.max(paramSnapshotVersionIndex + 1, paramNumSnapshotVersions);\n }\n\n if (!paramURL) {\n if (paramSaveDir) {\n const file = `${paramSaveDir}/info.json`;\n if (fs.existsSync(file)) {\n const info = JSON.parse(fs.readFileSync(file, { encoding: \"utf-8\" }));\n paramURL = info.url;\n } else {\n console.log(`Can't find file ${file}`);\n }\n }\n\n if (!paramURL) {\n console.error(\"ERROR: Missing URL\");\n printUsage();\n process.exit(-1);\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-tools/fetch-tool",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.1",
|
|
4
4
|
"description": "Console tool to fetch Fluid data from relay service",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": "https://github.com/microsoft/FluidFramework",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"build:full:compile": "npm run build:compile",
|
|
18
18
|
"clean": "rimraf dist *.tsbuildinfo *.build.log",
|
|
19
19
|
"eslint": "eslint --format stylish src",
|
|
20
|
-
"eslint:fix": "eslint --format stylish src --fix",
|
|
20
|
+
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
21
21
|
"lint": "npm run eslint",
|
|
22
22
|
"lint:fix": "npm run eslint:fix",
|
|
23
23
|
"tsc": "tsc",
|
|
@@ -25,39 +25,40 @@
|
|
|
25
25
|
"tsfmt:fix": "tsfmt --replace"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@fluid-tools/fluidapp-odsp-urlresolver": "^0.
|
|
29
|
-
"@fluidframework/azure-client": "^0.
|
|
28
|
+
"@fluid-tools/fluidapp-odsp-urlresolver": "^0.55.1",
|
|
29
|
+
"@fluidframework/azure-client": "^0.55.1",
|
|
30
30
|
"@fluidframework/common-utils": "^0.32.1",
|
|
31
|
-
"@fluidframework/container-runtime": "^0.
|
|
32
|
-
"@fluidframework/datastore": "^0.
|
|
31
|
+
"@fluidframework/container-runtime": "^0.55.1",
|
|
32
|
+
"@fluidframework/datastore": "^0.55.1",
|
|
33
33
|
"@fluidframework/driver-definitions": "^0.43.0",
|
|
34
|
-
"@fluidframework/driver-utils": "^0.
|
|
35
|
-
"@fluidframework/odsp-doclib-utils": "^0.
|
|
36
|
-
"@fluidframework/odsp-driver": "^0.
|
|
37
|
-
"@fluidframework/odsp-driver-definitions": "^0.
|
|
38
|
-
"@fluidframework/odsp-urlresolver": "^0.
|
|
34
|
+
"@fluidframework/driver-utils": "^0.55.1",
|
|
35
|
+
"@fluidframework/odsp-doclib-utils": "^0.55.1",
|
|
36
|
+
"@fluidframework/odsp-driver": "^0.55.1",
|
|
37
|
+
"@fluidframework/odsp-driver-definitions": "^0.55.1",
|
|
38
|
+
"@fluidframework/odsp-urlresolver": "^0.55.1",
|
|
39
39
|
"@fluidframework/protocol-definitions": "^0.1026.0",
|
|
40
|
-
"@fluidframework/routerlicious-driver": "^0.
|
|
41
|
-
"@fluidframework/routerlicious-urlresolver": "^0.
|
|
42
|
-
"@fluidframework/runtime-definitions": "^0.
|
|
43
|
-
"@fluidframework/telemetry-utils": "^0.
|
|
44
|
-
"@fluidframework/test-client-utils": "^0.
|
|
45
|
-
"@fluidframework/tool-utils": "^0.
|
|
40
|
+
"@fluidframework/routerlicious-driver": "^0.55.1",
|
|
41
|
+
"@fluidframework/routerlicious-urlresolver": "^0.55.1",
|
|
42
|
+
"@fluidframework/runtime-definitions": "^0.55.1",
|
|
43
|
+
"@fluidframework/telemetry-utils": "^0.55.1",
|
|
44
|
+
"@fluidframework/test-client-utils": "^0.55.1",
|
|
45
|
+
"@fluidframework/tool-utils": "^0.55.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@fluidframework/build-common": "^0.23.0",
|
|
49
|
-
"@fluidframework/eslint-config-fluid": "^0.
|
|
49
|
+
"@fluidframework/eslint-config-fluid": "^0.25.0",
|
|
50
|
+
"@rushstack/eslint-config": "^2.5.1",
|
|
50
51
|
"@types/node": "^14.18.0",
|
|
51
|
-
"@typescript-eslint/eslint-plugin": "~
|
|
52
|
-
"@typescript-eslint/parser": "~
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "~5.9.0",
|
|
53
|
+
"@typescript-eslint/parser": "~5.9.0",
|
|
53
54
|
"concurrently": "^6.2.0",
|
|
54
|
-
"eslint": "~
|
|
55
|
+
"eslint": "~8.6.0",
|
|
56
|
+
"eslint-plugin-editorconfig": "~3.2.0",
|
|
55
57
|
"eslint-plugin-eslint-comments": "~3.2.0",
|
|
56
|
-
"eslint-plugin-import": "~2.
|
|
58
|
+
"eslint-plugin-import": "~2.25.4",
|
|
57
59
|
"eslint-plugin-no-null": "~1.0.2",
|
|
58
|
-
"eslint-plugin-
|
|
59
|
-
"eslint-plugin-
|
|
60
|
-
"eslint-plugin-unicorn": "~26.0.1",
|
|
60
|
+
"eslint-plugin-react": "~7.28.0",
|
|
61
|
+
"eslint-plugin-unicorn": "~40.0.0",
|
|
61
62
|
"rimraf": "^2.6.2",
|
|
62
63
|
"typescript": "~4.1.3",
|
|
63
64
|
"typescript-formatter": "7.1.0"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { assert } from "@fluidframework/common-utils";
|
|
6
|
+
import { assert, unreachableCase } from "@fluidframework/common-utils";
|
|
7
7
|
import {
|
|
8
8
|
ISequencedDocumentMessage,
|
|
9
9
|
ISummaryProposal,
|
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
} from "@fluidframework/protocol-definitions";
|
|
13
13
|
import { IAttachMessage, IEnvelope } from "@fluidframework/runtime-definitions";
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
IChunkedOp,
|
|
16
16
|
isRuntimeMessage,
|
|
17
|
+
RuntimeMessage,
|
|
17
18
|
unpackRuntimeMessage,
|
|
18
19
|
} from "@fluidframework/container-runtime";
|
|
19
20
|
import { DataStoreMessageType } from "@fluidframework/datastore";
|
|
@@ -21,12 +22,12 @@ import { DataStoreMessageType } from "@fluidframework/datastore";
|
|
|
21
22
|
const noClientName = "No Client";
|
|
22
23
|
const objectTypePrefix = "https://graph.microsoft.com/types/";
|
|
23
24
|
|
|
24
|
-
function incr(map: Map<string, [number, number]>, key: string, size: number) {
|
|
25
|
+
function incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {
|
|
25
26
|
const value = map.get(key);
|
|
26
27
|
if (value === undefined) {
|
|
27
|
-
map.set(key, [
|
|
28
|
+
map.set(key, [count, size]);
|
|
28
29
|
} else {
|
|
29
|
-
value[0]
|
|
30
|
+
value[0] += count;
|
|
30
31
|
value[1] += size;
|
|
31
32
|
map.set(key, value);
|
|
32
33
|
}
|
|
@@ -225,6 +226,7 @@ class DataStructureAnalyzer implements IMessageAnalyzer {
|
|
|
225
226
|
private readonly dataType = new Map<string, string>();
|
|
226
227
|
private readonly dataTypeStats = new Map<string, [number, number]>();
|
|
227
228
|
private readonly objectStats = new Map<string, [number, number]>();
|
|
229
|
+
private readonly chunkMap = new Map<string, {chunks: string[], totalSize: number}>();
|
|
228
230
|
|
|
229
231
|
public processOp(message: ISequencedDocumentMessage, msgSize: number, skipMessage: boolean): void {
|
|
230
232
|
if (!skipMessage) {
|
|
@@ -234,7 +236,8 @@ class DataStructureAnalyzer implements IMessageAnalyzer {
|
|
|
234
236
|
this.objectStats,
|
|
235
237
|
msgSize,
|
|
236
238
|
this.dataTypeStats,
|
|
237
|
-
this.messageTypeStats
|
|
239
|
+
this.messageTypeStats,
|
|
240
|
+
this.chunkMap);
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
243
|
|
|
@@ -475,22 +478,57 @@ function processOp(
|
|
|
475
478
|
objectStats: Map<string, [number, number]>,
|
|
476
479
|
msgSize: number,
|
|
477
480
|
dataTypeStats: Map<string, [number, number]>,
|
|
478
|
-
messageTypeStats: Map<string, [number, number]
|
|
481
|
+
messageTypeStats: Map<string, [number, number]>,
|
|
482
|
+
chunkMap: Map<string, {chunks: string[], totalSize: number}>) {
|
|
479
483
|
let type = message.type;
|
|
480
484
|
let recorded = false;
|
|
485
|
+
let totalMsgSize = msgSize;
|
|
486
|
+
let opCount = 1;
|
|
481
487
|
if (isRuntimeMessage(message)) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
488
|
+
let runtimeMessage = unpackRuntimeMessage(message);
|
|
489
|
+
const messageType = runtimeMessage.type as RuntimeMessage;
|
|
490
|
+
switch (messageType) {
|
|
491
|
+
case RuntimeMessage.Attach: {
|
|
485
492
|
const attachMessage = runtimeMessage.contents as IAttachMessage;
|
|
486
493
|
processDataStoreAttachOp(attachMessage, dataType);
|
|
487
494
|
break;
|
|
488
495
|
}
|
|
489
496
|
// skip for now because these ops do not have contents
|
|
490
|
-
case
|
|
497
|
+
case RuntimeMessage.BlobAttach: {
|
|
491
498
|
break;
|
|
492
499
|
}
|
|
493
|
-
|
|
500
|
+
case RuntimeMessage.ChunkedOp: {
|
|
501
|
+
const chunk = runtimeMessage.contents as IChunkedOp;
|
|
502
|
+
if (!chunkMap.has(runtimeMessage.clientId)) {
|
|
503
|
+
chunkMap.set(runtimeMessage.clientId, {chunks: new Array<string>(chunk.totalChunks), totalSize:0});
|
|
504
|
+
}
|
|
505
|
+
const value = chunkMap.get(runtimeMessage.clientId);
|
|
506
|
+
assert(value !== undefined, 0x2b8 /* "Chunk should be set in map" */);
|
|
507
|
+
const chunks = value.chunks;
|
|
508
|
+
const chunkIndex = chunk.chunkId - 1;
|
|
509
|
+
if (chunks[chunkIndex] !== undefined) {
|
|
510
|
+
throw new Error("Chunk already assigned");
|
|
511
|
+
}
|
|
512
|
+
chunks[chunkIndex] = chunk.contents;
|
|
513
|
+
value.totalSize += msgSize;
|
|
514
|
+
if (chunk.chunkId === chunk.totalChunks) {
|
|
515
|
+
opCount = chunk.totalChunks; // 1 op for each chunk.
|
|
516
|
+
runtimeMessage = Object.create(runtimeMessage);
|
|
517
|
+
runtimeMessage.contents = chunks.join("");
|
|
518
|
+
runtimeMessage.type = chunk.originalType;
|
|
519
|
+
type = chunk.originalType;
|
|
520
|
+
totalMsgSize = value.totalSize;
|
|
521
|
+
chunkMap.delete(runtimeMessage.clientId);
|
|
522
|
+
} else {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
// eslint-disable-next-line no-fallthrough
|
|
526
|
+
}
|
|
527
|
+
case RuntimeMessage.FluidDataStoreOp:
|
|
528
|
+
case RuntimeMessage.Alias:
|
|
529
|
+
case RuntimeMessage.Rejoin:
|
|
530
|
+
case RuntimeMessage.Operation:
|
|
531
|
+
{
|
|
494
532
|
let envelope = runtimeMessage.contents as IEnvelope;
|
|
495
533
|
// TODO: Legacy?
|
|
496
534
|
if (envelope && typeof envelope === "string") {
|
|
@@ -521,14 +559,14 @@ function processOp(
|
|
|
521
559
|
};
|
|
522
560
|
|
|
523
561
|
const objectId = getObjectId(address, innerEnvelope.address);
|
|
524
|
-
incr(objectStats, objectId,
|
|
562
|
+
incr(objectStats, objectId, totalMsgSize, opCount);
|
|
525
563
|
let objectType = dataType.get(objectId);
|
|
526
564
|
if (objectType === undefined) {
|
|
527
565
|
// Somehow we do not have data...
|
|
528
566
|
dataType.set(objectId, objectId);
|
|
529
567
|
objectType = objectId;
|
|
530
568
|
}
|
|
531
|
-
incr(dataTypeStats, objectType,
|
|
569
|
+
incr(dataTypeStats, objectType, totalMsgSize, opCount);
|
|
532
570
|
recorded = true;
|
|
533
571
|
|
|
534
572
|
let subType = innerContent2.type;
|
|
@@ -550,11 +588,14 @@ function processOp(
|
|
|
550
588
|
type = `${type} (${objectType})`;
|
|
551
589
|
}
|
|
552
590
|
}
|
|
591
|
+
break;
|
|
553
592
|
}
|
|
593
|
+
default:
|
|
594
|
+
unreachableCase(messageType, "Message type not recognized!");
|
|
554
595
|
}
|
|
555
596
|
}
|
|
556
597
|
|
|
557
|
-
incr(messageTypeStats, type,
|
|
598
|
+
incr(messageTypeStats, type, totalMsgSize, opCount);
|
|
558
599
|
if (!recorded) {
|
|
559
600
|
// const objectId = `${type} (system)`;
|
|
560
601
|
const objectId = `(system messages)`;
|
|
@@ -562,8 +603,8 @@ function processOp(
|
|
|
562
603
|
if (dataType.get(objectId) === undefined) {
|
|
563
604
|
dataType.set(objectId, objectId);
|
|
564
605
|
}
|
|
565
|
-
incr(objectStats, objectId,
|
|
566
|
-
incr(dataTypeStats, objectType,
|
|
606
|
+
incr(objectStats, objectId, totalMsgSize, opCount);
|
|
607
|
+
incr(dataTypeStats, objectType, totalMsgSize, opCount);
|
|
567
608
|
}
|
|
568
609
|
}
|
|
569
610
|
|