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);
})();
|