Skip to content

Commit

Permalink
Merge branch 'main' into feat/SR-Start-Stop
Browse files Browse the repository at this point in the history
  • Loading branch information
brustolin authored Oct 9, 2024
2 parents 6eb502c + 0a23401 commit 40e71d9
Show file tree
Hide file tree
Showing 61 changed files with 411 additions and 2,527 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@
### Features

- feat: API to manually start/stop Session Replay (#4414)
- Custom redact modifier for SwiftUI (#4362, #4392)

### Removal of Experimental API

- Remove the deprecated experimental Metrics API (#4406): [Learn more](https://sentry.zendesk.com/hc/en-us/articles/26369339769883-Metrics-Beta-Coming-to-an-End)

### Fixes

- Edge case for swizzleClassNameExclude (#4405): Skip creating transactions for UIViewControllers ignored for swizzling
via the option `swizzleClassNameExclude`.
- Add TTID/TTFD spans when loadView gets skipped (#4415)
- Swizzling RootUIViewController if ignored by `swizzleClassNameExclude` (#4407)

### Improvements

- Serializing profile on a BG Thread (#4377) to avoid potentially slightly blocking the main thread.

## 8.38.0-beta.1

Expand All @@ -27,6 +43,8 @@

- Fix the versioning to support app release with Beta versions (#4368)
- Linking ongoing trace to crash event (#4393)
- Edge case for swizzleClassNameExclude (#4405): Skip creating transactions for UIViewControllers ignored for swizzling
via the option `swizzleClassNameExclude`.

## 8.37.0

Expand Down
1 change: 0 additions & 1 deletion Samples/iOS-Swift/iOS-Swift/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
#endif
options.enableTimeToFullDisplayTracing = true
options.enablePerformanceV2 = true
options.enableMetrics = !args.contains("--disable-metrics")

options.add(inAppInclude: "iOS_External")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class SecondarySplitViewController: UIViewController {

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
SentrySDK.reportFullyDisplayed()

if let topvc = TopViewControllerInspector.shared {
topvc.bringToFront()
Expand Down
20 changes: 11 additions & 9 deletions Samples/iOS-SwiftUI/iOS-SwiftUI/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,16 @@ struct ContentView: View {
return SentryTracedView("Content View Body") {
NavigationView {
VStack(alignment: HorizontalAlignment.center, spacing: 16) {
Text(getCurrentTracer()?.transactionContext.name ?? "NO SPAN")
.accessibilityIdentifier("TRANSACTION_NAME")
Text(getCurrentTracer()?.transactionContext.spanId.sentrySpanIdString ?? "NO ID")
.accessibilityIdentifier("TRANSACTION_ID")

Text(getCurrentTracer()?.transactionContext.origin ?? "NO ORIGIN")
.accessibilityIdentifier("TRACE_ORIGIN")

Group {
Text(getCurrentTracer()?.transactionContext.name ?? "NO SPAN")
.accessibilityIdentifier("TRANSACTION_NAME")
Text(getCurrentTracer()?.transactionContext.spanId.sentrySpanIdString ?? "NO ID")
.accessibilityIdentifier("TRANSACTION_ID")
.sentryReplayMask()

Text(getCurrentTracer()?.transactionContext.origin ?? "NO ORIGIN")
.accessibilityIdentifier("TRACE_ORIGIN")
}.sentryReplayUnmask()
SentryTracedView("Child Span") {
VStack {
Text(getCurrentSpan()?.spanDescription ?? "NO SPAN")
Expand Down Expand Up @@ -199,7 +201,7 @@ struct ContentView: View {
Text("Form Screen")
}
}
.sentryReplayMask()
.background(Color.white)
}
SecondView()
}
Expand Down
2 changes: 0 additions & 2 deletions Samples/iOS-SwiftUI/iOS-SwiftUI/SwiftUIApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ struct SwiftUIApp: App {
options.tracesSampleRate = 1.0
options.profilesSampleRate = 1.0
options.experimental.sessionReplay.sessionSampleRate = 1.0
options.experimental.sessionReplay.maskAllImages = false
options.experimental.sessionReplay.maskAllText = false
options.initialScope = { scope in
scope.injectGitInformation()
return scope
Expand Down
117 changes: 12 additions & 105 deletions Sentry.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions Sources/Sentry/Profiling/SentryCaptureTransactionWithProfile.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#import "SentryCaptureTransactionWithProfile.h"

#if SENTRY_TARGET_PROFILING_SUPPORTED

# import "SentryDispatchQueueWrapper.h"
# import "SentryHub+Private.h"
# import "SentryLog.h"
# import "SentryProfiledTracerConcurrency.h"
# import "SentryProfiler+Private.h"
# import "SentryProfilerSerialization.h"
# import "SentryProfilerState.h"
# import "SentrySwift.h"
# import "SentryTracer+Private.h"
# import "SentryTransaction.h"

NS_ASSUME_NONNULL_BEGIN

void
sentry_captureTransactionWithProfile(SentryHub *hub, SentryDispatchQueueWrapper *dispatchQueue,
SentryTransaction *transaction, NSDate *startTimestamp)
{
const auto profiler = sentry_profilerForFinishedTracer(transaction.trace.internalID);
if (!profiler) {
[hub captureTransaction:transaction withScope:hub.scope];
return;
}

// This code can run on the main thread, and the profile serialization can take a couple of
// milliseconds. Therefore, we move this to a background thread to avoid potentially blocking
// the main thread.
[dispatchQueue dispatchAsyncWithBlock:^{
const auto profilingData = [profiler.state copyProfilingData];

const auto profileEnvelopeItem = sentry_traceProfileEnvelopeItem(
hub, profiler, profilingData, transaction, startTimestamp);

if (!profileEnvelopeItem) {
[hub captureTransaction:transaction withScope:hub.scope];
return;
}

[hub captureTransaction:transaction
withScope:hub.scope
additionalEnvelopeItems:@[ profileEnvelopeItem ]];
}];
}

NS_ASSUME_NONNULL_END

#endif // SENTRY_TARGET_PROFILING_SUPPORTED
14 changes: 4 additions & 10 deletions Sources/Sentry/Profiling/SentryProfilerSerialization.mm
Original file line number Diff line number Diff line change
Expand Up @@ -346,22 +346,16 @@
return [[SentryEnvelope alloc] initWithId:chunkID singleItem:envelopeItem];
}

SentryEnvelopeItem *_Nullable sentry_traceProfileEnvelopeItem(
SentryEnvelopeItem *_Nullable sentry_traceProfileEnvelopeItem(SentryHub *hub,
SentryProfiler *profiler, NSDictionary<NSString *, id> *profilingData,
SentryTransaction *transaction, NSDate *startTimestamp)
{
SENTRY_LOG_DEBUG(@"Creating profiling envelope item");
const auto profiler = sentry_profilerForFinishedTracer(transaction.trace.internalID);
if (!profiler) {
return nil;
}

const auto payload = sentry_serializedTraceProfileData(
[profiler.state copyProfilingData], transaction.startSystemTime, transaction.endSystemTime,
profilingData, transaction.startSystemTime, transaction.endSystemTime,
sentry_profilerTruncationReasonName(profiler.truncationReason),
[profiler.metricProfiler serializeTraceProfileMetricsBetween:transaction.startSystemTime
and:transaction.endSystemTime],
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesCrashed:NO],
transaction.trace.hub
[SentryDependencyContainer.sharedInstance.debugImageProvider getDebugImagesCrashed:NO], hub
# if SENTRY_HAS_UIKIT
,
profiler.screenFrameData
Expand Down
40 changes: 4 additions & 36 deletions Sources/Sentry/Public/SentryOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,17 +446,17 @@ NS_SWIFT_NAME(Options)
@property (nonatomic, assign) BOOL enableSwizzling;

/**
* An array of class names to ignore for swizzling.
* A set of class names to ignore for swizzling.
*
* @discussion The SDK checks if a class name of a class to swizzle contains a class name of this
* array. For example, if you add MyUIViewController to this list, the SDK excludes the following
* classes from swizzling: YourApp.MyUIViewController, YourApp.MyUIViewControllerA,
* MyApp.MyUIViewController.
* We can't use an @c NSArray<Class> here because we use this as a workaround for which users have
* We can't use an @c NSSet<Class> here because we use this as a workaround for which users have
* to pass in class names that aren't available on specific iOS versions. By using @c
* NSArray<NSString *>, users can specify unavailable class names.
* NSSet<NSString *>, users can specify unavailable class names.
*
* @note Default is an empty array.
* @note Default is an empty set.
*/
@property (nonatomic, strong) NSSet<NSString *> *swizzleClassNameExcludes;

Expand Down Expand Up @@ -714,38 +714,6 @@ NS_SWIFT_NAME(Options)
*/
@property (nonatomic, copy) NSString *spotlightUrl;

/**
* Wether to enable DDM (delightful developer metrics) or not. For more information see
* https://docs.sentry.io/product/metrics/.
*
* @warning This is an experimental feature and may still have bugs.
* @note Default value is @c NO .
*/
@property (nonatomic, assign) BOOL enableMetrics;

/**
* Wether to enable adding some default tags to every metrics or not. You need to enable @c
* enableMetrics for this flag to work.
*
* @warning This is an experimental feature and may still have bugs.
* @note Default value is @c YES .
*/
@property (nonatomic, assign) BOOL enableDefaultTagsForMetrics;

/**
* Wether to enable connecting metrics to spans and transactions or not. You need to enable @c
* enableMetrics for this flag to work.
*
* @warning This is an experimental feature and may still have bugs.
* @note Default value is @c YES .
*/
@property (nonatomic, assign) BOOL enableSpanLocalMetricAggregation;

/**
* This block can be used to modify the event before it will be serialized and sent.
*/
@property (nullable, nonatomic, copy) SentryBeforeEmitMetricCallback beforeEmitMetric;

/**
* This aggregates options for experimental features.
* Be aware that the options available for experimental can change at any time.
Expand Down
53 changes: 1 addition & 52 deletions Sources/Sentry/SentryHub.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#import "SentryScope+Private.h"
#import "SentrySerialization.h"
#import "SentrySession+Private.h"
#import "SentryStatsdClient.h"
#import "SentrySwift.h"
#import "SentryTraceOrigins.h"
#import "SentryTracer.h"
Expand All @@ -35,7 +34,7 @@

NS_ASSUME_NONNULL_BEGIN

@interface SentryHub () <SentryMetricsAPIDelegate>
@interface SentryHub ()

@property (nullable, nonatomic, strong) SentryClient *client;
@property (nullable, nonatomic, strong) SentryScope *scope;
Expand Down Expand Up @@ -73,18 +72,6 @@ - (instancetype)initWithClient:(nullable SentryClient *)client
_scope = scope;
_crashWrapper = crashWrapper;
_dispatchQueue = dispatchQueue;
SentryStatsdClient *statsdClient = [[SentryStatsdClient alloc] initWithClient:client];
SentryMetricsClient *metricsClient =
[[SentryMetricsClient alloc] initWithClient:statsdClient];
_metrics = [[SentryMetricsAPI alloc]
initWithEnabled:client.options.enableMetrics
client:metricsClient
currentDate:SentryDependencyContainer.sharedInstance.dateProvider
dispatchQueue:_dispatchQueue
random:SentryDependencyContainer.sharedInstance.random
beforeEmitMetric:client.options.beforeEmitMetric];
[_metrics setDelegate:self];

_sessionLock = [[NSObject alloc] init];
_integrationsLock = [[NSObject alloc] init];
_installedIntegrations = [[NSMutableArray alloc] init];
Expand Down Expand Up @@ -762,7 +749,6 @@ - (NSString *)createSessionDebugString:(SentrySession *)session

- (void)flush:(NSTimeInterval)timeout
{
[_metrics flush];
SentryClient *client = _client;
if (client != nil) {
[client flush:timeout];
Expand All @@ -771,47 +757,10 @@ - (void)flush:(NSTimeInterval)timeout

- (void)close
{
[_metrics close];
[_client close];
SENTRY_LOG_DEBUG(@"Closed the Hub.");
}

#pragma mark - SentryMetricsAPIDelegate

- (NSDictionary<NSString *, NSString *> *)getDefaultTagsForMetrics
{
SentryOptions *options = [_client options];
if (options == nil || options.enableDefaultTagsForMetrics == NO) {
return @{};
}

NSMutableDictionary<NSString *, NSString *> *defaultTags = [NSMutableDictionary dictionary];

if (options.releaseName != nil) {
defaultTags[@"release"] = options.releaseName;
}

defaultTags[@"environment"] = options.environment;

return defaultTags;
}

- (id<SentrySpan> _Nullable)getCurrentSpan
{
return _scope.span;
}

- (LocalMetricsAggregator *_Nullable)getLocalMetricsAggregatorWithSpan:(id<SentrySpan>)span
{
// We don't want to add them LocalMetricsAggregator to the SentrySpan protocol and make it
// public. Instead, we check if the span responds to the getLocalMetricsAggregator which, every
// span should do.
if ([span isKindOfClass:SentrySpan.class]) {
return [(SentrySpan *)span getLocalMetricsAggregator];
}
return nil;
}

- (void)registerSessionListener:(id<SentrySessionListener>)listener
{
_sessionListener = listener;
Expand Down
15 changes: 0 additions & 15 deletions Sources/Sentry/SentryOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ - (instancetype)init
self.swiftAsyncStacktraces = NO;
self.enableSpotlight = NO;
self.spotlightUrl = @"http://localhost:8969/stream";
self.enableMetrics = NO;
self.enableDefaultTagsForMetrics = YES;
self.enableSpanLocalMetricAggregation = YES;

#if TARGET_OS_OSX
NSString *dsn = [[[NSProcessInfo processInfo] environment] objectForKey:@"SENTRY_DSN"];
Expand Down Expand Up @@ -550,18 +547,6 @@ - (BOOL)validateOptions:(NSDictionary<NSString *, id> *)options
self.spotlightUrl = options[@"spotlightUrl"];
}

[self setBool:options[@"enableMetrics"] block:^(BOOL value) { self->_enableMetrics = value; }];

[self setBool:options[@"enableDefaultTagsForMetrics"]
block:^(BOOL value) { self->_enableDefaultTagsForMetrics = value; }];

[self setBool:options[@"enableSpanLocalMetricAggregation"]
block:^(BOOL value) { self->_enableSpanLocalMetricAggregation = value; }];

if ([self isBlock:options[@"beforeEmitMetric"]]) {
self.beforeEmitMetric = options[@"beforeEmitMetric"];
}

if ([options[@"experimental"] isKindOfClass:NSDictionary.class]) {
[self.experimental validateOptions:options[@"experimental"]];
}
Expand Down
13 changes: 0 additions & 13 deletions Sources/Sentry/SentrySpan.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ @implementation SentrySpan {
NSObject *_stateLock;
BOOL _isFinished;
uint64_t _startSystemTime;
LocalMetricsAggregator *localMetricsAggregator;
#if SENTRY_HAS_UIKIT
NSUInteger initTotalFrames;
NSUInteger initSlowFrames;
Expand Down Expand Up @@ -310,14 +309,6 @@ - (nullable SentryTraceContext *)traceContext
return self.tracer.traceContext;
}

- (LocalMetricsAggregator *)getLocalMetricsAggregator
{
if (localMetricsAggregator == nil) {
localMetricsAggregator = [[LocalMetricsAggregator alloc] init];
}
return localMetricsAggregator;
}

- (NSDictionary *)serialize
{
NSMutableDictionary *mutableDictionary = @{
Expand Down Expand Up @@ -358,10 +349,6 @@ - (NSDictionary *)serialize
[mutableDictionary setValue:@(self.startTimestamp.timeIntervalSince1970)
forKey:@"start_timestamp"];

if (localMetricsAggregator != nil) {
mutableDictionary[@"_metrics_summary"] = [localMetricsAggregator serialize];
}

@synchronized(_data) {
NSMutableDictionary *data = _data.mutableCopy;

Expand Down
Loading

0 comments on commit 40e71d9

Please sign in to comment.