Skip to content

Conversation

@philprime
Copy link
Member

@philprime philprime commented Dec 22, 2025

📜 Description

This PR introduces a protocol-based system for typed attribute values to improve type safety when working with structured logging attributes. The changes add:

  • A type-safe enum SentryAttributeValue that represents attribute values (string, boolean, integer, double, and their array variants)
  • A protocol SentryAttributeValuable that allows types to convert themselves to SentryAttributeValue
  • Extensions on String, Bool, Int, Double, and Float to conform to SentryAttributeValuable

This change refactors the Objective-C compatible SentryAttribute to use the Swift enum SentryAttributeValue as its backing type. It also updates BatcherScope to use SentryAttributeValue directly instead of SentryAttribute objects.

This PR also introduces support for Array attribute types as defined in the documentation.

Changes in Public API:

The currently proposed changes contain new public API endpoints for the SentryLogger to accept [String: SentryAttributeValuable] instead of [String: Any] for improved type safety. I acknowledge this is a breaking change, therefore I am open to remove it until the next major version.

If we keep it it could cause ambiguity issues because we have to method signatures both with the same parameters, only having different Dictionary types as the attributes.

The main use case are the new methods introduced by Metrics in #6957

💡 Motivation and Context

Previously, attributes were stored as [String: Any] dictionaries, which provided no compile-time type safety. This made it easy to accidentally pass unsupported types or incorrect values, which are converted to String as a fallback, sending unpredictable data. By introducing a protocol-based system with SentryAttributeValuable, we can:

  1. Improve the type-safety as the compiler now enforces that only supported types (String, Bool, Int, Double, Float) can be used as attribute values
  2. Simplify API usage as developers can directly pass native Swift types without wrapping them in SentryAttribute objects (using th ExpressibleBy... protocol extensions)
  3. Maintain backward compatibility the SentryAttribute class still exists and can convert from SentryAttributeValue for Objective-C interop.

I also need this change to implement #6957.

💚 How did you test it?

  • Updated existing unit tests in BatcherScopeTests, BatcherTests, and SentryLoggerTests to use the new typed attribute system
  • All tests pass with the new protocol-based approach
  • Verified that the changes maintain the same runtime behavior while improving compile-time safety

📝 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.

@philprime philprime self-assigned this Dec 22, 2025
@codecov
Copy link

codecov bot commented Dec 22, 2025

Codecov Report

❌ Patch coverage is 89.94253% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.794%. Comparing base (33ade5e) to head (8121614).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
Sources/Swift/Protocol/SentryAttributeValue.swift 80.808% 19 Missing ⚠️
Sources/Swift/Protocol/SentryAttribute.swift 86.607% 14 Missing and 1 partial ⚠️
...ources/Swift/Protocol/SentryAttributeContent.swift 98.913% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##              main     #7077       +/-   ##
=============================================
+ Coverage   84.716%   84.794%   +0.078%     
=============================================
  Files          459       461        +2     
  Lines        27494     27780      +286     
  Branches     12120     12317      +197     
=============================================
+ Hits         23292     23556      +264     
- Misses        3942      4183      +241     
+ Partials       260        41      -219     
Files with missing lines Coverage Δ
Sources/Swift/Tools/Batcher/BatcherScope.swift 100.000% <100.000%> (ø)
Sources/Swift/Tools/SentryLogBatcher.swift 95.918% <100.000%> (+0.569%) ⬆️
...ources/Swift/Protocol/SentryAttributeContent.swift 98.913% <98.913%> (ø)
Sources/Swift/Protocol/SentryAttribute.swift 89.583% <86.607%> (-2.605%) ⬇️
Sources/Swift/Protocol/SentryAttributeValue.swift 80.808% <80.808%> (ø)

... and 33 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 33ade5e...8121614. Read the comment docs.

@philprime
Copy link
Member Author

@sentry review
@cursor review

@philprime philprime marked this pull request as ready for review December 22, 2025 09:26
@philprime philprime added the ready-to-merge Use this label to trigger all PR workflows label Dec 22, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 22, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1192.54 ms 1234.89 ms 42.35 ms
Size 24.14 KiB 1.04 MiB 1.02 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
35c962f 1207.61 ms 1235.90 ms 28.29 ms
650d802 1231.86 ms 1255.64 ms 23.78 ms
8ea5293 1242.70 ms 1262.25 ms 19.55 ms
e58d7bf 1219.98 ms 1242.39 ms 22.41 ms
4558de2 1225.29 ms 1258.35 ms 33.06 ms
32f2329 1224.36 ms 1257.33 ms 32.98 ms
0f410ad 1193.34 ms 1255.49 ms 62.15 ms
4be5cd8 1222.35 ms 1251.43 ms 29.07 ms
018037b 1209.31 ms 1228.33 ms 19.03 ms
5aa3ce5 1222.78 ms 1245.39 ms 22.61 ms

App size

Revision Plain With Sentry Diff
35c962f 23.75 KiB 854.77 KiB 831.02 KiB
650d802 23.74 KiB 913.13 KiB 889.39 KiB
8ea5293 23.75 KiB 852.24 KiB 828.49 KiB
e58d7bf 24.15 KiB 1.01 MiB 1014.91 KiB
4558de2 24.14 KiB 1.03 MiB 1.00 MiB
32f2329 23.75 KiB 1.01 MiB 1016.02 KiB
0f410ad 24.14 KiB 1.01 MiB 1014.82 KiB
4be5cd8 23.75 KiB 980.80 KiB 957.06 KiB
018037b 23.75 KiB 867.16 KiB 843.41 KiB
5aa3ce5 23.75 KiB 904.54 KiB 880.79 KiB

Previous results on branch: philprime/attributable

Startup times

Revision Plain With Sentry Diff
0862059 1209.10 ms 1235.65 ms 26.55 ms
cdbc520 1210.64 ms 1248.77 ms 38.13 ms
76e0378 1220.62 ms 1250.33 ms 29.70 ms
c0e1291 1221.29 ms 1240.65 ms 19.36 ms
447a784 1230.52 ms 1256.10 ms 25.58 ms
4ef1623 1213.43 ms 1240.73 ms 27.30 ms
c0e1291 1227.94 ms 1249.06 ms 21.12 ms

App size

Revision Plain With Sentry Diff
0862059 24.14 KiB 1.04 MiB 1.02 MiB
cdbc520 24.14 KiB 1.04 MiB 1.02 MiB
76e0378 24.14 KiB 1.04 MiB 1.01 MiB
c0e1291 24.14 KiB 1.04 MiB 1.02 MiB
447a784 24.14 KiB 1.04 MiB 1.02 MiB
4ef1623 24.14 KiB 1.04 MiB 1.01 MiB
c0e1291 24.14 KiB 1.04 MiB 1.02 MiB

@philprime philprime marked this pull request as draft December 22, 2025 12:22
@philprime
Copy link
Member Author

Array handling is incomplete, moved back to draft

@philprime
Copy link
Member Author

@sentry review
@cursor review

@philprime philprime marked this pull request as ready for review December 22, 2025 13:07
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 really like that we're adding type safety to the attributes with this PR. I think we need some slight tweaking for the public logging API to better communicate which types our users can use, such as:

public func warn(_ message: SentryLogMessage, attributes: [String: SentryAttributeValuable] = [:])

@philprime philprime disabled auto-merge January 8, 2026 13:59
@philprime philprime enabled auto-merge (squash) January 8, 2026 14:04
@philprime philprime disabled auto-merge January 8, 2026 14:04
@philprime philprime enabled auto-merge (squash) January 8, 2026 14:04
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, with a few comments. 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.

LGTM, thanks again.

…perty conversions

Extract attributesDict once before applying all attribute modifications,
then set it back once at the end. This reduces dictionary conversions
from 14 (7 getters + 7 setters) to 2 (1 get + 1 set) when applying
scope attributes to batcher items, improving performance especially
under high-volume logging scenarios.
@philprime philprime merged commit 20d12c6 into main Jan 9, 2026
193 of 195 checks passed
@philprime philprime deleted the philprime/attributable branch January 9, 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.

4 participants