Skip to content

Conversation

@philprime
Copy link
Member

@philprime philprime commented Dec 2, 2025

This PR is part of a merge-chain and should be merged one-by-one into main as soon as all of them are ready to be merged:

  1. feat(metrics): Add integration with installation by SDK #6956
  2. feat(metrics): Add implementation for metrics envelope item #6960
  3. feat(metrics): Add public API to collect count, distribution and gauge #6957

📜 Description

This PR implements the metrics envelope item functionality for the Sentry Cocoa SDK. It adds the core infrastructure for capturing, batching, and sending metrics to Sentry.

Key Changes

  • SentryMetric Protocol: Added a new SentryMetric class that represents a metric entry with support for:

    • Three metric types: counter, gauge, and distribution
    • Timestamp, trace ID, and optional span ID for distributed tracing
    • Metric name, value, unit, and structured attributes
    • JSON encoding support for envelope serialization
  • SentryMetricBatcher: Implemented a batcher that:

    • Batches metrics together before sending (configurable max count: 100, max buffer size: 1MB)
    • Flushes metrics automatically after a timeout (default: 5 seconds) or when limits are reached
    • Enriches metrics with scope attributes (environment, release, user info, scope attributes)
    • Sets trace ID from propagation context and span ID from active span
    • Supports beforeSendMetric callback for filtering/modifying metrics
  • MetricsIntegration Updates: Enhanced the integration to:

    • Initialize and manage the metric batcher
    • Provide addMetric(_:scope:) API for adding metrics
    • Flush pending metrics on uninstall
  • Client Support: Added captureMetricsData(_:with:) method to SentryClient that:

    • Creates envelope items with type trace_metric
    • Uses content type application/vnd.sentry.items.trace-metric+json
    • Includes item count in the envelope item header
  • Data Category Support: Added trace_metric data category to:

    • SentryDataCategory enum
    • SentryDataCategoryMapper for mapping envelope item types to categories
    • SentryEnvelopeItemType for the envelope item type constant
  • Options: Added beforeSendMetric callback option for filtering/modifying metrics before sending

Testing

Added comprehensive test coverage:

  • SentryMetricTests: Tests for metric creation, encoding, attribute management, and metric type handling
  • SentryMetricBatcherTests: Tests for batching behavior, timeout handling, buffer size limits, attribute enrichment, scope integration, and beforeSendMetric callback
  • MetricsIntegrationTests: Tests for integration initialization and metric addition
  • SentryClientTests: Tests for captureMetricsData envelope creation

💡 Motivation and Context

Closes #6948
Closes #6951
Closes #6952

💚 How did you test it?

  • Added comprehensive unit tests for SentryMetric covering encoding, attribute management, and metric types
  • Added extensive unit tests for SentryMetricBatcher covering batching, flushing, timeout behavior, attribute enrichment, and edge cases
  • Added integration tests for MetricsIntegration and SentryClient metrics capture
  • Verified envelope item creation with correct type and content type
  • Tested data category mapping for trace_metric

📝 Checklist

You have to check all boxes before merging:

  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 2, 2025

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

Generated by 🚫 dangerJS against d73700c

@codecov
Copy link

codecov bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 92.23301% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.990%. Comparing base (e61661b) to head (d73700c).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
Sources/Sentry/SentryClient.m 66.666% 4 Missing ⚠️
Sources/Sentry/SentryDataCategoryMapper.m 33.333% 4 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                        Coverage Diff                        @@
##           philprime/metrics-bootstrap     #6960       +/-   ##
=================================================================
- Coverage                       85.115%   84.990%   -0.125%     
=================================================================
  Files                              461       461               
  Lines                            28043     27730      -313     
  Branches                         12339     12190      -149     
=================================================================
- Hits                             23869     23568      -301     
- Misses                            3916      4123      +207     
+ Partials                           258        39      -219     
Files with missing lines Coverage Δ
SentryTestUtils/Sources/TestClient.swift 86.086% <100.000%> (+0.501%) ⬆️
...ft/Integrations/Metrics/SentryMetricsBatcher.swift 100.000% <100.000%> (ø)
...ntegrations/Metrics/SentryMetricsIntegration.swift 100.000% <100.000%> (ø)
Sources/Swift/Protocol/SentryAttribute.swift 92.187% <ø> (ø)
Sources/Swift/Protocol/SentryMetric.swift 100.000% <100.000%> (ø)
Sources/Swift/Protocol/SentryMetricValue.swift 100.000% <100.000%> (ø)
Sources/Swift/SentryDependencyContainer.swift 98.319% <ø> (-0.977%) ⬇️
Sources/Swift/SentryExperimentalOptions.swift 75.000% <ø> (ø)
Sources/Swift/Tools/Batcher/BatcherScope.swift 100.000% <100.000%> (ø)
Sources/Sentry/SentryClient.m 98.185% <66.666%> (+0.758%) ⬆️
... and 1 more

... and 44 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e61661b...d73700c. Read the comment docs.

@philprime philprime changed the base branch from philprime/metrics-bootstrap to philprime/metrics-stage-1 December 2, 2025 15:06
@philprime philprime changed the base branch from philprime/metrics-stage-1 to philprime/metrics-bootstrap December 2, 2025 15:08
@philprime philprime force-pushed the philprime/metrics-bootstrap branch from a5056fb to 1210307 Compare December 2, 2025 15:13
@philprime philprime force-pushed the philprime/metrics-envelope branch 2 times, most recently from 02c3573 to 303d533 Compare December 2, 2025 15:25
@philprime
Copy link
Member Author

@sentry review

@philprime
Copy link
Member Author

@sentry review

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

I left a couple of comments. Thanks for doing this.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 17, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1203.21 ms 1237.24 ms 34.04 ms
Size 24.14 KiB 1.04 MiB 1.01 MiB

Baseline results on branch: philprime/metrics-bootstrap

Startup times

Revision Plain With Sentry Diff
2d018e1 1227.67 ms 1245.79 ms 18.12 ms
c17fb00 1213.18 ms 1244.28 ms 31.10 ms
1fc93d0 1231.06 ms 1261.37 ms 30.31 ms
b0e9352 1229.50 ms 1265.81 ms 36.31 ms
40a71d5 1221.24 ms 1263.70 ms 42.46 ms
9ee5dae 1205.02 ms 1237.27 ms 32.25 ms
94a1efd 1212.39 ms 1250.19 ms 37.80 ms

App size

Revision Plain With Sentry Diff
2d018e1 24.14 KiB 1.03 MiB 1.01 MiB
c17fb00 24.14 KiB 1.03 MiB 1.00 MiB
1fc93d0 24.14 KiB 1.03 MiB 1.00 MiB
b0e9352 24.14 KiB 1.03 MiB 1.01 MiB
40a71d5 24.14 KiB 1.03 MiB 1.01 MiB
9ee5dae 24.14 KiB 1.03 MiB 1.01 MiB
94a1efd 24.14 KiB 1.03 MiB 1.00 MiB

Previous results on branch: philprime/metrics-envelope

Startup times

Revision Plain With Sentry Diff
63535b8 1228.64 ms 1255.27 ms 26.63 ms
34e473a 1195.53 ms 1222.53 ms 27.00 ms
94c57e8 1190.73 ms 1211.46 ms 20.72 ms
f1ee7f4 1221.29 ms 1248.16 ms 26.87 ms

App size

Revision Plain With Sentry Diff
63535b8 24.14 KiB 1.04 MiB 1.01 MiB
34e473a 24.14 KiB 1.04 MiB 1.01 MiB
94c57e8 24.14 KiB 1.04 MiB 1.01 MiB
f1ee7f4 24.14 KiB 1.04 MiB 1.01 MiB

…umentation, and improve metric handling in tests.
@philprime
Copy link
Member Author

@sentry review
@cursor review

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

LGTM, thanks

Copy link
Member

@philipphofmann philipphofmann left a comment

Choose a reason for hiding this comment

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

Again, LGTM.

@philprime
Copy link
Member Author

Thanks @philipphofmann, I'll keep this PR open and ready-for-merge until #6957 is ready to be merged too (blocked by #7077) so I merge all three PRs directly after another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dontmerge A branch that absolutely should not be merged while this label is applied. ready-to-merge Use this label to trigger all PR workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants