Skip to content

Added JDBC db.query.parameter span attributes #13719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

AlixBa
Copy link
Contributor

@AlixBa AlixBa commented Apr 16, 2025

Contribution for #7413

Not entirely sure about/need help/to finish

  • the way to opt-in to this
  • the stringify method for the attribute value

What does it do when opted-in?

query: SELECT * FROM table WHERE id=3
-> db.statement = SELECT * FROM table WHERE id=3
-- disable sanitization

query: SELECT * FROM table WHERE id=?
statement.setParameter(1, 3::int)
-> db.statement = SELECT * FROM table WHERE id=?
-> db.operation.parameter.0=3

Stringified types:

  • numbers
  • strings
  • dates

@AlixBa AlixBa requested a review from a team as a code owner April 16, 2025 08:29
Copy link

linux-foundation-easycla bot commented Apr 16, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@github-actions github-actions bot added the test native This label can be applied to PRs to trigger them to run native tests label Apr 16, 2025
"SELECT 3",
"SELECT ?",
"SELECT 3, $1",
"SELECT ?, $1",
Copy link
Contributor Author

@AlixBa AlixBa Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the 3 sanitized in this case? (not related to this PR, just a regular question)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sanitizer replaces all literals with ?. It does not distinguish where the literal appears or whether it just a random 3 or something sensitive like a password or a credit card number. The purpose of the sanitizer is to protect the users and apm vendors from accidentally sending sensitive information to the apm. Without having looked too much into your PR In my opinion it might be best if you first focus on prepared statements, if users wishes to see parameter values in sanitized queries they can disable the sanitizer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be best if you first focus on prepared statements, if users wishes to see parameter values in sanitized queries they can disable the sanitizer

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern with this PR is more to see parameters of the prepared statement itself. Currently, if I am doing things right, even with the sanitizer disabled, here is what I get from the library when I wrap with an OpenTelmetryDataSource in one of my app

SELECT pg_advisory_xact_lock(('x' || md5(?))::bit(64)::bigint)

where as my initial scala code (Scala + Doobie) looks like this

  private def acquireLockByIdsNel(ids: NonEmptyList[String]): Query0[Unit] = {
    val unique = ids.distinct.sorted
    val frg    = unique.map(id => fr"pg_advisory_xact_lock(('x' || md5($id))::bit(64)::bigint)")
    val all    = fragments.comma(frg)
    (fr"SELECT" ++ all).queryWithLabel[Unit]("SELECT locks")
  }

as this get translated into a PreparedStatement and having no clue about what is currently sent to the DB, I'd like db.(operation|query).parameter to be set. Thing is, ? is already used by the sanitizer. So in order to make things clear for the user, I have to(?) expose them as parameters.

Screenshot 2025-04-16 at 21 11 26

Let me know if I misunderstood or going the wrong direction!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thing is, ? is already used by the sanitizer. So in order to make things clear for the user, I have to(?) expose them as parameters.

I wouldn't be too concerned with this. Firstly users can disable the sanitizer, as far as I can tell currently you basically attempt to undo what the sanitizer does by capturing the value. Secondly I'd expect that most queries that use prepared statements don't contain literals that the sanitizer removes. In your place I would start with capturing the parameters for prepared statements.

Copy link
Contributor Author

@AlixBa AlixBa Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I think that this PR does exactly what I want!
I can remove the db.query.parameter for sanitized parameters from the query if that's an issue. But other than that, the PR captures the parameters from prepared statements

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect that most queries that use prepared statements don't contain literals that the sanitizer removes

ah, I think we should remove sanitization of prepared statement text in upcoming stable database semconv

Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk.

this will also ensure the ? placeholders line up with the db.query.parameter list

I've added this to our tracking issue #12608

@AlixBa AlixBa changed the title Added db.operation.parameter span attributes Added JDBC db.operation.parameter span attributes Apr 16, 2025
@trask
Copy link
Member

trask commented Apr 16, 2025

@AlixBa check out very recent semconv change: open-telemetry/semantic-conventions#2093

@AlixBa
Copy link
Contributor Author

AlixBa commented Apr 23, 2025

hey @laurit
Would you have time to do a first review of this PR? 🙏🏿
Let me know if there is anything I need to do first

| System property | Type | Default | Description |
|---------------------------------------------------------|---------|---------|----------------------------------------------------|
| `otel.instrumentation.jdbc.statement-sanitizer.enabled` | Boolean | `true` | Enables the DB statement sanitization. |
| `otel.instrumentation.jdbc.query-parameter.enabled` | Boolean | `false` | Enables the attribute db.query.parameter.<key> |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This table should be reformatted. The description of the flag needs to include a warning. I'll leave it to @trask to come up with the exact wording, probably something along the lines of WARNING: captured query parameters may contain sensitive information such as passwords, personally identifiable information or protected health info. Exposing such info may result in substantial fines and penalties or criminal liability. Consult your peers, superiors and a legal counsel before enabling this option.

Copy link
Member

@trask trask May 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a good question, I've asked in the community repo

@AlixBa AlixBa changed the title Added JDBC db.operation.parameter span attributes Added JDBC db.query.parameter span attributes Apr 28, 2025
@AlixBa AlixBa requested a review from laurit April 28, 2025 14:02
| System property | Type | Default | Description |
|---------------------------------------------------------|---------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `otel.instrumentation.jdbc.statement-sanitizer.enabled` | Boolean | `true` | Enables the DB statement sanitization. |
| `otel.instrumentation.jdbc.capture-query-parameters` | Boolean | `false` | Enables the attribute db.query.parameter.\<key\>.<br/><br/>WARNING: captured query parameters may contain sensitive information such as passwords, personally identifiable information or protected health info. Exposing such info may result in substantial fines and penalties or criminal liability. Consult your peers, superiors and a legal counsel before enabling this option.<br/><br/>This option will disable otel.instrumentation.jdbc.statement-sanitizer |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be added to metadata.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
test native This label can be applied to PRs to trigger them to run native tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants