Added Sentry.Samples.OpenTelemetry.MongoDB#5335
Conversation
Demonstrates how to instrument MongoDB using OTLP. Spans captured this way are automatically scrubbed and available in Sentry's Queries dashboard.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5335 +/- ##
==========================================
+ Coverage 74.15% 74.18% +0.02%
==========================================
Files 508 508
Lines 18353 18373 +20
Branches 3586 3595 +9
==========================================
+ Hits 13610 13630 +20
Misses 3870 3870
Partials 873 873 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9403424. Configure here.
| Could not connect to MongoDB at {mongoUri} | ||
| Is MongoDB running? See the README.md for this sample for instructions on starting MongoDB using Docker. | ||
| """); | ||
| } |
There was a problem hiding this comment.
Wrong exception type caught
Medium Severity
When MongoDB is unreachable, the driver throws a MongoConnectionException (or another MongoException) after ServerSelectionTimeout, not TimeoutException. The handler meant to print the README Docker hint never runs, so users see an unhandled exception instead of the friendly message.
Reviewed by Cursor Bugbot for commit 9403424. Configure here.
There was a problem hiding this comment.
This is a false positive — catch (TimeoutException) is correct here.
When the server can't be selected within ServerSelectionTimeout, the driver propagates a plain System.TimeoutException, not a MongoException. The MongoConnectionException mentioned above is real, but it's only embedded as the HeartbeatException inside the cluster-state diagnostics of the timeout message — it's the inner reason a server couldn't be selected, not the type that reaches the caller.
Source: Cluster.HandleServerSelectionException (driver v3.9.0) wraps and throws a new TimeoutException(...) — that's the message with the embedded MongoConnectionException that this finding was pattern-matching on.
Verified empirically with driver 3.9.0 and this sample's exact settings (ServerSelectionTimeout = 3s), catching Exception and printing the runtime type:
| Scenario | Thrown type | is TimeoutException |
is MongoException |
|---|---|---|---|
| Connection refused (closed port) | System.TimeoutException |
✅ | ❌ |
| Unreachable host | System.TimeoutException |
✅ | ❌ |
Broadening the catch would actually be a regression: the intent is to show the "Is MongoDB running?" hint only for the connection-timeout case. A genuine MongoException (auth failure, a real query bug, etc.) should surface as itself rather than be masked behind a misleading "is MongoDB running?" message.
| // MongoDB.Driver 3.7.0+ creates OpenTelemetry activities for every command out of the box. | ||
| // TracingOptions is only needed to tweak that behaviour - here we opt in to capturing the query | ||
| // text on each span (off by default), which shows up in Sentry as the `db.query.text` span data. | ||
| // Sentry automatically scrubs query parameter values to protect PII. |
There was a problem hiding this comment.
Does it when going through OTLP endpoint? I am not sure about that 🤔?
There was a problem hiding this comment.
Hm, so it turns out it kind of does but not really. It does for the purposes of grouping queries in the dashboard but ultimately the raw queries are retained for the Trace/Span samples... so from a PII perspective it doesn't.
I've corrected in ce26817 - also added a custom OTEL SpanProcessor to demonstrate how SDK users can implement scrubbing client side.
The blog post will need updating as well - once this PR is merged, I can link to the sample in the repo from the blog post.
There was a problem hiding this comment.
please have a final look at the .NET content from getsentry/sentry-docs#18441 I'm quite confident it's OK, but still 🙏, will need to check the last Symfony error and then it's good to go 🚀
| public override void OnEnd(Activity activity) | ||
| { | ||
| if (activity.GetTagItem("db.query.text") is string queryText) | ||
| { | ||
| activity.SetTag("db.query.text", SensitiveField().Replace(queryText, "$1\"[Filtered]\"")); | ||
| } |
There was a problem hiding this comment.
Bug: The RedactSensitiveMongoData processor calls activity.SetTag() in OnEnd, which is too late in the activity lifecycle. The tag modifications are not exported, causing PII redaction to fail.
Severity: HIGH
Suggested Fix
Move the redaction logic to a point in the OpenTelemetry pipeline before the Activity is stopped. Instead of using BaseProcessor<Activity>.OnEnd, consider creating a custom processor or using a different mechanism that allows modification of tags before the activity is finalized and exported. The goal is to ensure SetTag() is called while the activity's IsRecording property is still true.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location:
samples/Sentry.Samples.OpenTelemetry.MongoDB/RedactSensitiveMongoData.cs#L31-L36
Potential issue: The `RedactSensitiveMongoData` processor attempts to modify an
OpenTelemetry `Activity` by calling `activity.SetTag()` within the `OnEnd` method.
According to OpenTelemetry .NET specifications, the `OnEnd` method is invoked after the
activity has already been stopped. Any tags set on an activity after it has been stopped
are not included in the exported trace data. As a result, the redaction of sensitive
information, such as contributor names in MongoDB queries, will fail silently. This
leads to Personally Identifiable Information (PII) being sent to Sentry unredacted,
defeating the purpose of the processor.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Not true - the redacted spans are hitting Sentry just fine. See this trace, for example:



Demonstrates how to instrument MongoDB using OTLP. Spans captured this way are automatically scrubbed and available in Sentry's Queries dashboard.
I'm not sure if we want to push this in our core repo - technically it's not demonstrating anything Sentry has built (except the OTLP integration - but there are tens of thousands of different ways that can be used). On the other hand, MongoDB is extremely popular and wiring all of this up might not be entirely obvious to SDK users.
Other options (not mutually exclusive):
Note
It would be possible to make Mongo DB instrumentation available even to SDK customers who are not using our OTLP integration... basically we'd have to build an integration that includes a custom ActivityListener that listens to the MongoDB events (similar to what we did to support Microsoft.Extensions.AI.Abstractions) and then translate those into Sentry spans. I'm not sure we want to do that though - it's another thing to maintain. I guess there would have to be clear reasons why customers would want MongoDB instumentation but not be able to or not want to use our OTLP integration. Currently we don't have anyone in that situation talking to us so it may be an imaginary problem to solve.