Skip to content

Commit

Permalink
feat: Send GraphQL "operationName" in HTTP breadcrumbs
Browse files Browse the repository at this point in the history
  • Loading branch information
Max Chuquimia committed Jan 15, 2024
1 parent 42ef6ba commit fa0b660
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
15E0A8F22411A45A00F044E3 /* SentrySession.m in Sources */ = {isa = PBXBuildFile; fileRef = 15E0A8F12411A45A00F044E3 /* SentrySession.m */; };
33042A0D29DAF79A00C60085 /* SentryExtraContextProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 33042A0C29DAF79A00C60085 /* SentryExtraContextProvider.m */; };
33042A1729DC2C4300C60085 /* SentryExtraContextProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33042A1629DC2C4300C60085 /* SentryExtraContextProviderTests.swift */; };
5147B3752B50B5FA00129F4B /* NSURLSessionTask+Sentry.h in Headers */ = {isa = PBXBuildFile; fileRef = 5147B3732B50B5FA00129F4B /* NSURLSessionTask+Sentry.h */; };
5147B3762B50B5FA00129F4B /* NSURLSessionTask+Sentry.m in Sources */ = {isa = PBXBuildFile; fileRef = 5147B3742B50B5FA00129F4B /* NSURLSessionTask+Sentry.m */; };
620379DB2AFE1415005AC0C1 /* SentryBuildAppStartSpans.h in Headers */ = {isa = PBXBuildFile; fileRef = 620379DA2AFE1415005AC0C1 /* SentryBuildAppStartSpans.h */; };
620379DD2AFE1432005AC0C1 /* SentryBuildAppStartSpans.m in Sources */ = {isa = PBXBuildFile; fileRef = 620379DC2AFE1432005AC0C1 /* SentryBuildAppStartSpans.m */; };
622C08D829E546F4002571D4 /* SentryTraceOrigins.h in Headers */ = {isa = PBXBuildFile; fileRef = 622C08D729E546F4002571D4 /* SentryTraceOrigins.h */; };
Expand Down Expand Up @@ -993,6 +995,8 @@
33042A0B29DAF5F400C60085 /* SentryExtraContextProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryExtraContextProvider.h; sourceTree = "<group>"; };
33042A0C29DAF79A00C60085 /* SentryExtraContextProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryExtraContextProvider.m; sourceTree = "<group>"; };
33042A1629DC2C4300C60085 /* SentryExtraContextProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryExtraContextProviderTests.swift; sourceTree = "<group>"; };
5147B3732B50B5FA00129F4B /* NSURLSessionTask+Sentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSURLSessionTask+Sentry.h"; path = "include/NSURLSessionTask+Sentry.h"; sourceTree = "<group>"; };
5147B3742B50B5FA00129F4B /* NSURLSessionTask+Sentry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSURLSessionTask+Sentry.m"; path = "include/NSURLSessionTask+Sentry.m"; sourceTree = "<group>"; };
620379DA2AFE1415005AC0C1 /* SentryBuildAppStartSpans.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryBuildAppStartSpans.h; path = include/SentryBuildAppStartSpans.h; sourceTree = "<group>"; };
620379DC2AFE1432005AC0C1 /* SentryBuildAppStartSpans.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryBuildAppStartSpans.m; sourceTree = "<group>"; };
622C08D729E546F4002571D4 /* SentryTraceOrigins.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryTraceOrigins.h; path = include/SentryTraceOrigins.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2045,6 +2049,8 @@
7B6438A926A70F24000D0F65 /* UIViewController+Sentry.m */,
0A2D8D9728997887008720F6 /* NSLocale+Sentry.h */,
0A2D8D9428997845008720F6 /* NSLocale+Sentry.m */,
5147B3732B50B5FA00129F4B /* NSURLSessionTask+Sentry.h */,
5147B3742B50B5FA00129F4B /* NSURLSessionTask+Sentry.m */,
);
name = Categories;
sourceTree = "<group>";
Expand Down Expand Up @@ -3752,6 +3758,7 @@
63FE716F20DA4C1100CDBAE8 /* SentryCrashCPU_Apple.h in Headers */,
639FCFA81EBC80CC00778193 /* SentryFrame.h in Headers */,
D8BFE37229A3782F002E73F3 /* SentryTimeToDisplayTracker.h in Headers */,
5147B3752B50B5FA00129F4B /* NSURLSessionTask+Sentry.h in Headers */,
8E8C57A625EEFC43001CEEFA /* SentryTracesSampler.h in Headers */,
7B634599280EB9D100CFA05A /* SentryUIEventTrackingIntegration.h in Headers */,
63FE716D20DA4C1100CDBAE8 /* SentryCrashSysCtl.h in Headers */,
Expand Down Expand Up @@ -4285,6 +4292,7 @@
7BA61CBB247BC5D800C130A8 /* SentryCrashDefaultBinaryImageProvider.m in Sources */,
63FE713120DA4C1100CDBAE8 /* SentryCrashDynamicLinker.c in Sources */,
8E25C95325F836D000DC215B /* SentryRandom.m in Sources */,
5147B3762B50B5FA00129F4B /* NSURLSessionTask+Sentry.m in Sources */,
7BC85231245812EC005A70F0 /* SentryFileContents.m in Sources */,
03F84D3527DD4191008FE43F /* SentryThreadHandle.cpp in Sources */,
0A2D8DA9289BC905008720F6 /* SentryViewHierarchy.m in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions Sources/Sentry/Public/SentryOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ NS_SWIFT_NAME(Options)
*/
@property (nonatomic, assign) BOOL enableAutoSessionTracking;

/**
* Whether to attach the top level `operationName` node of HTTP json requests to HTTP breadcrumbs
* @note Default is @c NO.
*/
@property (nonatomic, assign) BOOL enableGraphQLOperationTracking;

/**
* Whether to enable Watchdog Termination tracking or not.
* @note This feature requires the @c SentryCrashIntegration being enabled, otherwise it would
Expand Down
20 changes: 20 additions & 0 deletions Sources/Sentry/SentryNetworkTracker.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#import "SentryTraceOrigins.h"
#import "SentryTracer.h"
#import "SentryUser.h"
#import "NSURLSessionTask+Sentry.h"
#import <objc/runtime.h>
@import SentryPrivate;

Expand All @@ -42,6 +43,7 @@
@property (nonatomic, assign) BOOL isNetworkTrackingEnabled;
@property (nonatomic, assign) BOOL isNetworkBreadcrumbEnabled;
@property (nonatomic, assign) BOOL isCaptureFailedRequestsEnabled;
@property (nonatomic, assign) BOOL isGraphQLOperationTrackingEnabled;

@end

Expand All @@ -61,6 +63,7 @@ - (instancetype)init
_isNetworkTrackingEnabled = NO;
_isNetworkBreadcrumbEnabled = NO;
_isCaptureFailedRequestsEnabled = NO;
_isGraphQLOperationTrackingEnabled = NO;
}
return self;
}
Expand All @@ -86,12 +89,20 @@ - (void)enableCaptureFailedRequests
}
}

- (void)enableGraphQLOperationTracking
{
@synchronized(self) {
_isGraphQLOperationTrackingEnabled = YES;
}
}

- (void)disable
{
@synchronized(self) {
_isNetworkBreadcrumbEnabled = NO;
_isNetworkTrackingEnabled = NO;
_isCaptureFailedRequestsEnabled = NO;
_isGraphQLOperationTrackingEnabled = NO;
}
}

Expand Down Expand Up @@ -439,6 +450,11 @@ - (void)captureFailedRequests:(NSURLSessionTask *)sessionTask
}

context[@"response"] = response;

if (self.isGraphQLOperationTrackingEnabled) {
context[@"graphql"] = [sessionTask sentry_graphQLOperationName];
}

event.context = context;

[SentrySDK captureEvent:event];
Expand Down Expand Up @@ -488,6 +504,10 @@ - (void)addBreadcrumbForSessionTask:(NSURLSessionTask *)sessionTask
breadcrumbData[@"status_code"] = statusCode;
breadcrumbData[@"reason"] =
[NSHTTPURLResponse localizedStringForStatusCode:responseStatusCode];

if (self.isGraphQLOperationTrackingEnabled) {
breadcrumbData[@"graphql"] = [sessionTask sentry_graphQLOperationName];
}
}

if (urlComponents.query != nil) {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Sentry/SentryNetworkTrackingIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ - (BOOL)installWithOptions:(SentryOptions *)options
[SentryNetworkTracker.sharedInstance enableCaptureFailedRequests];
}

if (options.enableGraphQLOperationTracking) {
[SentryNetworkTracker.sharedInstance enableGraphQLOperationTracking];
}

if (shouldEnableNetworkTracking || options.enableNetworkBreadcrumbs
|| options.enableCaptureFailedRequests) {
[SentryNetworkTrackingIntegration swizzleURLSessionTask];
Expand Down
4 changes: 4 additions & 0 deletions Sources/Sentry/SentryOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ - (instancetype)init
_defaultSampleRate = @1;
self.sampleRate = _defaultSampleRate;
self.enableAutoSessionTracking = YES;
self.enableGraphQLOperationTracking = NO;
self.enableWatchdogTerminationTracking = YES;
self.sessionTrackingIntervalMillis = [@30000 unsignedIntValue];
self.attachStacktrace = YES;
Expand Down Expand Up @@ -352,6 +353,9 @@ - (BOOL)validateOptions:(NSDictionary<NSString *, id> *)options
[self setBool:options[@"enableAutoSessionTracking"]
block:^(BOOL value) { self->_enableAutoSessionTracking = value; }];

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

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

Expand Down
8 changes: 8 additions & 0 deletions Sources/Sentry/include/NSURLSessionTask+Sentry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>

@interface
NSURLSessionTask (Sentry)

- (nullable NSString *)sentry_graphQLOperationName;

@end
25 changes: 25 additions & 0 deletions Sources/Sentry/include/NSURLSessionTask+Sentry.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#import "NSURLSessionTask+Sentry.h"


@implementation
NSURLSessionTask (Sentry)

- (nullable NSString *)sentry_graphQLOperationName
{
if (!self.originalRequest.HTTPBody) { return nil; }
if (![[self.originalRequest valueForHTTPHeaderField:@"Content-Type"] isEqual: @"application/json"]) { return nil; }

NSError *error = nil;
id requestDictionary = [NSJSONSerialization JSONObjectWithData:self.originalRequest.HTTPBody options:0 error:&error];

if (error) { return nil; }
if (![requestDictionary isKindOfClass: [NSDictionary class]]) { return nil; } // Could be an array

id operationName = [requestDictionary valueForKey:@"operationName"];
if (![operationName isKindOfClass: [NSString class]]) { return nil; }
if ([operationName length] == 0) { return nil; }

return operationName;
}

@end
2 changes: 2 additions & 0 deletions Sources/Sentry/include/SentryNetworkTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ static NSString *const SENTRY_NETWORK_REQUEST_TRACKER_BREADCRUMB
- (void)enableNetworkTracking;
- (void)enableNetworkBreadcrumbs;
- (void)enableCaptureFailedRequests;
- (void)enableGraphQLOperationTracking;
- (BOOL)isTargetMatch:(NSURL *)URL withTargets:(NSArray *)targets;
- (void)disable;

@property (nonatomic, readonly) BOOL isNetworkTrackingEnabled;
@property (nonatomic, readonly) BOOL isNetworkBreadcrumbEnabled;
@property (nonatomic, readonly) BOOL isCaptureFailedRequestsEnabled;
@property (nonatomic, readonly) BOOL isGraphQLOperationTrackingEnabled;

@end

Expand Down

0 comments on commit fa0b660

Please sign in to comment.