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

This PR must also wait for #7077 to be merged

📜 Description

This pull request introduces a new metrics API to the codebase, allowing clients to record custom metrics such as counts, distributions, and gauges. The API is exposed via the SentrySDK.metrics property and is designed for future extensibility, though the current implementation is a no-op.

This PR also adds an example UI to manually collect metrics in iOS-Swift.

💡 Motivation and Context

Closes #6949

💚 How did you test it?

  • Added unit tests

📝 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. → feat(apple): Add documentation for metrics sentry-docs#15822
  • 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.

TODO

  • Add Attributable and AttributeValue to support type-safe bool, string, int, float, double literal values and variables
  • Add AttributeArrayValue to support type-safe arrays without mixed types

@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 2201e78

@philprime philprime marked this pull request as draft December 2, 2025 13:42
@codecov
Copy link

codecov bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 98.84393% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.050%. Comparing base (7e93d85) to head (2201e78).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ntegrations/Metrics/SentryMetricsIntegration.swift 0.000% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##              main     #6957       +/-   ##
=============================================
+ Coverage   84.909%   85.050%   +0.141%     
=============================================
  Files          465       468        +3     
  Lines        28050     28222      +172     
  Branches     12385     12514      +129     
=============================================
+ Hits         23817     24003      +186     
+ Misses        4189      4176       -13     
+ Partials        44        43        -1     
Files with missing lines Coverage Δ
Sources/Swift/Helper/SentrySDK.swift 84.259% <ø> (ø)
.../Swift/Integrations/Metrics/SentryMetricsApi.swift 100.000% <100.000%> (ø)
...ntegrations/Metrics/SentryMetricsApiProtocol.swift 100.000% <100.000%> (ø)
Sources/Swift/Protocol/SentryMetric.swift 100.000% <ø> (ø)
Sources/Swift/Protocol/SentryUnit.swift 100.000% <100.000%> (ø)
Sources/Swift/SentryExperimentalOptions.swift 75.000% <100.000%> (ø)
...ntegrations/Metrics/SentryMetricsIntegration.swift 92.307% <0.000%> (-7.693%) ⬇️

... and 9 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 7e93d85...2201e78. Read the comment docs.

@philprime philprime changed the base branch from philprime/metrics-bootstrap to philprime/metrics December 2, 2025 14:33
@philprime philprime force-pushed the philprime/metrics-public-api branch from 7158dfc to 87379ed Compare December 2, 2025 14:34
@philprime philprime force-pushed the philprime/metrics-public-api branch from 4c30f13 to 02c3573 Compare December 2, 2025 15:23
@philprime philprime changed the base branch from philprime/metrics to philprime/metrics-envelope December 2, 2025 15:26
@philprime philprime force-pushed the philprime/metrics-public-api branch from 02c3573 to 1ab754c Compare December 2, 2025 15:32
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.

Deep Review Summary

I've completed a thorough review comparing this implementation against the official metrics spec and the JavaScript SDK.

🤖 This review was generated with Claude Code to ensure comprehensive spec compliance checking and cross-SDK consistency analysis.

🎯 Overall Assessment: High Quality Implementation (85% Spec Compliant)

This is an excellent, well-architected implementation with several Swift-native improvements over the JavaScript SDK. The type-safe value system, dependency injection pattern, and attribute handling are exemplary.

📊 Priority Breakdown

🔴 HIGH Priority (2 issues in this PR) - Must fix before merge
🟡 MEDIUM Priority (2 issues in this PR) - Should address
🟢 LOW Priority + Praise (3 items) - Nice to have + excellent work

Note: Some issues relate to files from previous PRs (SentryMetricValue, SentryAttributeValue, SentryMetricsBatcher) which I'll comment on separately or in those PRs.

✨ Outstanding Work

Special recognition for:

  1. Clean protocol-based API design
  2. Dependency injection pattern for testability
  3. Comprehensive test coverage (unit + E2E)
  4. Excellent sample code
  5. Type-safe unit enum with generic escape hatch

📋 Spec Compliance: 10/12 Requirements

The main deviations are:

  • ❌ Missing counter default value (easy fix - this PR)
  • ⚠️ Unsigned counter vs signed (previous PR - SentryMetricValue)
  • ✅ Typed unit enum (improvement over spec's free-form strings)

🚀 Recommendation

Fix the 2 HIGH priority issues in this PR, then this is ready to merge. The other issues can be addressed in the related PRs or follow-ups.

Great work on this feature! 🎉


🔄 How to Reproduce This Review

Click to expand: Instructions for re-running this AI-assisted review

Prerequisites

Steps to Reproduce

  1. Navigate to the repository:

    cd /path/to/sentry-cocoa
  2. Open Claude Code in your terminal:

    claude
  3. Use this prompt:

    Please do a very deep review of this PR https://github.com/getsentry/sentry-cocoa/pull/6957. 
    Please don't make any comments to the PR, just give me some comments based on the LOGAF scale. 
    Please also double check very closely if the metrics API aligns with what is specified here 
    https://develop.sentry.dev/sdk/telemetry/metrics/ and also compare it with the metrics 
    implementation of the JS sentry SDK https://github.com/getsentry/sentry-javascript.
    
  4. After receiving the analysis, ask Claude to create the GitHub review:

    Now please add them to a new GH PR review for this PR and not submit the review please. 
    So I can double check the comments on GH and please use the logaf scale with `h`, `m`, `l` 
    prefixes for the comments.
    

What Claude Does

  1. Fetches PR details using gh pr view 6957
  2. Retrieves the official spec from https://develop.sentry.dev/sdk/telemetry/metrics/
  3. Analyzes the JavaScript SDK implementation for comparison
  4. Reads all modified files in the PR
  5. Compares implementation against spec requirements
  6. Generates LOGAF-scaled comments (h=high, m=medium, l=low priority)
  7. Creates a pending GitHub review via the GitHub API

Review Coverage

The AI review checks:

  • ✅ Spec compliance (all required methods, parameters, defaults)
  • ✅ Cross-SDK consistency (comparing with JavaScript SDK)
  • ✅ API ergonomics (Swift-native patterns)
  • ✅ Type safety and error handling
  • ✅ Documentation completeness
  • ✅ Test coverage
  • ✅ Edge cases and potential bugs

Benefits of AI-Assisted Review

  • Comprehensive: Checks every spec requirement systematically
  • Consistent: Uses same criteria across all reviews
  • Cross-SDK awareness: Compares with other language implementations
  • Fast: Analyzes thousands of lines in minutes
  • Learning: Discovers patterns and suggests improvements
  • Documented: Provides reasoning for each comment

Limitations

  • May miss context-specific business logic issues
  • Cannot assess UX/design decisions without user input
  • Line number references may break if PR is updated
  • Best used as a complement to human review, not replacement

Follow-up Reviews

To review subsequent commits:

# Get the new commit SHA
git log origin/philprime/metrics-public-api -1 --format=%H

# Ask Claude to review changes since last review
claude
# Then: "Please review the changes in commit <SHA> against the same spec and JS SDK"

Expands the headerdoc for the metrics property to include:
- Description of what Sentry Metrics does and its capabilities
- Documentation of the three metric types (count, gauge, distribution)
- Code examples showing typical usage patterns
- Requirements section referencing enableMetrics option
- Beta status note
- Important callout explaining Swift-only availability
- Link to full documentation at docs.sentry.io/platforms/apple/metrics/
- Add customer-friendly warning logs when metrics are recorded without
  SDK started or metrics enabled
- Use SentryCurrentDateProvider instead of Date() for testability
- Set traceId at metric creation time instead of deferring to batcher
  to prevent empty traceIds if enrichment fails
- Add comprehensive comments explaining the intentional traceId logic
  duplication with BatcherScope
- Update test mock to include dateProvider dependency
…back

- Fix count value description: UInt is always non-negative, add default note
- Add default value of 1 for count per metrics spec
- Improve unit parameter docs to reference SentryMetricsUnit enum cases
- Fix attributes docs: list correct types (String, Bool, Int, Double + arrays)
- Document that mixed arrays and unsupported types are converted to strings
- Add comment explaining protocol extension pattern for default parameters
- Update docs to clarify units are for telemetry data (Metrics, Spans, Logs)
- Add Equatable to enum declaration, remove manual implementation
- Add comment explaining why RawRepresentable is implemented manually
  (to support custom units via .generic(String) associated value)
- Add XCTAssertNil assertions to count/distribution/gauge disabled tests
- Clarify in comments that when integration is nil, there's no mock to
  verify invocations on - assertion confirms test precondition
- Remove commented empty line before MARK comment
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 🚀

Post edit: LGTM, after resolving the SentryUnit discussion above #6957 (comment)

…eMetric

- Enable metrics by default (options.experimental.enableMetrics = true)
- Rename internal recordMetric to captureMetric to align with SDK terminology
- Update changelog and documentation to reflect the new default
- Fix warning message to reference correct option path
Base automatically changed from philprime/metrics-envelope to main January 15, 2026 18:27
@philprime philprime removed the dontmerge A branch that absolutely should not be merged while this label is applied. label Jan 15, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 15, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Metrics

  • Add public API to collect count, distribution and gauge by philprime in #6957
  • Add implementation for metrics envelope item by philprime in #6960
  • Add integration with installation by SDK by philprime in #6956

Other

  • Add isiOSAppOnVisionOS, isiOSAppOnMac, isMacCatalystApp to device context by philprime in #6939

Bug Fixes 🐛

  • (logs) Use sendDefaultPii and span_id for attributes by philprime in #7055
  • Fix incorrect variable assignment for 'sampled' key by xjshi in #7120
  • Mark dark theme deprecated by noahsmartin in #7114
  • Update raw_description in runtime context for Mac Catalyst App by philprime in #7082
  • Use correct parsing for stackframes by noahsmartin in #6908
  • Transport correctly handling 4xx and 5xx by dfed in #6618

Build / dependencies / internal 🔧

Deps

  • Bump ruby/setup-ruby from 1.279.0 to 1.281.0 by dependabot in #7160
  • Bump getsentry/craft from 2.18.1 to 2.18.3 by dependabot in #7161
  • Bump getsentry/craft/.github/workflows/changelog-preview.yml from 2.18.1 to 2.18.3 by dependabot in #7159
  • Bump ruby/setup-ruby from 1.276.0 to 1.279.0 by dependabot in #7117
  • Bump mikepenz/action-junit-report from 6.0.1 to 6.1.0 by dependabot in #7116
  • Update swiftlint version by github-actions in #7109
  • Bump ruby/setup-ruby from 1.275.0 to 1.276.0 by dependabot in #7103
  • Bump codecov/test-results-action from 1.1.1 to 1.2.1 by itaybre in #7087
  • Bump ruby/setup-ruby from 1.270.0 to 1.275.0 by itaybre in #7088
  • Bump peter-evans/create-pull-request from 7.0.11 to 8.0.0 by dependabot in #7084
  • Bump actions/download-artifact from 6 to 7 by dependabot in #7048
  • Bump aws-sdk-s3 from 1.205.0 to 1.208.0 by dependabot in #7074
  • Bump ruby/setup-ruby from 1.269.0 to 1.270.0 by dependabot in #7049
  • Update clang-format version by github-actions in #7056
  • Bump actions/cache from 4 to 5 by dependabot in #7052
  • Bump actions/upload-artifact from 5 to 6 by dependabot in #7050
  • Bump codecov/codecov-action from 5.5.1 to 5.5.2 by dependabot in #7051

Other

  • (dx) Add structured Makefile with usage description by philprime in #7129
  • (release) Switch from action-prepare-release to Craft (minimal) by BYK in #7153
  • Convert SentryNetworkTrackingIntegration to Swift by itaybre in #7106
  • Update iOS test destination OS version to 18.5 in fast-pr-checks workflow by itaybre in #7168
  • Fix typos in comments in multiple files v2 by philipphofmann in #7139
  • Run visionOS tests on Cirrus Runners + Boot simulator by itaybre in #7147
  • Skip jobs/steps that require secrets for non contributors by itaybre in #7124
  • Add attributable protocol for typed attribute values by philprime in #7077
  • Allow alpha releases on RNSentry.podspec for Cross Platform Test by itaybre in #7130
  • Remove swift5.9 checks by itaybre in #7098
  • Remove duplicate file in project by itaybre in #7093
  • Convert SentryMetricKitIntegration to Swift by noahsmartin in #7076
  • Removes HybridSDK subspec by itaybre in #7019
  • Move testRemoveImageFromTail to flaky plan by itaybre in #7041
  • Use at least xcode 16 for all jobs by itaybre in #7012
  • Cleanup file filter for required files modified by itaybre in #7031
  • Remove assembly workflow files from UI test filter by itaybre in #7030
  • Bumps macOS-14 runner to macOS-15 by itaybre in #7029
  • Ensure required simulators are loaded for all platforms by itaybre in #7022

Other

  • test: Add Options Documentation Sync Tests by philipphofmann in #7075

🤖 This preview updates automatically when you update the PR.

Enhanced the documentation for the metrics feature, explaining that while metrics are enabled by default, they require manual API calls to function and do not automatically capture metrics or affect application behavior. Updated instructions for disabling metrics.
- Consolidated entries in CHANGELOG for metrics integration and API.
- Clarified documentation in SentrySDK regarding the default behavior of metrics and the necessity of manual API calls for functionality.
- Removed unnecessary blank lines throughout the test file to improve readability and maintainability.
- Ensured consistent formatting in the test cases for better clarity.
@philprime philprime enabled auto-merge (squash) January 15, 2026 19:29
- Added "Metrics" to the expected integrations in SentryClientTests and SentrySDKTests.
- Updated assertions in SentryEnabledFeaturesBuilderTests to include "metrics" in the expected features.
- Adjusted SentrySwiftIntegrationInstallerTests to set enableMetrics to false in options.
- Enhanced the xcodebuild script to remove existing result bundles before running tests.
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.

@philprime philprime merged commit 58a9225 into main Jan 16, 2026
197 of 199 checks passed
@philprime philprime deleted the philprime/metrics-public-api branch January 16, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Use this label to trigger all PR workflows Waiting for: Review ⏳

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Metrics] Add public API for integration

4 participants