Skip to content
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

[PLAT-8819] Add leaveNetworkRequestBreadcrumbForTask:metrics: #1472

Merged
merged 5 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Bugsnag.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,19 @@
01935AE2275E68E9007498B3 /* UIApplicationStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 01935AE1275E68E9007498B3 /* UIApplicationStub.m */; };
01935AE3275E68E9007498B3 /* UIApplicationStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 01935AE1275E68E9007498B3 /* UIApplicationStub.m */; };
019480D42625F3EB00E833ED /* BSGAppKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 019480D32625F3EB00E833ED /* BSGAppKitTests.m */; };
01A2957C28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */ = {isa = PBXBuildFile; fileRef = 01A2957A28B665F5005FCC8C /* BSGNetworkBreadcrumb.h */; };
01A2957D28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */ = {isa = PBXBuildFile; fileRef = 01A2957A28B665F5005FCC8C /* BSGNetworkBreadcrumb.h */; };
01A2957E28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */ = {isa = PBXBuildFile; fileRef = 01A2957A28B665F5005FCC8C /* BSGNetworkBreadcrumb.h */; };
01A2957F28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */ = {isa = PBXBuildFile; fileRef = 01A2957A28B665F5005FCC8C /* BSGNetworkBreadcrumb.h */; };
01A2958028B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */; };
01A2958128B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */; };
01A2958228B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */; };
01A2958328B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */; };
01A2958428B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */; };
01A2958628B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2958528B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m */; };
01A2958728B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2958528B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m */; };
01A2958828B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2958528B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m */; };
01A2958928B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 01A2958528B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m */; };
01A2C542271EB9B400A27B23 /* BSG_Symbolicate.c in Sources */ = {isa = PBXBuildFile; fileRef = 01A2C540271EB9B300A27B23 /* BSG_Symbolicate.c */; };
01A2C543271EB9B400A27B23 /* BSG_Symbolicate.c in Sources */ = {isa = PBXBuildFile; fileRef = 01A2C540271EB9B300A27B23 /* BSG_Symbolicate.c */; };
01A2C544271EB9B400A27B23 /* BSG_Symbolicate.c in Sources */ = {isa = PBXBuildFile; fileRef = 01A2C540271EB9B300A27B23 /* BSG_Symbolicate.c */; };
Expand Down Expand Up @@ -1568,6 +1581,9 @@
019480D32625F3EB00E833ED /* BSGAppKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGAppKitTests.m; sourceTree = "<group>"; };
0195FC3B256BC81400DE6646 /* BugsnagEvent+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagEvent+Private.h"; sourceTree = "<group>"; };
0198762E2567D5AB000A7AF3 /* BugsnagStackframe+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagStackframe+Private.h"; sourceTree = "<group>"; };
01A2957A28B665F5005FCC8C /* BSGNetworkBreadcrumb.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BSGNetworkBreadcrumb.h; sourceTree = "<group>"; };
01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGNetworkBreadcrumb.m; sourceTree = "<group>"; };
01A2958528B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGNetworkBreadcrumbTests.m; sourceTree = "<group>"; };
01A2C540271EB9B300A27B23 /* BSG_Symbolicate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = BSG_Symbolicate.c; sourceTree = "<group>"; };
01A2C541271EB9B300A27B23 /* BSG_Symbolicate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_Symbolicate.h; sourceTree = "<group>"; };
01A6176B2733CFEA00024A0B /* TestHost-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TestHost-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -1999,6 +2015,7 @@
010993A3273D188B00128BBE /* BSGFeatureFlagStoreTests.m */,
01847DAB26441A5E00ADA4C7 /* BSGInternalErrorReporterTests.m */,
CBCF77AA250142E0004AF22A /* BSGJSONSerializationTests.m */,
01A2958528B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m */,
0163BF5825823D8D008DC28B /* BSGNotificationBreadcrumbsTests.m */,
008966C82486D43600DC48C2 /* BSGOutOfMemoryTests.m */,
0130DEF82880203A00E5953F /* BSGRunContextTests.m */,
Expand Down Expand Up @@ -2068,6 +2085,8 @@
00AD1CF124869EBD00A27979 /* Breadcrumbs */ = {
isa = PBXGroup;
children = (
01A2957A28B665F5005FCC8C /* BSGNetworkBreadcrumb.h */,
01A2957B28B665F5005FCC8C /* BSGNetworkBreadcrumb.m */,
01468F5025876DC1002B0519 /* BSGNotificationBreadcrumbs.h */,
01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */,
008967B32486D9D700DC48C2 /* BugsnagBreadcrumbs.h */,
Expand Down Expand Up @@ -2365,6 +2384,7 @@
00896A262486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.h in Headers */,
008968182486DA5600DC48C2 /* BugsnagCollections.h in Headers */,
00AD1F2B2486A17900A27979 /* BSGCrashSentry.h in Headers */,
01A2957C28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */,
00896A1D2486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.h in Headers */,
0089695A2486DAD000DC48C2 /* BSG_KSBacktrace.h in Headers */,
0089688B2486DA9600DC48C2 /* BugsnagStacktrace.h in Headers */,
Expand Down Expand Up @@ -2467,6 +2487,7 @@
00896A272486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.h in Headers */,
008968192486DA5600DC48C2 /* BugsnagCollections.h in Headers */,
00AD1F2C2486A17900A27979 /* BSGCrashSentry.h in Headers */,
01A2957D28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */,
00896A1E2486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.h in Headers */,
0089695B2486DAD000DC48C2 /* BSG_KSBacktrace.h in Headers */,
0089688C2486DA9600DC48C2 /* BugsnagStacktrace.h in Headers */,
Expand Down Expand Up @@ -2569,6 +2590,7 @@
00896A282486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.h in Headers */,
0089681A2486DA5600DC48C2 /* BugsnagCollections.h in Headers */,
00AD1F2D2486A17900A27979 /* BSGCrashSentry.h in Headers */,
01A2957E28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */,
00896A1F2486DAD100DC48C2 /* BSG_KSCrashSentry_NSException.h in Headers */,
0089695C2486DAD000DC48C2 /* BSG_KSBacktrace.h in Headers */,
0089688D2486DA9600DC48C2 /* BugsnagStacktrace.h in Headers */,
Expand Down Expand Up @@ -2620,6 +2642,7 @@
CBBDE98D2800698F0070DCD3 /* BSG_KSCrashReportFields.h in Headers */,
01FF490928BF8B7B001F817B /* BugsnagInternals.h in Headers */,
CBBDE95E280068FD0070DCD3 /* BugsnagMetadataStore.h in Headers */,
01A2957F28B665F5005FCC8C /* BSGNetworkBreadcrumb.h in Headers */,
CBBDE9AF280069B20070DCD3 /* BSG_KSArchSpecific.h in Headers */,
CBBDE91C2800687E0070DCD3 /* BugsnagBreadcrumbs.h in Headers */,
CBBDE9252800689F0070DCD3 /* BSGConnectivity.h in Headers */,
Expand Down Expand Up @@ -3069,6 +3092,7 @@
CBCF77A625010648004AF22A /* BSGJSONSerialization.m in Sources */,
008968912486DA9600DC48C2 /* BugsnagError.m in Sources */,
0089687C2486DA9500DC48C2 /* BugsnagBreadcrumb.m in Sources */,
01A2958028B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */,
008967FA2486DA4500DC48C2 /* BugsnagApiClient.m in Sources */,
01CCAEED25D414D60057268D /* BugsnagLastRunInfo.m in Sources */,
CBCAF6FD25A457F90095771F /* BSGFileLocations.m in Sources */,
Expand Down Expand Up @@ -3148,6 +3172,7 @@
008967722486D43700DC48C2 /* KSSysCtl_Tests.m in Sources */,
0089676C2486D43700DC48C2 /* BugsnagTestsDummyClass.m in Sources */,
008966EB2486D43700DC48C2 /* BugsnagDeviceTest.m in Sources */,
01A2958628B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */,
CBCF77AB250142E0004AF22A /* BSGJSONSerializationTests.m in Sources */,
008967A22486D43700DC48C2 /* KSCrashSentry_Signal_Tests.m in Sources */,
0130DEF92880203A00E5953F /* BSGRunContextTests.m in Sources */,
Expand Down Expand Up @@ -3242,6 +3267,7 @@
CBCF77A725010648004AF22A /* BSGJSONSerialization.m in Sources */,
0089687D2486DA9500DC48C2 /* BugsnagBreadcrumb.m in Sources */,
008967FB2486DA4500DC48C2 /* BugsnagApiClient.m in Sources */,
01A2958128B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */,
008967DF2486DA2D00DC48C2 /* BSGConfigurationBuilder.m in Sources */,
01CCAEEE25D414D60057268D /* BugsnagLastRunInfo.m in Sources */,
CBCAF6FE25A457F90095771F /* BSGFileLocations.m in Sources */,
Expand Down Expand Up @@ -3372,6 +3398,7 @@
010993A5273D188B00128BBE /* BSGFeatureFlagStoreTests.m in Sources */,
004E353B2487B3B3007FBAE4 /* BugsnagSwiftPublicAPITests.swift in Sources */,
0089677C2486D43700DC48C2 /* RFC3339DateTool_Tests.m in Sources */,
01A2958728B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */,
008967552486D43700DC48C2 /* BugsnagOnCrashTest.m in Sources */,
008967A02486D43700DC48C2 /* KSCrashSentry_Tests.m in Sources */,
008967432486D43700DC48C2 /* BugsnagSessionTrackerStopTest.m in Sources */,
Expand Down Expand Up @@ -3412,6 +3439,7 @@
008968932486DA9600DC48C2 /* BugsnagError.m in Sources */,
CBCF77A825010648004AF22A /* BSGJSONSerialization.m in Sources */,
0089687E2486DA9600DC48C2 /* BugsnagBreadcrumb.m in Sources */,
01A2958228B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */,
008967FC2486DA4500DC48C2 /* BugsnagApiClient.m in Sources */,
008967E02486DA2D00DC48C2 /* BSGConfigurationBuilder.m in Sources */,
01CCAEEF25D414D60057268D /* BugsnagLastRunInfo.m in Sources */,
Expand Down Expand Up @@ -3544,6 +3572,7 @@
CB26E9BC28350E0C005A1865 /* UISceneStub.m in Sources */,
008967982486D43700DC48C2 /* KSCrashState_Tests.m in Sources */,
008967772486D43700DC48C2 /* XCTestCase+KSCrash.m in Sources */,
01A2958828B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */,
008967322486D43700DC48C2 /* BSGClientObserverTests.m in Sources */,
CBA2249D251E429C00B87416 /* TestSupport.m in Sources */,
01847DAE26441A5E00ADA4C7 /* BSGInternalErrorReporterTests.m in Sources */,
Expand Down Expand Up @@ -3587,6 +3616,7 @@
E7462913248907E500F92D67 /* BSG_KSSignalInfo.c in Sources */,
E7462914248907E500F92D67 /* BSG_KSString.c in Sources */,
01CCAEF025D414D60057268D /* BugsnagLastRunInfo.m in Sources */,
01A2958428B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */,
E7462916248907E500F92D67 /* BSG_KSCrashType.c in Sources */,
E7462918248907E500F92D67 /* BSG_KSCrashSentry_Signal.c in Sources */,
E7462919248907E500F92D67 /* BSG_KSCrashSentry_MachException.c in Sources */,
Expand Down Expand Up @@ -3679,6 +3709,7 @@
CBBDE927280068AD0070DCD3 /* BSGEventUploadFileOperation.m in Sources */,
CBBDE968280069210070DCD3 /* BugsnagDeviceWithState.m in Sources */,
CBBDE946280068E60070DCD3 /* BugsnagCollections.m in Sources */,
01A2958328B665F5005FCC8C /* BSGNetworkBreadcrumb.m in Sources */,
CBBDE9B7280069B20070DCD3 /* BSG_KSMachHeaders.c in Sources */,
CBBDE9892800698F0070DCD3 /* BSG_KSCrashC.c in Sources */,
CBBDE9BB280069B20070DCD3 /* BSG_KSMach.c in Sources */,
Expand Down Expand Up @@ -3803,6 +3834,7 @@
CB28F0AF28294D4F003AB200 /* KSCrashState_Tests.m in Sources */,
CB28F0B528294DE1003AB200 /* BSGEventUploadKSCrashReportOperationTests.m in Sources */,
CB28F0A428294D4F003AB200 /* KSSysCtl_Tests.m in Sources */,
01A2958928B667C2005FCC8C /* BSGNetworkBreadcrumbTests.m in Sources */,
CB28F0C4282A488B003AB200 /* BugsnagApiClientTest.m in Sources */,
CB28F0D7282A4BA6003AB200 /* BugsnagEventTests.m in Sources */,
CB28F0AE28294D4F003AB200 /* KSSystemInfo_Tests.m in Sources */,
Expand Down
20 changes: 20 additions & 0 deletions Bugsnag/Breadcrumbs/BSGNetworkBreadcrumb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// BSGNetworkBreadcrumb.h
// Bugsnag
//
// Created by Nick Dowell on 24/08/2022.
// Copyright © 2022 Bugsnag Inc. All rights reserved.
//

#import <Bugsnag/Bugsnag.h>

NS_ASSUME_NONNULL_BEGIN

API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
BugsnagBreadcrumb * _Nullable BSGNetworkBreadcrumbWithTaskMetrics(NSURLSessionTask *task, NSURLSessionTaskMetrics *metrics);

NSDictionary<NSString *, id> * _Nullable BSGURLParamsForQueryItems(NSArray<NSURLQueryItem *> * _Nullable queryItems);

NSString * _Nullable BSGURLStringForComponents(NSURLComponents * _Nullable URLComponents);
kstenerud marked this conversation as resolved.
Show resolved Hide resolved

NS_ASSUME_NONNULL_END
96 changes: 96 additions & 0 deletions Bugsnag/Breadcrumbs/BSGNetworkBreadcrumb.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// BSGNetworkBreadcrumb.m
// Bugsnag
//
// Created by Nick Dowell on 24/08/2022.
// Copyright © 2022 Bugsnag Inc. All rights reserved.
//

#import "BSGNetworkBreadcrumb.h"

BugsnagBreadcrumb * BSGNetworkBreadcrumbWithTaskMetrics(NSURLSessionTask *task, NSURLSessionTaskMetrics *metrics) {
NSURLRequest *request = task.originalRequest ? task.originalRequest : task.currentRequest;
if (!request) {
return nil;
}

NSMutableDictionary *metadata = [NSMutableDictionary dictionary];
metadata[@"duration"] = @((unsigned)(metrics.taskInterval.duration * 1000));
metadata[@"method"] = request.HTTPMethod;

NSURL *url = request.URL;
if (url) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
metadata[@"url"] = BSGURLStringForComponents(components);
metadata[@"urlParams"] = BSGURLParamsForQueryItems(components.queryItems);
}

if (task.countOfBytesSent) {
metadata[@"requestContentLength"] = @(task.countOfBytesSent);
} else if (request.HTTPBody) {
// Fall back because task.countOfBytesSent is 0 when a custom NSURLProtocol is used
metadata[@"requestContentLength"] = @(request.HTTPBody.length);
}

NSString *message = @"NSURLSession request error";

// NSURLSessionTaskTransactionMetrics.response is nil when a custom NSURLProtocol is used.
// If there was an error, task.response will be nil.
NSURLResponse *response = task.response;
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
if (100 <= statusCode && statusCode < 400) {
message = @"NSURLSession request succeeded";
}
if (400 <= statusCode && statusCode < 500) {
message = @"NSURLSession request failed";
kstenerud marked this conversation as resolved.
Show resolved Hide resolved
}
metadata[@"responseContentLength"] = @(task.countOfBytesReceived);
metadata[@"status"] = @(statusCode);
}

BugsnagBreadcrumb *breadcrumb = [BugsnagBreadcrumb new];
breadcrumb.message = message;
breadcrumb.metadata = metadata;
breadcrumb.type = BSGBreadcrumbTypeRequest;
return breadcrumb;
}

NSDictionary<NSString *, id> * BSGURLParamsForQueryItems(NSArray<NSURLQueryItem *> *queryItems) {
if (!queryItems) {
return nil;
}
NSMutableDictionary *result = [NSMutableDictionary new];
for (NSURLQueryItem *item in queryItems) {
// - note: If a NSURLQueryItem name-value pair is empty (i.e. the query string starts with '&', ends
// with '&', or has "&&" within it), you get a NSURLQueryItem with a zero-length name and a nil value.
// If a NSURLQueryItem name-value pair has nothing before the equals sign, you get a zero-length name.
// If a NSURLQueryItem name-value pair has nothing after the equals sign, you get a zero-length value.
// If a NSURLQueryItem name-value pair has no equals sign, the NSURLQueryItem name-value pair string
// is the name and you get a nil value.
id value = item.value ?: [NSNull null];

id existingValue = result[item.name];
if ([existingValue isKindOfClass:[NSMutableArray class]]) {
[existingValue addObject:value];
} else if (existingValue) {
result[item.name] = [NSMutableArray arrayWithObjects:existingValue, value, nil];
} else {
result[item.name] = value;
}
}
return result;
}

NSString * BSGURLStringForComponents(NSURLComponents *components) {
if (components.rangeOfQuery.location == NSNotFound) {
return components.string;
}
NSRange rangeOfQuery = components.rangeOfQuery;
NSString *string = [components.string stringByReplacingCharactersInRange:rangeOfQuery withString:@""];
// rangeOfQuery does not include the '?' character, so that must be removed separately
if ([string characterAtIndex:rangeOfQuery.location - 1] == '?') {
string = [string stringByReplacingCharactersInRange:NSMakeRange(rangeOfQuery.location - 1, 1) withString:@""];
}
return string;
}
7 changes: 7 additions & 0 deletions Bugsnag/Bugsnag.m
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ + (void)leaveBreadcrumbWithMessage:(NSString *_Nonnull)message
}
}

+ (void)leaveNetworkRequestBreadcrumbForTask:(NSURLSessionTask *)task
metrics:(NSURLSessionTaskMetrics *)metrics {
if ([self bugsnagStarted]) {
[self.client leaveNetworkRequestBreadcrumbForTask:task metrics:metrics];
}
}

+ (NSArray<BugsnagBreadcrumb *> *_Nonnull)breadcrumbs {
if ([self bugsnagStarted]) {
return self.client.breadcrumbs;
Expand Down
14 changes: 14 additions & 0 deletions Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#import "BSGInternalErrorReporter.h"
#import "BSGJSONSerialization.h"
#import "BSGKeys.h"
#import "BSGNetworkBreadcrumb.h"
#import "BSGNotificationBreadcrumbs.h"
#import "BSGRunContext.h"
#import "BSGSerialization.h"
Expand Down Expand Up @@ -513,6 +514,19 @@ - (void)leaveBreadcrumbWithMessage:(NSString *_Nonnull)message
BSGRunContextUpdateTimestamp();
}

- (void)leaveNetworkRequestBreadcrumbForTask:(NSURLSessionTask *)task
metrics:(NSURLSessionTaskMetrics *)metrics {
if (!(self.configuration.enabledBreadcrumbTypes & BSGEnabledBreadcrumbTypeRequest)) {
return;
}
BugsnagBreadcrumb *breadcrumb = BSGNetworkBreadcrumbWithTaskMetrics(task, metrics);
if (!breadcrumb) {
return;
}
[self.breadcrumbStore addBreadcrumb:breadcrumb];
BSGRunContextUpdateTimestamp();
}

- (NSArray<BugsnagBreadcrumb *> *)breadcrumbs {
return self.breadcrumbStore.breadcrumbs ?: @[];
}
Expand Down
8 changes: 8 additions & 0 deletions Bugsnag/include/Bugsnag/Bugsnag.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ BUGSNAG_EXTERN
andType:(BSGBreadcrumbType)type
NS_SWIFT_NAME(leaveBreadcrumb(_:metadata:type:));

/**
* Leave a "breadcrumb" log message representing a completed network request.
*/
+ (void)leaveNetworkRequestBreadcrumbForTask:(nonnull NSURLSessionTask *)task
metrics:(nonnull NSURLSessionTaskMetrics *)metrics
API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))
NS_SWIFT_NAME(leaveNetworkRequestBreadcrumb(task:metrics:));

/**
* Returns the current buffer of breadcrumbs that will be sent with captured events. This
* ordered list represents the most recent breadcrumbs to be captured up to the limit
Expand Down
3 changes: 3 additions & 0 deletions Bugsnag/include/Bugsnag/BugsnagBreadcrumb.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ BUGSNAG_EXTERN

#pragma mark -

/// Internal protocol, not for public use.
/// Will be removed from public headers in next major release.
/// :nodoc:
@protocol BSGBreadcrumbSink <NSObject>

- (void)leaveBreadcrumbWithMessage:(nonnull NSString *)message metadata:(nullable NSDictionary *)metadata andType:(BSGBreadcrumbType)type
Expand Down
Loading