Skip to content

Commit 738189a

Browse files
committed
feat(sdam_viz): add new tool for visualizing driver sdam changes
1 parent 7fbe763 commit 738189a

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

test/tools/sdam_viz

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env node
2+
'use strict';
3+
4+
const { MongoClient } = require('../..');
5+
const arrayStrictEqual = require('../../lib/core/utils').arrayStrictEqual;
6+
const chalk = require('chalk');
7+
8+
function print(msg) {
9+
console.log(`${chalk.white(new Date().toISOString())} ${msg}`);
10+
}
11+
12+
const uri = process.argv[2];
13+
const client = new MongoClient(uri, {
14+
useNewUrlParser: true,
15+
useUnifiedTopology: true
16+
});
17+
18+
async function run() {
19+
print(`connecting to: ${uri}`);
20+
client.on('serverHeartbeatSucceeded', event =>
21+
print(
22+
`${chalk.yellow('heartbeat')} ${chalk.green('succeeded')} host: '${
23+
event.connectionId
24+
}' ${chalk.gray(`(${event.duration} ms)`)}`
25+
)
26+
);
27+
28+
client.on('serverHeartbeatFailed', event =>
29+
print(
30+
`${chalk.yellow('heartbeat')} ${chalk.red('failed')} host: '${
31+
event.connectionId
32+
}' ${chalk.gray(`(${event.duration} ms)`)}`
33+
)
34+
);
35+
36+
// server information
37+
client.on('serverOpening', event => {
38+
print(`${chalk.cyan('server')} [${event.address}] added to topology#${event.topologyId}`);
39+
});
40+
41+
client.on('serverClosed', event => {
42+
print(`${chalk.cyan('server')} [${event.address}] removed from topology#${event.topologyId}`);
43+
});
44+
45+
client.on('serverDescriptionChanged', event => {
46+
print(`${chalk.cyan('server')} [${event.address}] changed:`);
47+
console.log(serverDescriptionDiff(event.previousDescription, event.newDescription));
48+
});
49+
50+
// topology information
51+
client.on('topologyOpening', event => {
52+
print(`${chalk.magenta('topology')} adding topology#${event.topologyId}`);
53+
});
54+
55+
client.on('topologyClosed', event => {
56+
print(`${chalk.magenta('topology')} removing topology#${event.topologyId}`);
57+
});
58+
59+
client.on('topologyDescriptionChanged', event => {
60+
const diff = topologyDescriptionDiff(event.previousDescription, event.newDescription);
61+
if (diff !== '') {
62+
print(`${chalk.magenta('topology')} [topology#${event.topologyId}] changed:`);
63+
console.log(diff);
64+
}
65+
});
66+
67+
await client.connect();
68+
}
69+
70+
function diff(lhs, rhs, fields, comparator) {
71+
return fields.reduce((diff, field) => {
72+
if (lhs[field] == null || rhs[field] == null) {
73+
return diff;
74+
}
75+
76+
if (!comparator(lhs[field], rhs[field])) {
77+
diff.push(
78+
` ${field}: ${chalk.green(`[${lhs[field]}]`)} => ${chalk.green(`[${rhs[field]}]`)}`
79+
);
80+
}
81+
82+
return diff;
83+
}, []);
84+
}
85+
86+
function serverDescriptionDiff(lhs, rhs) {
87+
const objectIdFields = ['electionId'];
88+
const arrayFields = ['hosts', 'tags'];
89+
const simpleFields = [
90+
'type',
91+
'minWireVersion',
92+
'me',
93+
'setName',
94+
'setVersion',
95+
'electionId',
96+
'primary',
97+
'logicalSessionTimeoutMinutes'
98+
];
99+
100+
return diff(lhs, rhs, simpleFields, (x, y) => x === y)
101+
.concat(diff(lhs, rhs, arrayFields, (x, y) => arrayStrictEqual(x, y)))
102+
.concat(diff(lhs, rhs, objectIdFields, (x, y) => x.equals(y)))
103+
.join(',\n');
104+
}
105+
106+
function topologyDescriptionDiff(lhs, rhs) {
107+
const simpleFields = [
108+
'type',
109+
'setName',
110+
'maxSetVersion',
111+
'stale',
112+
'compatible',
113+
'compatibilityError',
114+
'logicalSessionTimeoutMinutes',
115+
'error',
116+
'commonWireVersion'
117+
];
118+
119+
return diff(lhs, rhs, simpleFields, (x, y) => x === y).join(',\n');
120+
}
121+
122+
run().catch(error => console.log('Caught', error));
123+
process.on('SIGINT', async function() {
124+
await client.close();
125+
});

0 commit comments

Comments
 (0)