summaryrefslogtreecommitdiff
path: root/jstests/hooks/run_aggregate_metrics_background.js
blob: 32335852fcd618eaa28249468ada1d4279221493 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
 * Runs the $operationMetrics stage and ensures that all the expected fields are present.
 */

'use strict';

(function() {
load('jstests/libs/discover_topology.js');  // For Topology and DiscoverTopology.

if (typeof db === 'undefined') {
    throw new Error(
        "Expected mongo shell to be connected a server, but global 'db' object isn't defined");
}

// Disable implicit sessions so FSM workloads that kill random sessions won't interrupt the
// operations in this test that aren't resilient to interruptions.
TestData.disableImplicitSessions = true;

const topology = DiscoverTopology.findConnectedNodes(db.getMongo());

const aggregateMetricsBackground = function(host) {
    function verifyFields(doc) {
        const kTopLevelFields = [
            "docBytesWritten",
            "docUnitsWritten",
            "idxEntryBytesWritten",
            "idxEntryUnitsWritten",
            "totalUnitsWritten",
            "cpuNanos",
            "db",
            "primaryMetrics",
            "secondaryMetrics"
        ];
        const kReadFields = [
            "docBytesRead",
            "docUnitsRead",
            "idxEntryBytesRead",
            "idxEntryUnitsRead",
            "keysSorted",
            "docUnitsReturned"
        ];

        for (let key of kTopLevelFields) {
            assert(doc.hasOwnProperty(key), "The metrics output is missing the property: " + key);
        }
        let primaryMetrics = doc.primaryMetrics;
        for (let key of kReadFields) {
            assert(primaryMetrics.hasOwnProperty(key),
                   "The metrics output is missing the property: primaryMetrics." + key);
        }
        let secondaryMetrics = doc.secondaryMetrics;
        for (let key of kReadFields) {
            assert(secondaryMetrics.hasOwnProperty(key),
                   "The metrics output is missing the property: secondaryMetrics." + key);
        }
    }

    let conn = new Mongo(host);
    conn.setSecondaryOk();

    assert.neq(
        null, conn, "Failed to connect to host '" + host + "' for background metrics collection");

    // Filter out arbiters.
    if (conn.adminCommand({isMaster: 1}).arbiterOnly) {
        print("Skipping background aggregation against test node: " + host +
              " because it is an arbiter and has no data.");
        return;
    }

    let db = conn.getDB("admin");
    let clearMetrics = Math.random() < 0.9 ? false : true;
    print("Running $operationMetrics with {clearMetrics: " + clearMetrics + "} on host: " + host);
    const cursor = db.aggregate([{$operationMetrics: {clearMetrics: clearMetrics}}]);
    while (cursor.hasNext()) {
        let doc = cursor.next();
        try {
            verifyFields(doc);
        } catch (e) {
            print("caught exception while verifying that all expected fields are in the metrics " +
                  "output: " + tojson(doc));
            throw (e);
        }
    }
};

// This file is run continuously and is very fast so we want to impose some kind of rate limiting
// which is why we sleep for 1 second here. This sleep is here rather than in
// aggregate_metrics_background.py because the background job that file uses is designed to be run
// continuously so it is easier and cleaner to just sleep here.
sleep(1000);
if (topology.type === Topology.kStandalone) {
    try {
        aggregateMetricsBackground(topology.mongod);
    } catch (e) {
        print("background aggregate metrics against the standalone failed");
        throw e;
    }
} else if (topology.type === Topology.kReplicaSet) {
    for (let replicaMember of topology.nodes) {
        try {
            aggregateMetricsBackground(replicaMember);
        } catch (e) {
            print("background aggregate metrics was not successful against all replica set " +
                  "members");
            throw e;
        }
    }
} else {
    throw new Error("Unsupported topology configuration: " + tojson(topology));
}
})();