Skip to content

[Structured Logging] Public API & Send Logs Envelope #5532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 37 commits into
base: main
Choose a base branch
from

Conversation

denrase
Copy link
Collaborator

@denrase denrase commented Jul 1, 2025

#skip-changelog

📜 Description

  • Adds SentryLogger, which is the user facing API:
// Enable through experimental options
...
options.experimental.enableLogs = true
...

// Log away
SentrySDK.logger.warn("These are not the droids i'm looking for...")
  • Add capture methods to Hub and Client
  • Add enableLogs to experimental options

💡 Motivation and Context

This mirrors the structures we have on the Flutter SDK and should be seen as a first attempt to integrate this into cocoa. So please scrutinise it and give me feedback so we can get this right. 🙇

The placement in the Swift folders of the added classes is also something i was not sure about.

Needed to change SentryLog to a class in order to integrate with the ObjC Hub. Kept as much as possible Swift only and module internal.

Also, this is obviously missing many other features (default attributes, user attributes, client reports, batching, etc), but the PR is large enough as is and I hope that the next ones are smaller again.

Relates to #5122

💚 How did you test it?

Unit tests + tried to send a log in the sample app.

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

Copy link
Contributor

github-actions bot commented Jul 1, 2025

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

Generated by 🚫 dangerJS against 47aba91

Copy link

codecov bot commented Jul 1, 2025

Codecov Report

Attention: Patch coverage is 92.80576% with 10 lines in your changes missing coverage. Please review.

Project coverage is 86.310%. Comparing base (ea5a59b) to head (47aba91).

Files with missing lines Patch % Lines
Sources/Swift/Protocol/SentryLogAttribute.swift 82.142% 5 Missing ⚠️
Sources/Sentry/SentrySDK.m 0.000% 3 Missing ⚠️
Sources/Sentry/SentryDependencyContainer.m 80.000% 1 Missing ⚠️
Sources/Swift/Tools/SentryLogBatcher.swift 96.000% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##              main     #5532       +/-   ##
=============================================
+ Coverage   86.175%   86.310%   +0.134%     
=============================================
  Files          407       409        +2     
  Lines        35091     35217      +126     
  Branches     15025     15291      +266     
=============================================
+ Hits         30240     30396      +156     
+ Misses        4808      4773       -35     
- Partials        43        48        +5     
Files with missing lines Coverage Δ
SentryTestUtils/TestHub.swift 63.636% <100.000%> (+3.636%) ⬆️
Sources/Sentry/SentryHub.m 99.130% <100.000%> (+0.016%) ⬆️
Sources/Swift/Protocol/SentryLog.swift 100.000% <100.000%> (ø)
Sources/Swift/Protocol/SentryLogLevel.swift 100.000% <ø> (ø)
Sources/Swift/SentryExperimentalOptions.swift 83.333% <100.000%> (+1.515%) ⬆️
Sources/Swift/Tools/SentryLogger.swift 100.000% <100.000%> (ø)
Sources/Sentry/SentryDependencyContainer.m 88.181% <80.000%> (-0.191%) ⬇️
Sources/Swift/Tools/SentryLogBatcher.swift 96.000% <96.000%> (ø)
Sources/Sentry/SentrySDK.m 87.401% <0.000%> (-0.694%) ⬇️
Sources/Swift/Protocol/SentryLogAttribute.swift 93.333% <82.142%> (-6.667%) ⬇️

... and 18 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 ea5a59b...47aba91. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

[self.logBatcher processLog:log with:scope];
}

// SentryLogBatcherDelegate
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using the delegation pattern to avoid injecting transportAdapter into the batcher.

- (SentryLogger *)logger SENTRY_THREAD_SANITIZER_DOUBLE_CHECKED_LOCK
{
SENTRY_LAZY_INIT(_logger, ({
_logger = [[SentryLogger alloc] initWithHub: SentrySDK.currentHub
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not happy with using SentrySDK.currentHub static accessor here TBH. Would be great to get your perspective here on how to avoid this. Dependency injection?

super.init()
}

public func trace(_ body: String) {
Copy link
Collaborator Author

@denrase denrase Jul 3, 2025

Choose a reason for hiding this comment

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

These methods are the user facing api, accessed by SentrySDK.logger.trace(...) etc.

@denrase denrase changed the title [Structured Logging] Send logs via envelopes [Structured Logging] Public API & Send Logs Envelope Jul 3, 2025

@_spi(Private) public func processLog(_ log: SentryLog, with scope: Scope) {
do {
let envelope = try SentryEnvelope(logs: [log])
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For now we only create the envelope from logs. Actual batching will be implemented in a later PR.

Copy link
Contributor

github-actions bot commented Jul 3, 2025

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1232.70 ms 1249.21 ms 16.51 ms
Size 23.75 KiB 883.70 KiB 859.95 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
9be5373 1215.92 ms 1239.44 ms 23.52 ms
db9572a 1223.13 ms 1241.60 ms 18.47 ms
aa96485 1215.37 ms 1234.04 ms 18.67 ms
701b301 1226.10 ms 1245.57 ms 19.47 ms
4d264fa 1223.48 ms 1246.91 ms 23.44 ms
8fd192f 1202.10 ms 1220.19 ms 18.09 ms
e18d392 1228.69 ms 1244.43 ms 15.73 ms
d637379 1226.43 ms 1250.77 ms 24.34 ms
7908e84 1224.33 ms 1246.39 ms 22.06 ms
f92cfa9 1228.45 ms 1251.33 ms 22.88 ms

App size

Revision Plain With Sentry Diff
9be5373 23.75 KiB 866.50 KiB 842.75 KiB
db9572a 23.75 KiB 858.64 KiB 834.89 KiB
aa96485 23.75 KiB 874.46 KiB 850.71 KiB
701b301 23.75 KiB 867.16 KiB 843.41 KiB
4d264fa 23.74 KiB 874.07 KiB 850.33 KiB
8fd192f 23.74 KiB 872.75 KiB 849.01 KiB
e18d392 23.75 KiB 866.68 KiB 842.93 KiB
d637379 23.75 KiB 855.38 KiB 831.63 KiB
7908e84 23.74 KiB 872.75 KiB 849.00 KiB
f92cfa9 23.75 KiB 855.38 KiB 831.62 KiB

Previous results on branch: feat/structured-logs-send-via-envelopes

Startup times

Revision Plain With Sentry Diff
1db7d20 1234.14 ms 1252.38 ms 18.23 ms

App size

Revision Plain With Sentry Diff
1db7d20 23.75 KiB 883.70 KiB 859.95 KiB

@@ -14,6 +14,14 @@ NS_ASSUME_NONNULL_BEGIN
replayRecording:(SentryReplayRecording *)replayRecording
video:(NSURL *)videoURL;

- (instancetype)initWithHeader:(SentryEnvelopeItemHeader *)header data:(NSData *)data;
Copy link
Collaborator Author

@denrase denrase Jul 3, 2025

Choose a reason for hiding this comment

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

These are not correct, but it was the only way to get access to SentryEnvelope in the Swift part of the SDK.
The SPM action on CLI is failing, as SentryEnvelope.h cannot be found.

Copy link
Collaborator Author

@denrase denrase Jul 3, 2025

Choose a reason for hiding this comment

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

Failing CI: https://github.com/getsentry/sentry-cocoa/actions/runs/16053769859/job/45302808174?pr=5532

I'm sure there's a correct way to access SDK internal classes from the Swift code that i'm not aware of.


@interface SentryEnvelope ()

- (instancetype)initWithId:(SentryId *_Nullable)id singleItem:(SentryEnvelopeItem *)item;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Dito

@denrase
Copy link
Collaborator Author

denrase commented Jul 3, 2025

API Stability Check is failing for now, as i want to have feedback before resolving this.

@denrase denrase marked this pull request as ready for review July 3, 2025 15:00
@@ -0,0 +1,41 @@
@_implementationOnly import _SentryPrivate
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

SPM is not building as SentryEnvelope can't be accessed.

import Foundation

#if CARTHAGE || SWIFT_PACKAGE
import Sentry._Hybrid
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just a failed attempt to resolve the SPM issue.

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.

1 participant