Skip to content

Commit

Permalink
Added maxPersistedEvents config option so that users can control how …
Browse files Browse the repository at this point in the history
…many unsent events will be kept before deleting the oldest.
  • Loading branch information
kstenerud committed Dec 14, 2020
1 parent 0bfaf82 commit 1360415
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 14 deletions.
4 changes: 1 addition & 3 deletions Bugsnag/BugsnagCrashSentry.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#import "Bugsnag.h"
#import "BugsnagErrorTypes.h"

NSUInteger const BSG_MAX_STORED_REPORTS = 12;

@implementation BugsnagCrashSentry

- (void)install:(BugsnagConfiguration *)config
Expand All @@ -29,7 +27,7 @@ - (void)install:(BugsnagConfiguration *)config
ksCrash.sink = sink;
ksCrash.introspectMemory = YES;
ksCrash.onCrash = onCrash;
ksCrash.maxStoredReports = BSG_MAX_STORED_REPORTS;
ksCrash.maxStoredReports = (int)config.maxPersistedEvents;

// overridden elsewhere for handled errors, so we can assume that this only
// applies to unhandled errors
Expand Down
1 change: 0 additions & 1 deletion Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ - (void)initializeNotificationNameMap {

- (void)start {
[self.configuration validate];

[self.crashSentry install:self.configuration
apiClient:self.errorReportApiClient
onCrash:&BSSerializeDataCrashHandler];
Expand Down
17 changes: 9 additions & 8 deletions Bugsnag/Configuration/BSGConfigurationBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ + (BugsnagConfiguration *)configurationFromOptions:(NSDictionary *)options {
BSGKeyEnabledReleaseStages,
BSGKeyEndpoints,
BSGKeyMaxBreadcrumbs,
BSGKeyMaxPersistedEvents,
BSGKeyPersistUser,
BSGKeyRedactedKeys,
BSGKeyReleaseStage,
Expand All @@ -54,7 +55,8 @@ + (BugsnagConfiguration *)configurationFromOptions:(NSDictionary *)options {
[self loadStringArray:config options:options key:BSGKeyRedactedKeys];
[self loadEndpoints:config options:options];

[self loadMaxBreadcrumbs:config options:options];
[self loadNumber:config options:options key:BSGKeyMaxBreadcrumbs];
[self loadNumber:config options:options key:BSGKeyMaxPersistedEvents];
[self loadSendThreads:config options:options];
return config;
}
Expand All @@ -71,6 +73,12 @@ + (void)loadString:(BugsnagConfiguration *)config options:(NSDictionary *)option
}
}

+ (void)loadNumber:(BugsnagConfiguration *)config options:(NSDictionary *)options key:(NSString *)key {
if (options[key] && [options[key] isKindOfClass:[NSNumber class]]) {
[config setValue:options[key] forKey:key];
}
}

+ (void)loadStringArray:(BugsnagConfiguration *)config options:(NSDictionary *)options key:(NSString *)key {
if (options[key] && [options[key] isKindOfClass:[NSArray class]]) {
NSArray *val = options[key];
Expand All @@ -97,13 +105,6 @@ + (void)loadEndpoints:(BugsnagConfiguration *)config options:(NSDictionary *)opt
}
}

+ (void)loadMaxBreadcrumbs:(BugsnagConfiguration *)config options:(NSDictionary *)options {
if (options[BSGKeyMaxBreadcrumbs] && [options[BSGKeyMaxBreadcrumbs] isKindOfClass:[NSNumber class]]) {
NSNumber *num = options[BSGKeyMaxBreadcrumbs];
config.maxBreadcrumbs = [num unsignedIntValue];
}
}

+ (void)loadSendThreads:(BugsnagConfiguration *)config options:(NSDictionary *)options {
if (options[BSGKeySendThreads] && [options[BSGKeySendThreads] isKindOfClass:[NSString class]]) {
NSString *sendThreads = [options[BSGKeySendThreads] lowercaseString];
Expand Down
22 changes: 22 additions & 0 deletions Bugsnag/Configuration/BugsnagConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ - (nonnull id)copyWithZone:(nullable NSZone *)zone {
[copy setEnabledErrorTypes:self.enabledErrorTypes];
[copy setEnabledReleaseStages:self.enabledReleaseStages];
[copy setRedactedKeys:self.redactedKeys];
[copy setMaxPersistedEvents:self.maxPersistedEvents];
[copy setMaxBreadcrumbs:self.maxBreadcrumbs];
copy->_metadata = [[BugsnagMetadata alloc] initWithDictionary:[[self.metadata toDictionary] mutableCopy]];
[copy setEndpoints:self.endpoints];
Expand Down Expand Up @@ -159,6 +160,7 @@ - (instancetype)initWithApiKey:(NSString *)apiKey {
_enabledReleaseStages = nil;
_redactedKeys = [NSSet setWithArray:@[@"password"]];
_enabledBreadcrumbTypes = BSGEnabledBreadcrumbTypeAll;
_maxPersistedEvents = 12;
_maxBreadcrumbs = 25;
_autoTrackSessions = YES;
_sendThreads = BSGThreadSendPolicyAlways;
Expand Down Expand Up @@ -415,6 +417,26 @@ -(void)deletePersistedUserData {
// MARK: - Properties: Getters and Setters
// -----------------------------------------------------------------------------

@synthesize maxPersistedEvents = _maxPersistedEvents;

- (NSUInteger)maxPersistedEvents {
@synchronized (self) {
return _maxPersistedEvents;
}
}

- (void)setMaxPersistedEvents:(NSUInteger)maxPersistedEvents {
@synchronized (self) {
if (maxPersistedEvents >= 1 && maxPersistedEvents <= 100) {
_maxPersistedEvents = maxPersistedEvents;
} else {
bsg_log_err(@"Invalid configuration value detected. Option maxPersistedEvents "
"should be an integer between 1-100. Supplied value is %lu",
(unsigned long) maxPersistedEvents);
}
}
}

@synthesize maxBreadcrumbs = _maxBreadcrumbs;

- (NSUInteger)maxBreadcrumbs {
Expand Down
3 changes: 2 additions & 1 deletion Bugsnag/Helpers/BugsnagKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ extern NSString *const BSGKeyExceptionName;
extern NSString *const BSGKeyExceptions;
extern NSString *const BSGKeyExecutableName;
extern NSString *const BSGKeyExtraRuntimeInfo;
extern NSString *const BSGKeyFrameAddrFormat;
extern NSString *const BSGKeyFrameAddress;
extern NSString *const BSGKeyFrameAddrFormat;
extern NSString *const BSGKeyGroupingHash;
extern NSString *const BSGKeyHwMachine;
extern NSString *const BSGKeyHwModel;
Expand All @@ -63,6 +63,7 @@ extern NSString *const BSGKeyMachoLoadAddr;
extern NSString *const BSGKeyMachoUUID;
extern NSString *const BSGKeyMachoVMAddress;
extern NSString *const BSGKeyMaxBreadcrumbs;
extern NSString *const BSGKeyMaxPersistedEvents;
extern NSString *const BSGKeyMessage;
extern NSString *const BSGKeyMetadata;
extern NSString *const BSGKeyMethod;
Expand Down
3 changes: 2 additions & 1 deletion Bugsnag/Helpers/BugsnagKeys.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
NSString *const BSGKeyExceptions = @"exceptions";
NSString *const BSGKeyExecutableName = @"CFBundleExecutable";
NSString *const BSGKeyExtraRuntimeInfo = @"extraRuntimeInfo";
NSString *const BSGKeyFrameAddrFormat = @"0x%lx";
NSString *const BSGKeyFrameAddress = @"frameAddress";
NSString *const BSGKeyFrameAddrFormat = @"0x%lx";
NSString *const BSGKeyGroupingHash = @"groupingHash";
NSString *const BSGKeyHwMachine = @"hw.machine";
NSString *const BSGKeyHwModel = @"hw.model";
Expand All @@ -59,6 +59,7 @@
NSString *const BSGKeyMachoUUID = @"machoUUID";
NSString *const BSGKeyMachoVMAddress = @"machoVMAddress";
NSString *const BSGKeyMaxBreadcrumbs = @"maxBreadcrumbs";
NSString *const BSGKeyMaxPersistedEvents = @"maxPersistedEvents";
NSString *const BSGKeyMessage = @"message";
NSString *const BSGKeyMetadata = @"metaData";
NSString *const BSGKeyMethod = @"method";
Expand Down
8 changes: 8 additions & 0 deletions Bugsnag/include/Bugsnag/BugsnagConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ typedef BOOL (^BugsnagOnSessionBlock)(BugsnagSession *_Nonnull session);

@property(retain, nullable) NSString *appType;

/**
* Sets the maximum number of events which will be stored. Once the threshold is reached,
* the oldest events will be deleted.
*
* By default, 12 events are stored: this can be amended up to a maximum of 100.
*/
@property (nonatomic) NSUInteger maxPersistedEvents;

/**
* Sets the maximum number of breadcrumbs which will be stored. Once the threshold is reached,
* the oldest breadcrumbs will be deleted.
Expand Down
4 changes: 4 additions & 0 deletions Tests/BSGConfigurationBuilderTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ - (void)testDecodeDefaultValues {
XCTAssertNil(config.appVersion);
XCTAssertTrue(config.autoDetectErrors);
XCTAssertTrue(config.autoTrackSessions);
XCTAssertEqual(12, config.maxPersistedEvents);
XCTAssertEqual(25, config.maxBreadcrumbs);
XCTAssertTrue(config.persistUser);
XCTAssertEqualObjects(@[@"password"], [config.redactedKeys allObjects]);
Expand Down Expand Up @@ -92,6 +93,7 @@ - (void)testDecodeFullConfig {
@"sessions": @"https://sessions.example.co"
},
@"enabledReleaseStages": @[@"beta2", @"prod"],
@"maxPersistedEvents": @29,
@"maxBreadcrumbs": @27,
@"persistUser": @NO,
@"redactedKeys": @[@"foo"],
Expand All @@ -105,6 +107,7 @@ - (void)testDecodeFullConfig {
XCTAssertFalse(config.autoDetectErrors);
XCTAssertFalse(config.autoTrackSessions);
XCTAssertEqualObjects(@"7.22", config.bundleVersion);
XCTAssertEqual(29, config.maxPersistedEvents);
XCTAssertEqual(27, config.maxBreadcrumbs);
XCTAssertFalse(config.persistUser);
XCTAssertEqualObjects(@[@"foo"], config.redactedKeys);
Expand Down Expand Up @@ -138,6 +141,7 @@ - (void)testInvalidConfigOptions {
@"endpoints": [NSNull null],
@"enabledReleaseStages": @[@"beta2", @"prod"],
@"enabledErrorTypes": @[@"ooms", @"signals"],
@"maxPersistedEvents": @29,
@"maxBreadcrumbs": @27,
@"persistUser": @"pomelo",
@"redactedKeys": @[@77],
Expand Down
4 changes: 4 additions & 0 deletions Tests/BugsnagClientTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ - (void)assertEqualConfiguration:(BugsnagConfiguration *)expected withActual:(Bu
XCTAssertEqual(expected.enabledReleaseStages, actual.enabledReleaseStages);
XCTAssertEqualObjects(expected.endpoints.notify, actual.endpoints.notify);
XCTAssertEqualObjects(expected.endpoints.sessions, actual.endpoints.sessions);
XCTAssertEqual(expected.maxPersistedEvents, actual.maxPersistedEvents);
XCTAssertEqual(expected.maxBreadcrumbs, actual.maxBreadcrumbs);
XCTAssertEqual(expected.persistUser, actual.persistUser);
XCTAssertEqual([expected.redactedKeys count], [actual.redactedKeys count]);
Expand All @@ -209,11 +210,13 @@ - (void)testChangesToConfigurationAreIgnoredAfterCallingStart {

// Modify some arbitrary properties
config.persistUser = !config.persistUser;
config.maxPersistedEvents = config.maxPersistedEvents * 2;
config.maxBreadcrumbs = config.maxBreadcrumbs * 2;
config.appVersion = @"99.99.99";

// Ensure the changes haven't been reflected in our copy
XCTAssertNotEqual(initialConfig.persistUser, config.persistUser);
XCTAssertNotEqual(initialConfig.maxPersistedEvents, config.maxPersistedEvents);
XCTAssertNotEqual(initialConfig.maxBreadcrumbs, config.maxBreadcrumbs);
XCTAssertNotEqualObjects(initialConfig.appVersion, config.appVersion);

Expand All @@ -231,6 +234,7 @@ - (void)testStartingBugsnagTwiceLogsAWarningAndIgnoresNewConfiguration {
BugsnagConfiguration *updatedConfig = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_2];
updatedConfig.persistUser = !initialConfig.persistUser;
updatedConfig.maxBreadcrumbs = initialConfig.maxBreadcrumbs * 2;
updatedConfig.maxPersistedEvents = initialConfig.maxPersistedEvents * 2;
updatedConfig.appVersion = @"99.99.99";

[Bugsnag startWithConfiguration:updatedConfig];
Expand Down
32 changes: 32 additions & 0 deletions Tests/BugsnagConfigurationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,38 @@ - (void)testSettingPersistUser {
XCTAssertTrue(config.persistUser);
}

// =============================================================================
// MARK: - Max Persisted Events
// =============================================================================

- (void)testMaxPersistedEvents {
BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithApiKey:DUMMY_APIKEY_32CHAR_1];
XCTAssertEqual(12, config.maxPersistedEvents);

// alter to valid value
config.maxPersistedEvents = 10;
XCTAssertEqual(10, config.maxPersistedEvents);

// alter to max value
config.maxPersistedEvents = 100;
XCTAssertEqual(100, config.maxPersistedEvents);

// alter to min value
config.maxPersistedEvents = 1;
XCTAssertEqual(1, config.maxPersistedEvents);

config.maxPersistedEvents = 0;
XCTAssertEqual(1, config.maxPersistedEvents);

// alter to negative value
config.maxPersistedEvents = -1;
XCTAssertEqual(1, config.maxPersistedEvents);

// alter to > max value
config.maxPersistedEvents = 500;
XCTAssertEqual(1, config.maxPersistedEvents);
}

// =============================================================================
// MARK: - Max Breadcrumb
// =============================================================================
Expand Down
19 changes: 19 additions & 0 deletions Tests/ConfigurationApiValidationTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,25 @@ - (void)testValidAppType {
XCTAssertEqualObjects(@"cocoa", self.config.appType);
}

- (void)testValidMaxPersistedEvents {
self.config.maxPersistedEvents = 1;
XCTAssertEqual(1, self.config.maxPersistedEvents);
self.config.maxPersistedEvents = 100;
XCTAssertEqual(100, self.config.maxPersistedEvents);
self.config.maxPersistedEvents = 40;
XCTAssertEqual(40, self.config.maxPersistedEvents);
}

- (void)testInvalidMaxPersistedEvents {
self.config.maxPersistedEvents = 1;
self.config.maxPersistedEvents = 0;
XCTAssertEqual(1, self.config.maxPersistedEvents);
self.config.maxPersistedEvents = -1;
XCTAssertEqual(1, self.config.maxPersistedEvents);
self.config.maxPersistedEvents = 590;
XCTAssertEqual(1, self.config.maxPersistedEvents);
}

- (void)testValidMaxBreadcrumbs {
self.config.maxBreadcrumbs = 0;
XCTAssertEqual(0, self.config.maxBreadcrumbs);
Expand Down

0 comments on commit 1360415

Please sign in to comment.