Skip to content

Commit 0fb43c7

Browse files
committed
DRIVERS-1204 add general spec, unified format changes, and command logging
1 parent cab0e8a commit 0fb43c7

File tree

90 files changed

+4732
-80
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+4732
-80
lines changed

source/command-monitoring/command-monitoring.rst source/command-logging-and-monitoring/command-logging-and-monitoring.rst

+236-57
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
.. role:: javascript(code)
2+
:language: javascript
3+
4+
==============================
5+
Command Logging and Monitoring
6+
==============================
7+
8+
.. contents::
9+
10+
--------
11+
12+
Testing
13+
=======
14+
15+
Automated Tests
16+
^^^^^^^^^^^^^^^
17+
There are tests in the `Unified Test Format <../../unified-test-format/unified-test-format.rst>`__ for both logging and
18+
monitoring in `/logging/unified </logging/unified>`_ and `/monitoring/unified </monitoring/unified>`_, respectively.
19+
20+
21+
Prose Tests
22+
~~~~~~~~~~~
23+
Drivers MUST implement the following logging prose tests. These tests require the ability to capture log message data in a
24+
structured form as described in the
25+
`Unified Test Format specification <../../unified-test-format/unified-test-format.rst#expectedLogMessage>`__.
26+
27+
*Test 1: Default truncation limit*
28+
29+
1. Configure logging with a minimum severity level of "debug" for the "command" component. Do not explicitly configure the max document length.
30+
2. Construct an array ``docs`` containing the document ``{"x" : "y"}`` repeated 100 times.
31+
3. Insert ``docs`` to a collection via ``insertMany``.
32+
4. Inspect the resulting "command started" log message and assert that the "command" value is a string of length 1000.
33+
5. Inspect the resulting "command succeeded" log message and assert that the "reply" value is a string of length <= 1000.
34+
6. Run ``find()`` on the collection where the document was inserted.
35+
7. Inspect the resulting "command succeeded" log message and assert that the reply is a string of length 1000.
36+
37+
*Test 2: Explicitly configured truncation limit*
38+
39+
1. Configure logging with a minimum severity level of "debug" for the "command" component. Set the max document length to 5 of (your driver's unit of choice for truncation).
40+
2. Run the command ``{"hello": true}```.
41+
3. Inspect the resulting "command started" log message and assert that the "command" value is a string of length 5.
42+
4. Inspect the resulting "command succeeded" log message and assert that the "reply" value is a string of length 5.
43+
5. If the driver attaches raw server responses to failures and can access these via log messages to assert on, run the command
44+
``{"notARealCommand": true}``. Inspect the resulting "command failed" log message and confirm that the server error is
45+
a string of length 5.
46+
47+
*Test 3: Truncation with multi-byte codepoints*
48+
49+
A specific test case is not provided here due to the allowed variations in truncation logic as well as varying extended JSON whitespace usage.
50+
Drivers MUST write language-specific tests that confirm truncation of commands, replies, and (if applicable) server responses included in error
51+
messages work as expected when the data being truncated includes multi-byte Unicode codepoints.
52+
If the driver uses bytes as the unit for max document length, there also MUST be tests confirming that cases where the max byte length falls in
53+
the middle of a multi-byte codepoint are handled gracefully.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
{
2+
"description": "command-logging",
3+
"schemaVersion": "1.11",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client",
8+
"observeLogMessages": {
9+
"command": "debug"
10+
}
11+
}
12+
},
13+
{
14+
"database": {
15+
"id": "database",
16+
"client": "client",
17+
"databaseName": "logging-tests"
18+
}
19+
},
20+
{
21+
"collection": {
22+
"id": "collection",
23+
"database": "database",
24+
"collectionName": "logging-tests-collection"
25+
}
26+
}
27+
],
28+
"initialData": [
29+
{
30+
"collectionName": "logging-tests-collection",
31+
"databaseName": "logging-tests",
32+
"documents": [
33+
{
34+
"_id": 1,
35+
"x": 11
36+
}
37+
]
38+
}
39+
],
40+
"tests": [
41+
{
42+
"description": "A successful command",
43+
"operations": [
44+
{
45+
"name": "runCommand",
46+
"object": "database",
47+
"arguments": {
48+
"command": {
49+
"ping": 1
50+
},
51+
"commandName": "ping"
52+
}
53+
}
54+
],
55+
"expectLogMessages": [
56+
{
57+
"client": "client",
58+
"messages": [
59+
{
60+
"level": "debug",
61+
"component": "command",
62+
"data": {
63+
"message": "Command started",
64+
"databaseName": "logging-tests",
65+
"commandName": "ping",
66+
"command": {
67+
"$$matchAsDocument": {
68+
"$$matchAsRoot": {
69+
"ping": 1,
70+
"$db": "logging-tests"
71+
}
72+
}
73+
},
74+
"requestId": {
75+
"$$exists": true
76+
},
77+
"driverConnectionId": {
78+
"$$exists": true
79+
},
80+
"serverHost": {
81+
"$$exists": true
82+
},
83+
"serverPort": {
84+
"$$exists": true
85+
}
86+
}
87+
},
88+
{
89+
"level": "debug",
90+
"component": "command",
91+
"data": {
92+
"message": "Command succeeded",
93+
"commandName": "ping",
94+
"reply": {
95+
"$$type": "string"
96+
},
97+
"requestId": {
98+
"$$exists": true
99+
},
100+
"driverConnectionId": {
101+
"$$exists": true
102+
},
103+
"serverHost": {
104+
"$$exists": true
105+
},
106+
"serverPort": {
107+
"$$exists": true
108+
},
109+
"durationMS": {
110+
"$$exists": true
111+
}
112+
}
113+
}
114+
]
115+
}
116+
]
117+
},
118+
{
119+
"description": "A failed command",
120+
"operations": [
121+
{
122+
"name": "find",
123+
"object": "collection",
124+
"arguments": {
125+
"filter": {
126+
"$or": true
127+
}
128+
},
129+
"expectError": {
130+
"isClientError": false
131+
}
132+
}
133+
],
134+
"expectLogMessages": [
135+
{
136+
"client": "client",
137+
"messages": [
138+
{
139+
"level": "debug",
140+
"component": "command",
141+
"data": {
142+
"message": "Command started",
143+
"databaseName": "logging-tests",
144+
"commandName": "find",
145+
"command": {
146+
"$$type": "string"
147+
},
148+
"requestId": {
149+
"$$exists": true
150+
},
151+
"driverConnectionId": {
152+
"$$exists": true
153+
},
154+
"serverHost": {
155+
"$$exists": true
156+
},
157+
"serverPort": {
158+
"$$exists": true
159+
}
160+
}
161+
},
162+
{
163+
"level": "debug",
164+
"component": "command",
165+
"data": {
166+
"message": "Command failed",
167+
"commandName": "find",
168+
"failure": {
169+
"$$exists": true
170+
},
171+
"requestId": {
172+
"$$exists": true
173+
},
174+
"driverConnectionId": {
175+
"$$exists": true
176+
},
177+
"serverHost": {
178+
"$$exists": true
179+
},
180+
"serverPort": {
181+
"$$exists": true
182+
},
183+
"durationMS": {
184+
"$$exists": true
185+
}
186+
}
187+
}
188+
]
189+
}
190+
]
191+
}
192+
]
193+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
description: "command-logging"
2+
3+
schemaVersion: "1.11"
4+
5+
createEntities:
6+
- client:
7+
id: &client client
8+
observeLogMessages:
9+
command: debug
10+
- database:
11+
id: &database database
12+
client: *client
13+
databaseName: &databaseName logging-tests
14+
- collection:
15+
id: &collection collection
16+
database: *database
17+
collectionName: &collectionName logging-tests-collection
18+
19+
initialData:
20+
- collectionName: *collectionName
21+
databaseName: *databaseName
22+
documents:
23+
- { _id: 1, x: 11 }
24+
25+
tests:
26+
- description: "A successful command"
27+
operations:
28+
- name: runCommand
29+
object: *database
30+
arguments:
31+
command: { ping: 1 }
32+
commandName: &commandName ping
33+
expectLogMessages:
34+
- client: *client
35+
messages:
36+
- level: debug
37+
component: command
38+
data:
39+
message: "Command started"
40+
databaseName: *databaseName
41+
commandName: *commandName
42+
command:
43+
$$matchAsDocument:
44+
$$matchAsRoot:
45+
ping: 1
46+
$db: *databaseName
47+
requestId: { $$exists: true }
48+
driverConnectionId: { $$exists: true }
49+
serverHost: { $$exists: true }
50+
serverPort: { $$exists: true }
51+
52+
- level: debug
53+
component: command
54+
data:
55+
message: "Command succeeded"
56+
commandName: *commandName
57+
reply: { $$type: string }
58+
requestId: { $$exists: true }
59+
driverConnectionId: { $$exists: true }
60+
serverHost: { $$exists: true }
61+
serverPort: { $$exists: true }
62+
durationMS: { $$exists: true }
63+
64+
- description: "A failed command"
65+
operations:
66+
- name: &commandName find
67+
object: *collection
68+
arguments:
69+
filter: { $or: true }
70+
expectError:
71+
isClientError: false
72+
expectLogMessages:
73+
- client: *client
74+
messages:
75+
- level: debug
76+
component: command
77+
data:
78+
message: "Command started"
79+
databaseName: *databaseName
80+
commandName: *commandName
81+
command: { $$type: string }
82+
requestId: { $$exists: true }
83+
driverConnectionId: { $$exists: true }
84+
serverHost: { $$exists: true }
85+
serverPort: { $$exists: true }
86+
87+
- level: debug
88+
component: command
89+
data:
90+
message: "Command failed"
91+
commandName: *commandName
92+
failure: { $$exists: true }
93+
requestId: { $$exists: true }
94+
driverConnectionId: { $$exists: true }
95+
serverHost: { $$exists: true }
96+
serverPort: { $$exists: true }
97+
durationMS: { $$exists: true }

0 commit comments

Comments
 (0)