Skip to content

Sanitize Dropwizard metric names to comply with OpenTelemetry spec#15954

Merged
laurit merged 10 commits intomainfrom
copilot/fix-illegal-characters-dropwizard
Jan 22, 2026
Merged

Sanitize Dropwizard metric names to comply with OpenTelemetry spec#15954
laurit merged 10 commits intomainfrom
copilot/fix-illegal-characters-dropwizard

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 20, 2026

Fix illegal characters when bridging from Dropwizard metrics

Based on issue #15931 and OpenTelemetry specification for instrument name syntax:

Plan:

  • Understand the OpenTelemetry spec requirements (alphanumeric, _, ., -, / only; must start with letter; max 255 chars)
  • Create a sanitization method to clean instrument names
  • Update DropwizardMetricsAdapter to sanitize names in all metric creation methods (gauge, counter, histogram, meter, timer)
  • Simplify tests: removed new test methods and updated existing tests to use metric names with special characters
  • Run tests to validate the fix (all tests passed)
  • Address code review feedback:
    • Simplified sanitization to strip invalid characters instead of replacing
    • Return null for invalid names and skip instrument creation (preventing exceptions from propagating to application code)
    • Log warnings when sanitization fails to produce a valid name
    • Log warnings when sanitization changes the metric name
    • Log warnings when truncating metric names exceeding 255 characters
    • Use precompiled regex Pattern for better performance
    • Inlined sanitizedName variable in onGaugeAdded
    • Simplified tests by updating existing ones instead of adding new ones
    • Applied code formatting with spotlessApply
  • Review and finalize

Summary:

Fixed issue where Dropwizard metric names with illegal characters (like single quotes in jvm.memory.pools.CodeHeap-'non-profiled-nmethods'.used) were causing OpenTelemetry validation errors. The solution sanitizes metric names by stripping illegal characters using a precompiled regex Pattern. For invalid names (null, empty, no valid characters, or doesn't start with a letter), logs a warning and skips instrument creation entirely. Also logs warnings when sanitization changes a metric name or when metric names exceed 255 characters and are truncated, providing full visibility into which metrics are affected by the sanitization process.

Original prompt

fix #15931

by stripping illegal characters when briding from dropwizard metrics based on OpenTelemetry specification: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-name-syntax


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix illegal characters when bridging from Dropwizard metrics Sanitize Dropwizard metric names to comply with OpenTelemetry spec Jan 20, 2026
Copilot AI requested a review from trask January 20, 2026 23:15
Comment on lines +55 to +64
/**
* Sanitizes instrument names to comply with OpenTelemetry specification.
* Instrument names must consist of alphanumeric characters, '_', '.', '-', '/',
* and must start with a letter.
* Invalid characters are replaced with '_', and consecutive underscores are collapsed.
* If the name doesn't start with a letter, 'metric_' is prepended.
*
* @param name the original metric name from Dropwizard
* @return the sanitized instrument name
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot keep the logic simple, and just strip invalid characters. If there are no characters left, then throw exception.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Simplified the logic in c9ae12a:

  • Now strips invalid characters instead of replacing with _
  • Throws IllegalArgumentException if name is null, empty, contains no valid characters, or doesn't start with a letter after sanitization
  • Removed the logic for prepending metric_ and collapsing consecutive underscores

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Returning empty string could be weird as probably then the sdk will log a warning that empty string is not a valid name. Perhaps when sanitization fails to come up with a name we should skip creating the instrument? Maybe we should log warning? Maybe we should log something when sanitization changes the name of the instrument?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot

when sanitization fails to come up with a name (it's empty) log a warning and should skip creating the instrument

also log a warning any time that sanitization changes the name of the instrument

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 73747cf:

  • When sanitization fails (returns null), logs a warning and skips instrument creation
  • When sanitization changes the name, logs a warning with both original and sanitized names
  • All tests pass with visible warning logs for the sanitized metric names

Copilot AI requested a review from trask January 20, 2026 23:33
Copilot AI requested a review from trask January 21, 2026 02:11
@trask trask marked this pull request as ready for review January 21, 2026 03:53
@trask trask requested a review from a team as a code owner January 21, 2026 03:53
*/
private static String sanitizeInstrumentName(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Metric name cannot be null or empty");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we shouldn't throw exceptions from here as they'll propagate into application code

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

good point, I checked SDK and it will handle this and return noop instrument

@copilot don't throw exceptions from this method, returning empty string is ok

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i wonder if copilot is referencing this or not, or if we need to use different language

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 54b96e5 - now returns empty string instead of throwing exceptions, which allows the SDK to handle invalid names and return noop instruments

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 54b96e5 - now returns empty string instead of throwing exceptions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i wonder if copilot is referencing this or not, or if we need to use different language

the problem is me #15954 (comment)

Copilot AI requested a review from trask January 21, 2026 16:56
@laurit laurit merged commit 6a2393f into main Jan 22, 2026
86 checks passed
@laurit laurit deleted the copilot/fix-illegal-characters-dropwizard branch January 22, 2026 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instrument name "jvm.memory.pools.CodeHeap-'non-profiled-nmethods'.used" is invalid

4 participants