Skip to content

mongodb instrumentation should set span.outcome and captureError() on commandFailed #3182

@trentm

Description

@trentm

From #3168 (comment)

About span outcome - the same onEnd event handler is in use for commandSucceeded and commandFailed events:

          client.on('commandSucceeded', onEnd)
          client.on('commandFailed', onEnd)

And it's possible to set outcome by checking event.failure like:

  function onEnd (event) {
    if (!activeSpans.has(event.requestId)) return
    const span = activeSpans.get(event.requestId)
    activeSpans.delete(event.requestId)
    span.setOutcome(event.failure ? 'failure' : 'success')
    span.end((span._timer.start / 1000) + event.duration)
  }

Doc: v4.0 v5.0

This diff to "examples/trace-mongodb.js" shows a way to get a commandFailed event -- a bogus "hint" to a .deleteOne() call (https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteOne/#std-label-ex-deleteOne-hint),

diff --git a/examples/trace-mongodb.js b/examples/trace-mongodb.js
index 2f4f8992..733d8241 100755
--- a/examples/trace-mongodb.js
+++ b/examples/trace-mongodb.js
@@ -42,6 +42,12 @@ async function main () {
     ])
     console.log('insertMany:', res)

+    try {
+      await coll.deleteOne({ item: 'ham' }, { hint: 'foo' })
+    } catch (err) {
+      console.log('error in .deleteOne() with bogus "hint":', err)
+    }
+
     res = await coll.findOne({ item: 'eggs' })
     console.log('findOne eggs:', res)

Running that:

% node examples/trace-mongodb.js
insertMany: {
  acknowledged: true,
  insertedCount: 3,
  insertedIds: {
    '0': new ObjectId("6400e8780cc1a4a785975123"),
    '1': new ObjectId("6400e8780cc1a4a785975124"),
    '2': new ObjectId("6400e8780cc1a4a785975125")
  }
}
error in .deleteOne() with bogus "hint": MongoServerError: error processing query: ns=example-trace-mongodb.breakfastTree: item $eq "ham"
Sort: {}
Proj: {}
 planner returned error :: caused by :: hint provided does not correspond to an existing index
    at /Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/operations/delete.js:60:33
    at /Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/cmap/connection_pool.js:327:25
    at /Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/sdam/server.js:207:17
    at handleOperationResult (/Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/sdam/server.js:323:20)
    at operationDescription.cb (/Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/cmap/connection.js:475:17)
    at Connection.onMessage (/Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/cmap/connection.js:213:9)
    at MessageStream.<anonymous> (/Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/cmap/connection.js:59:60)
    at MessageStream.emit (node:events:513:28)
    at processIncomingData (/Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/cmap/message_stream.js:124:16)
    at MessageStream._write (/Users/trentm/el/apm-agent-nodejs/node_modules/mongodb/lib/cmap/message_stream.js:33:9)
    at writeOrBuffer (node:internal/streams/writable:391:12)
    at _write (node:internal/streams/writable:332:10)
    at MessageStream.Writable.write (node:internal/streams/writable:336:10)
    at Socket.ondata (node:internal/streams/readable:754:22)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:315:12)
    at readableAddChunk (node:internal/streams/readable:289:9)
    at Socket.Readable.push (node:internal/streams/readable:228:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)
    at TCP.callbackTrampoline (node:internal/async_hooks:130:17) {
  index: 0,
  code: 2,
  [Symbol(errorLabels)]: Set(0) {}
}
findOne eggs: { _id: new ObjectId("6400e8780cc1a4a785975125"), item: 'eggs', n: 2 }
findOne eggs: null

results in a trace like this:

    trace b1f040
    `- transaction d40217 "t1" (65.025ms, outcome=unknown)
       `- span ad7344 "example-trace-mongodb.breakfast.insert" (3ms, mongodb, sync)
       `- span c4139c "example-trace-mongodb.breakfast.delete" (1ms, mongodb)   <--- this span
       `- span 325a5b "example-trace-mongodb.breakfast.find" (2ms, mongodb)
       `- span 7ee1b0 "example-trace-mongodb.breakfast.delete" (1ms, mongodb)
       `- span 1342ae "example-trace-mongodb.breakfast.find" (1ms, mongodb)
       `- span b7aec1 "admin.$cmd.endSessions" (0ms, mongodb, sync)

The span marked "this span" should have outcome=failure and should have captured an error event.

Metadata

Metadata

Assignees

Labels

agent-nodejsMake available for APM Agents project planning.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions