summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/log-message.js
blob: b5e876b8ea9e6f1d46c4fcb6ef4554e2ba15eab2 (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
// Test behavior of {logMessage: ... } test-only command.

(function() {
'use strict';

const mongo = MongoRunner.runMongod({useLogFiles: true});
const admin = mongo.getDB('admin');

// Use our own log parser instead of `checkLog`
// because we want to force reading from a file.
// {getLog: 'global'} could mask output encoding issues.
// It would also be swell to get the record back as a return value.
function assertContainsLog(expectLog, severityCode) {
    const assertMsg = tojson(expectLog) + '(' + severityCode + ')';
    assert.soon(function() {
        // Search by splitting the log file on newlines,
        // filtering out blanks, parsing the remains as JSON,
        // then filtering on id, attr, and s.
        //
        // We should get precisely one match.
        // Too few and we didn't log,
        // too many and we didn't make the message unique enough.
        const count = cat(mongo.fullOptions.logFile)
                          .split("\n")
                          .filter((l) => l != '')
                          .map((l) => JSON.parse(l))
                          .filter((l) => (l.id === 5060500) && (l.s === severityCode) &&
                                      (0 === bsonWoCompare(l.attr, expectLog)))
                          .length;

        assert.lt(count, 2, "Repeated log entry: " + assertMsg);
        return count === 1;
    }, "Expected log not found: " + assertMsg, 20 * 1000);
}

const severities = {
    'severe': 'F',  // As in 'F'atal.
    'error': 'E',
    'warning': 'W',
    'info': 'I',
    'log': 'I',    // Not a typo.
    'debug': 'D',  // Actually D1-D5, overridden by main loop.
};

function test(msg, extra = undefined, severity = undefined, debug = undefined) {
    // Add entropy to msg to disambiguate multiple passes of the loop.
    if (severity !== undefined) {
        msg = severity + debug + ": " + msg;
    }

    const payload = {logMessage: msg};
    const expectLog = {msg: msg};
    if (extra !== undefined) {
        payload.extra = extra;
        expectLog.extra = extra;
    }

    let expectSeverity = severities['log'];
    if (severity !== undefined) {
        payload.severity = severity;
        if (severity === 'debug') {
            if (debug !== undefined) {
                payload.debugLevel = NumberInt(debug);
            }
            expectSeverity = 'D' + (debug ? debug : 1);
        } else {
            expectSeverity = severities[severity];
        }
    }

    assert.commandWorked(admin.runCommand(payload));
    assertContainsLog(expectLog, expectSeverity);
}

// Quick sanity check before diving deep.
test('Hello World');
test('Hello World', {arg: 'value'});

// Don't up the log level till now in order to avoid aggregious spammage.
admin.setLogLevel(5);

// Now roll up sleeves and check them all.
const testMessage = 'The quick "brown" \'fox\' jumped over,\nthe lazy\tdog.\u0000';
const extras = [
    undefined,
    {},
    {arg: 'value'},
    {arg: [{foo: 'bar'}], baz: 'qux'},
];

extras.forEach(function(extra) {
    Object.keys(severities).forEach(function(severity) {
        test(testMessage, extra, severity);
        if (severity === 'debug') {
            // Above call tests as default debug level,
            // Following loop tests at explicitly debug levels.
            for (let debug = 1; debug < 6; ++debug) {
                test(testMessage, extra, severity, debug);
            }
        }
    });
});

// Reset log level to avoid spammage during shutdown.
admin.setLogLevel(0);

MongoRunner.stopMongod(mongo);
})();