Skip to content

feat: metrics#1498

Open
jpnurmi wants to merge 25 commits intomasterfrom
jpnurmi/feat/metrics
Open

feat: metrics#1498
jpnurmi wants to merge 25 commits intomasterfrom
jpnurmi/feat/metrics

Conversation

@jpnurmi
Copy link
Collaborator

@jpnurmi jpnurmi commented Jan 29, 2026

Summary

Implements the Sentry Metrics feature for the native SDK, allowing applications to record counter, gauge, and distribution metrics that are batched and sent to Sentry: https://develop.sentry.dev/sdk/telemetry/metrics/.

Closes #1453

Features

  • Three metric types: counter, gauge, and distribution
  • Batching: Metrics are buffered and sent in batches (same logic as logs - every 100 items or 5 seconds)
  • Attributes: Automatic default attributes (environment, release, SDK info) plus custom user attributes
  • Trace context: Metrics are automatically associated with the current trace/span
  • Hook: before_send_metric callback for filtering or modifying metrics before sending
  • Unit constants: Pre-defined SENTRY_UNIT_* constants for common telemetry units (byte, kilobyte, millisecond, second, etc.)
  • Parallel flush/close: Logs and metrics flush and shutdown operations run in parallel for faster sentry_flush() and sentry_close()

Public API

// Enable metrics
sentry_options_set_enable_metrics(options, true);

// Record metrics
sentry_metrics_count("api.requests", 1, sentry_value_new_null());
sentry_metrics_gauge("memory.usage", 1024, SENTRY_UNIT_BYTE, sentry_value_new_null());
sentry_metrics_distribution("response.time", 150.5, SENTRY_UNIT_MILLISECOND, attributes);

Considerations

The current API requires passing sentry_value_new_null() when no custom attributes are needed. An alternative would be to provide simplified variants without the attributes parameter (e.g., sentry_metrics_count()) alongside explicit variants (e.g., sentry_metrics_count_with_attributes()). Feedback welcome on which approach is preferred.

Dependencies

Test plan

  • Unit tests for all metric types (tests/unit/test_metrics.c)
  • Integration tests for HTTP transport (tests/test_integration_http.py)
  • Tests for custom attributes, before_send_metric hook, and disabled state
  • Crash-safe flush behavior tested

🤖 Generated with Claude Code

jpnurmi and others added 3 commits January 29, 2026 16:01
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@jpnurmi jpnurmi force-pushed the jpnurmi/feat/metrics branch from 422c6ad to 875c3d9 Compare January 29, 2026 15:01
@jpnurmi jpnurmi changed the title feat: metrics WIP: feat: metrics Jan 29, 2026
jpnurmi and others added 10 commits January 29, 2026 17:18
Per the Sentry metrics specification, counter metrics should use 64-bit
signed integers. This is consistent with sentry_value_new_int64 /
sentry_value_as_int64 in sentry.h.

Also refactored internal record_metric to pass sentry_value_t instead
of double, allowing proper type preservation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The value parameter was not being decremented when metrics were disabled,
causing a memory leak.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SDKs "should offer constants or similar that help customers send in
units we support" as specified in the developer docs.

See:
- https://develop.sentry.dev/sdk/telemetry/metrics/
- https://develop.sentry.dev/sdk/telemetry/attributes/#units

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per the developer docs, units are only used for distribution and gauge
metrics, not counters.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Split blocking shutdown and force_flush operations into begin (non-blocking
trigger) and wait (blocking completion) phases. This allows logs and metrics
operations to run in parallel in sentry_flush() and sentry_close().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add metrics integration tests to match the existing logs test coverage:
- test_metrics_threaded: concurrent metrics from 50 threads
- test_metrics_global_and_local_attributes_merge: global + local attributes
- test_metrics_discarded_on_crash_no_backend: metrics discarded without backend
- test_metrics_on_crash: parameterized test for inproc/breakpad backends

Also refactor thread creation in example.c into a shared run_threads() helper
function used by both logs-threads and metrics-threads commands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow reusing attribute objects across multiple log calls, as documented.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Global attributes set via sentry_set_attribute() were not being merged
into metrics. Now scope attributes are merged with user attributes
having priority on conflicts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@jpnurmi jpnurmi marked this pull request as ready for review February 2, 2026 16:02
@jpnurmi jpnurmi changed the title WIP: feat: metrics feat: metrics Feb 2, 2026
@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against ca4a0e6

jpnurmi and others added 3 commits February 2, 2026 19:38
The split of force_flush into _begin() + _wait() introduced a race where
_begin() wakes the batcher thread, but _wait() could return early if the
batcher thread wins the race to acquire the flushing lock. This could
cause sentry_flush() to return before data was actually sent.

Fix by making sentry__batcher_flush return bool indicating success, and
loop in _wait() until a flush actually completes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
jpnurmi added a commit to getsentry/sentry-docs that referenced this pull request Feb 3, 2026
Document metrics support for the Native SDK being added in
getsentry/sentry-native#1498.

Co-Authored-By: Claude <noreply@anthropic.com>
* Records a counter metric. Counters track incrementing values like
* request counts or error counts.
*/
SENTRY_EXPERIMENTAL_API sentry_metrics_result_t sentry_metrics_count(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Android and Cocoa SDKs expose a unit parameter for count metrics - should we add this for native as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good question. Some SDKs have a unit argument for the counter, while others don't. I also added it there at first, but decided to leave it out because it says in the docs:

The unit of measurement (only used for distribution and gauge)

https://develop.sentry.dev/sdk/telemetry/metrics/#method-signatures

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The unit argument was removed from Cocoa:

During revision of the Method Signatures of the metrics API in the develop docs it was surfaced to me that count metrics do not accept a Metric Unit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@tustanivsky Are you ok with leaving this as is? See Sentry Cocoa 9.4.0:

Breaking Changes

  • Sentry.metrics.count(..) does not support units, therefore the API was incorrectly defined. This breaking change applies to a method marked as experimental. (#7358)

Copy link
Member

@JoshuaMoelans JoshuaMoelans left a comment

Choose a reason for hiding this comment

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

nice work, LGTM! just one small nit on a docstring, and a follow-up for cleaning up our integration test structure

split_log_request_cond,
is_feedback_envelope,
is_logs_envelope,
is_metrics_envelope,
Copy link
Member

Choose a reason for hiding this comment

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

(idea): this integration test file is becoming huge, maybe we should start splitting it up (e.g., additional files for metrics/logs/traces/proxy). I can create a follow-up PR 🧹

jpnurmi and others added 2 commits February 4, 2026 13:56
Co-authored-by: JoshuaMoelans <60878493+JoshuaMoelans@users.noreply.github.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

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.

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.

Sentry Metrics for Native

4 participants