From 794ff08887edfc39fc450a162267be0a29028596 Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Fri, 8 Apr 2022 22:00:44 -0700 Subject: [PATCH 01/11] feat: ref #144, #145 --- .../RollbarMemoryStatsDescriptors.m | 81 ++++++++++++ .../Sources/RollbarCommon/RollbarMemoryUtil.m | 119 ++++++++++++++++++ .../include/RollbarMemoryStatsDescriptors.h | 65 ++++++++++ .../RollbarCommon/include/RollbarMemoryUtil.h | 37 ++++++ 4 files changed, 302 insertions(+) create mode 100644 RollbarCommon/Sources/RollbarCommon/RollbarMemoryStatsDescriptors.m create mode 100644 RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m create mode 100644 RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryStatsDescriptors.h create mode 100644 RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h diff --git a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryStatsDescriptors.m b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryStatsDescriptors.m new file mode 100644 index 00000000..46bd6b3f --- /dev/null +++ b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryStatsDescriptors.m @@ -0,0 +1,81 @@ +#import "RollbarMemoryStatsDescriptors.h" + +#pragma mark - Rollbar memorty stats related descriptors + +static NSString *const Rollbar_memory_physical = @"physical"; +static NSString *const Rollbar_memory_physical_totalMB = @"total_MB"; + +static NSString *const Rollbar_memory_vm = @"vm"; +static NSString *const Rollbar_memory_vm_free = @"free_MB"; +static NSString *const Rollbar_memory_vm_active = @"active_MB"; +static NSString *const Rollbar_memory_vm_inactive = @"inactive_MB"; +static NSString *const Rollbar_memory_vm_speculative = @"speculative_MB"; +static NSString *const Rollbar_memory_vm_wired = @"wired_MB"; + +#pragma mark - RollbarMemoryStatsDescriptors class + +static RollbarMemoryStatsDescriptors *singleton = nil; + +@implementation RollbarMemoryStatsDescriptors +{ +@private + NSArray *memoryTypeIndex; + NSArray *physicalMemoryStatsIndex; + NSArray *virtualMemoryStatsIndex; +} + +#pragma mark - Sigleton pattern + ++ (nonnull instancetype)sharedInstance { + + //static RollbarMemoryStatsDescriptors *singleton = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + + singleton = [[[self class] alloc] init]; + singleton->memoryTypeIndex = @[ + // match order of RollbarMemoryStatsType values: + Rollbar_memory_physical, + Rollbar_memory_vm, + ]; + singleton->physicalMemoryStatsIndex = @[ + // match order of RollbarPhysicalMemory values: + Rollbar_memory_physical_totalMB, + ]; + singleton->virtualMemoryStatsIndex = @[ + // match order of RollbarVirtualMemory values: + Rollbar_memory_vm_free, + Rollbar_memory_vm_active, + Rollbar_memory_vm_inactive, + Rollbar_memory_vm_speculative, + Rollbar_memory_vm_wired, + ]; + }); + + return singleton; +} + ++ (BOOL)sharedInstanceExists { + + return (nil != singleton); +} + +#pragma mark - Instance methods + +- (nonnull NSString *)getMemoryStatsTypeDescriptor: (RollbarMemoryStatsType)memoryAttribute { + + return self->memoryTypeIndex[memoryAttribute]; +} + +- (nonnull NSString *)getPhysicalMemoryDescriptor: (RollbarPhysicalMemory)memoryAttribute { + + return self->physicalMemoryStatsIndex[memoryAttribute]; +} + +- (nonnull NSString *)getVirtualMemoryDescriptor: (RollbarVirtualMemory)memoryAttribute { + + return self->virtualMemoryStatsIndex[memoryAttribute]; +} + +@end diff --git a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m new file mode 100644 index 00000000..71538e49 --- /dev/null +++ b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m @@ -0,0 +1,119 @@ +// +// RollbarMemoryUtil.m +// +// +// Created by Andrey Kornich on 2022-04-07. +// + +#import "RollbarMemoryUtil.h" +#import "RollbarMemoryStatsDescriptors.h" + +static NSByteCountFormatter *formatter = nil; +static const NSInteger bytesInMB = 1024 * 1024; + +@implementation RollbarMemoryUtil + ++ (void)initialize { + + formatter = [[NSByteCountFormatter alloc] init]; + formatter.countStyle = NSByteCountFormatterCountStyleMemory; + formatter.includesActualByteCount = YES; + formatter.adaptive = YES; + formatter.includesUnit = YES; + formatter.zeroPadsFractionDigits = YES; +} + +#pragma mark - memory stats getters + ++ (nullable NSDictionary *)getPhysicalMemoryStats { + + return @{ + [[RollbarMemoryStatsDescriptors sharedInstance] getPhysicalMemoryDescriptor:RollbarPhysicalMemory_TotalMB] : + [NSNumber numberWithUnsignedInteger: [RollbarMemoryUtil getPhysicalMemoryInMBs]], + }; +} + ++ (nullable NSDictionary *)getVirtualMemoryStats { + + vm_statistics_data_t vmStats; + mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT; + kern_return_t kernReturn = host_statistics( + mach_host_self(), + HOST_VM_INFO, + (host_info_t)&vmStats, &infoCount + ); + if(kernReturn != KERN_SUCCESS) { + + return nil; + } + + NSUInteger memoryMBs; + + memoryMBs = [RollbarMemoryUtil convertToMBs:(vm_page_size * vmStats.free_count)]; + NSNumber *freeMemory = [NSNumber numberWithUnsignedInteger:[RollbarMemoryUtil convertToMBs:memoryMBs]]; + + memoryMBs = [RollbarMemoryUtil convertToMBs:(vm_page_size * vmStats.active_count)]; + NSNumber *activeMemory = [NSNumber numberWithUnsignedInteger:[RollbarMemoryUtil convertToMBs:memoryMBs]]; + + memoryMBs = [RollbarMemoryUtil convertToMBs:(vm_page_size * vmStats.inactive_count)]; + NSNumber *inactiveMemory = [NSNumber numberWithUnsignedInteger:[RollbarMemoryUtil convertToMBs:memoryMBs]]; + + memoryMBs = [RollbarMemoryUtil convertToMBs:(vm_page_size * vmStats.speculative_count)]; + NSNumber *speculativeMemory = [NSNumber numberWithUnsignedInteger:[RollbarMemoryUtil convertToMBs:memoryMBs]]; + + memoryMBs = [RollbarMemoryUtil convertToMBs:(vm_page_size * vmStats.wire_count)]; + NSNumber *wiredMemory = [NSNumber numberWithUnsignedInteger:[RollbarMemoryUtil convertToMBs:memoryMBs]]; + + return @{ + + [[RollbarMemoryStatsDescriptors sharedInstance] getVirtualMemoryDescriptor:RollbarVirtualMemory_FreeMB] : + freeMemory ? freeMemory : [NSNull null], + [[RollbarMemoryStatsDescriptors sharedInstance] getVirtualMemoryDescriptor:RollbarVirtualMemory_ActiveMB] : + activeMemory ? activeMemory : [NSNull null], + [[RollbarMemoryStatsDescriptors sharedInstance] getVirtualMemoryDescriptor:RollbarVirtualMemory_InactiveMB] : + inactiveMemory ? inactiveMemory : [NSNull null], + [[RollbarMemoryStatsDescriptors sharedInstance] getVirtualMemoryDescriptor:RollbarVirtualMemory_SpeculativeMB] : + speculativeMemory ? speculativeMemory : [NSNull null], + [[RollbarMemoryStatsDescriptors sharedInstance] getVirtualMemoryDescriptor:RollbarVirtualMemory_WiredMB] : + wiredMemory ? wiredMemory : [NSNull null], + }; +} + ++ (NSUInteger)getPhysicalMemoryInBytes { + + unsigned long long bytesTotal = [[NSProcessInfo processInfo] physicalMemory]; + return (NSUInteger)bytesTotal; +} + +#pragma mark - converters + ++ (NSUInteger)convertToMBs:(NSUInteger)bytesCount { + + NSUInteger result = (bytesCount / bytesInMB); + result += (bytesCount % bytesInMB); + return result; +} + ++ (NSString *)convertToHumanFriendlyFormat:(NSUInteger)bytesCount { + + NSString *result = [formatter stringFromByteCount:bytesCount]; + return result; +} + +#pragma mark - convenience methods + ++ (NSUInteger)getPhysicalMemoryInMBs { + + NSInteger result = [RollbarMemoryUtil convertToMBs:[RollbarMemoryUtil getPhysicalMemoryInBytes]]; + return result; +} + +#pragma mark - convenience string presenters + ++ (NSString *)getPhysicalMemorySizeWithUnits { + + NSString *result = [RollbarMemoryUtil convertToHumanFriendlyFormat:[RollbarMemoryUtil getPhysicalMemoryInBytes]]; + return result; +} + +@end diff --git a/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryStatsDescriptors.h b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryStatsDescriptors.h new file mode 100644 index 00000000..429b1918 --- /dev/null +++ b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryStatsDescriptors.h @@ -0,0 +1,65 @@ +// +// RollbarMemoryStatsDescriptors.h +// +// +// Created by Andrey Kornich on 2022-04-07. +// + +@import Foundation; + +#pragma mark - RollbarMemoryStatsType enum + +typedef NS_ENUM(NSUInteger, RollbarMemoryStatsType) { + RollbarMemoryStatsType_Physical = 0, + RollbarMemoryStatsType_VM, +}; + +#pragma mark - RollbarPhysicalMemory enum + +typedef NS_ENUM(NSUInteger, RollbarPhysicalMemory) { + RollbarPhysicalMemory_TotalMB = 0, +}; + +#pragma mark - RollbarVirtualMemory enum + +typedef NS_ENUM(NSUInteger, RollbarVirtualMemory) { + RollbarVirtualMemory_FreeMB = 0, + RollbarVirtualMemory_ActiveMB, + RollbarVirtualMemory_InactiveMB, + RollbarVirtualMemory_SpeculativeMB, + RollbarVirtualMemory_WiredMB +}; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - RollbarMemoryStatsDescriptors class + +@interface RollbarMemoryStatsDescriptors : NSObject +{ +} + +#pragma mark - Sigleton pattern + ++ (nonnull instancetype)sharedInstance; ++ (BOOL)sharedInstanceExists; + ++ (instancetype)new NS_UNAVAILABLE; ++ (instancetype)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (instancetype)alloc NS_UNAVAILABLE; ++ (id)copyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (id)mutableCopyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; +- (void)dealloc NS_UNAVAILABLE; +- (id)copy NS_UNAVAILABLE; +- (id)mutableCopy NS_UNAVAILABLE; + +#pragma mark - Instance methods + +- (nonnull NSString *)getMemoryStatsTypeDescriptor: (RollbarMemoryStatsType)memoryAttribute; +- (nonnull NSString *)getPhysicalMemoryDescriptor: (RollbarPhysicalMemory)memoryAttribute; +- (nonnull NSString *)getVirtualMemoryDescriptor: (RollbarVirtualMemory)memoryAttribute; + +@end + +NS_ASSUME_NONNULL_END diff --git a/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h new file mode 100644 index 00000000..87682fcb --- /dev/null +++ b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h @@ -0,0 +1,37 @@ +// +// RollbarMemoryUtil.h +// +// +// Created by Andrey Kornich on 2022-04-07. +// + +@import Foundation; + +NS_ASSUME_NONNULL_BEGIN + +@interface RollbarMemoryUtil : NSObject + + +#pragma mark - memory stats getters + ++ (nullable NSDictionary *)getPhysicalMemoryStats; ++ (nullable NSDictionary *)getVirtualMemoryStats; ++ (NSUInteger)getPhysicalMemoryInBytes; + +#pragma mark - converters + ++ (NSUInteger)convertToMBs:(NSUInteger)bytesCount; ++ (NSString *)convertToHumanFriendlyFormat:(NSUInteger)bytesCount; + +#pragma mark - convenience methods + ++ (NSUInteger)getPhysicalMemoryInMBs; + +#pragma mark - convenience string presenters + ++ (NSString *)getPhysicalMemorySizeWithUnits; + + +@end + +NS_ASSUME_NONNULL_END From 26a995580abbdf46fc54a685a6fc21b51dd16a7f Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Fri, 8 Apr 2022 22:17:54 -0700 Subject: [PATCH 02/11] feat: ref #144, #145 --- RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m index 71538e49..6a4160c3 100644 --- a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m +++ b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m @@ -1,12 +1,7 @@ -// -// RollbarMemoryUtil.m -// -// -// Created by Andrey Kornich on 2022-04-07. -// - #import "RollbarMemoryUtil.h" #import "RollbarMemoryStatsDescriptors.h" +#import +//#import static NSByteCountFormatter *formatter = nil; static const NSInteger bytesInMB = 1024 * 1024; From 03d0bb7de770000fab7a498e3b1a6541a40ad121 Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Fri, 8 Apr 2022 22:20:52 -0700 Subject: [PATCH 03/11] feat: ref #144, #145 --- RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m | 1 - 1 file changed, 1 deletion(-) diff --git a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m index 6a4160c3..a4918d25 100644 --- a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m +++ b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m @@ -1,7 +1,6 @@ #import "RollbarMemoryUtil.h" #import "RollbarMemoryStatsDescriptors.h" #import -//#import static NSByteCountFormatter *formatter = nil; static const NSInteger bytesInMB = 1024 * 1024; From 97f1faf6fdc217e05e9b6b064cb9cac43bb8b4c4 Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 11 Apr 2022 16:14:32 -0700 Subject: [PATCH 04/11] feat: ref #144, #145 --- .../Sources/RollbarCommon/RollbarMemoryUtil.m | 14 ++++++ .../RollbarCommon/include/RollbarMemoryUtil.h | 8 ++++ .../RollbarMemoryStatsDescriptorsTests.swift | 48 +++++++++++++++++++ .../RollbarMemoryUtilTests.swift | 29 +++++++++++ 4 files changed, 99 insertions(+) create mode 100644 RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryStatsDescriptorsTests.swift create mode 100644 RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift diff --git a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m index a4918d25..6388ef39 100644 --- a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m +++ b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m @@ -19,6 +19,20 @@ + (void)initialize { #pragma mark - memory stats getters ++ (nonnull NSDictionary *)getMemoryStats { + + NSObject *physicalMemoryStats = [RollbarMemoryUtil getPhysicalMemoryStats]; + NSObject *virtualMemoryStats = [RollbarMemoryUtil getVirtualMemoryStats]; + + return @{ + + [[RollbarMemoryStatsDescriptors sharedInstance] getMemoryStatsTypeDescriptor:RollbarMemoryStatsType_Physical] : + physicalMemoryStats ? physicalMemoryStats : [NSNull null], + [[RollbarMemoryStatsDescriptors sharedInstance] getMemoryStatsTypeDescriptor:RollbarMemoryStatsType_VM] : + virtualMemoryStats ? virtualMemoryStats : [NSNull null], + }; +} + + (nullable NSDictionary *)getPhysicalMemoryStats { return @{ diff --git a/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h index 87682fcb..6eb0fa63 100644 --- a/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h +++ b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - memory stats getters ++ (nonnull NSDictionary *)getMemoryStats; + (nullable NSDictionary *)getPhysicalMemoryStats; + (nullable NSDictionary *)getVirtualMemoryStats; + (NSUInteger)getPhysicalMemoryInBytes; @@ -31,6 +32,13 @@ NS_ASSUME_NONNULL_BEGIN + (NSString *)getPhysicalMemorySizeWithUnits; +#pragma mark - static utility nature + ++ (instancetype)new NS_UNAVAILABLE; ++ (instancetype)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (instancetype)alloc NS_UNAVAILABLE; ++ (id)copyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (id)mutableCopyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; @end diff --git a/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryStatsDescriptorsTests.swift b/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryStatsDescriptorsTests.swift new file mode 100644 index 00000000..2631cba2 --- /dev/null +++ b/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryStatsDescriptorsTests.swift @@ -0,0 +1,48 @@ +import XCTest +import Foundation +@testable import RollbarCommon + +final class RollbarMemoryStatsDescriptorsTests: XCTestCase { + + func testRollbarMemoryStatsDescriptors_basics() { + + XCTAssertEqual( + "physical", + RollbarMemoryStatsDescriptors.sharedInstance().getMemoryStatsTypeDescriptor(RollbarMemoryStatsType.physical) + ); + XCTAssertEqual( + "vm", + RollbarMemoryStatsDescriptors.sharedInstance().getMemoryStatsTypeDescriptor(RollbarMemoryStatsType.VM) + ); + + XCTAssertEqual( + "total_MB", + RollbarMemoryStatsDescriptors.sharedInstance().getPhysicalMemoryDescriptor(RollbarPhysicalMemory.totalMB) + ); + + XCTAssertEqual( + "free_MB", + RollbarMemoryStatsDescriptors.sharedInstance().getVirtualMemoryDescriptor(RollbarVirtualMemory.freeMB) + ); + XCTAssertEqual( + "active_MB", + RollbarMemoryStatsDescriptors.sharedInstance().getVirtualMemoryDescriptor(RollbarVirtualMemory.activeMB) + ); + XCTAssertEqual( + "inactive_MB", + RollbarMemoryStatsDescriptors.sharedInstance().getVirtualMemoryDescriptor(RollbarVirtualMemory.inactiveMB) + ); + XCTAssertEqual( + "speculative_MB", + RollbarMemoryStatsDescriptors.sharedInstance().getVirtualMemoryDescriptor(RollbarVirtualMemory.speculativeMB) + ); + XCTAssertEqual( + "wired_MB", + RollbarMemoryStatsDescriptors.sharedInstance().getVirtualMemoryDescriptor(RollbarVirtualMemory.wiredMB) + ); + } + + static var allTests = [ + ("testRollbarMemoryStatsDescriptors_basics", testRollbarMemoryStatsDescriptors_basics), + ] +} diff --git a/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift b/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift new file mode 100644 index 00000000..b8f9d73b --- /dev/null +++ b/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift @@ -0,0 +1,29 @@ +import XCTest +import Foundation +@testable import RollbarCommon + +final class RollbarMemoryUtilTests: XCTestCase { + + func testRollbarMemoryUtil_basics() { + + let memoryStats = RollbarMemoryUtil.getMemoryStats(); + + print(memoryStats); + + XCTAssertTrue(memoryStats["physical"] is NSDictionary); + let physicalMemoryStats = memoryStats["physical"] as! NSDictionary; + XCTAssertTrue((physicalMemoryStats["total_MB"] as! NSNumber).uintValue > 0); + + XCTAssertTrue(memoryStats["vm"] is NSDictionary); + let virtualMemoryStats = memoryStats["vm"] as! NSDictionary; + XCTAssertTrue((virtualMemoryStats["free_MB"] as! NSNumber).uintValue > 0); + XCTAssertTrue((virtualMemoryStats["active_MB"] as! NSNumber).uintValue > 0); + XCTAssertTrue((virtualMemoryStats["inactive_MB"] as! NSNumber).uintValue > 0); + XCTAssertTrue((virtualMemoryStats["speculative_MB"] as! NSNumber).uintValue > 0); + XCTAssertTrue((virtualMemoryStats["wired_MB"] as! NSNumber).uintValue > 0); + } + + static var allTests = [ + ("testRollbarMemoryUtil_basics", testRollbarMemoryUtil_basics), + ] +} From 52827dfdab7fe11c4b939ec218db44bb31867ecd Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 11 Apr 2022 16:41:34 -0700 Subject: [PATCH 05/11] feat: ref #144, #145 added performance test --- .../RollbarCommonTests/RollbarMemoryUtilTests.swift | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift b/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift index b8f9d73b..b7c53f6e 100644 --- a/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift +++ b/RollbarCommon/Tests/RollbarCommonTests/RollbarMemoryUtilTests.swift @@ -4,7 +4,7 @@ import Foundation final class RollbarMemoryUtilTests: XCTestCase { - func testRollbarMemoryUtil_basics() { + func testRollbarMemoryUtil_Basics() throws { let memoryStats = RollbarMemoryUtil.getMemoryStats(); @@ -23,7 +23,14 @@ final class RollbarMemoryUtilTests: XCTestCase { XCTAssertTrue((virtualMemoryStats["wired_MB"] as! NSNumber).uintValue > 0); } + func testRollbarMemoryUtil_Performance() throws { + + measure { + _ = RollbarMemoryUtil.getMemoryStats(); + } + } static var allTests = [ - ("testRollbarMemoryUtil_basics", testRollbarMemoryUtil_basics), + ("testRollbarMemoryUtil_basics", testRollbarMemoryUtil_Basics), + ("testPerformance", testRollbarMemoryUtil_Performance) ] } From fd256e7d87bc9aa0147306b8af34325d2ba5be0a Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 11 Apr 2022 18:52:30 -0700 Subject: [PATCH 06/11] chore: ref #146 - Telemetry code cleanup --- .../RollbarNotifier/RollbarTelemetry.m | 80 ------------------- 1 file changed, 80 deletions(-) diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m index ca54d9bf..f8df88cc 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m @@ -207,31 +207,6 @@ - (void)recordViewEventForLevel:(RollbarLevel)level RollbarTelemetryBody *body = [[RollbarTelemetryViewBody alloc] initWithElement:element extraData:extraData]; [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// // check if the extradata needs some scrubbing based on the element name: -// __block BOOL needsScrubbing = false; -// [_viewInputsToScrub enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { -// if( [element caseInsensitiveCompare:obj] == NSOrderedSame ) { -// needsScrubbing = true; -// *stop = YES; -// } -// }]; -// // scrub the extradata as needed: -// if (needsScrubbing) { -// for (NSString * key in data) -// { -// [data setValue:@"[scrubbed]" forKey:key]; -// } -// } -// // add the element name: -// [data setObject:element forKey:@"element"]; -// -// [self recordEventForLevel:level type:RollbarTelemetryView data:data]; } - (void)recordNetworkEventForLevel:(RollbarLevel)level @@ -250,17 +225,6 @@ - (void)recordNetworkEventForLevel:(RollbarLevel)level } [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// [data setObject:method forKey:@"method"]; -// [data setObject:url forKey:@"url"]; -// [data setObject:statusCode forKey:@"status_code"]; -// -// [self recordEventForLevel:level type:RollbarTelemetryNetwork data:data]; } - (void)recordConnectivityEventForLevel:(RollbarLevel)level @@ -274,15 +238,6 @@ - (void)recordConnectivityEventForLevel:(RollbarLevel)level RollbarTelemetryConnectivityBody *body = [[RollbarTelemetryConnectivityBody alloc] initWithStatus:status extraData:extraData]; [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// [data setObject:status forKey:@"change"]; -// -// [self recordEventForLevel:level type:RollbarTelemetryConnectivity data:data]; } - (void)recordErrorEventForLevel:(RollbarLevel)level @@ -296,15 +251,6 @@ - (void)recordErrorEventForLevel:(RollbarLevel)level RollbarTelemetryErrorBody *body = [[RollbarTelemetryErrorBody alloc] initWithMessage:message extraData:extraData]; [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// [data setObject:message forKey:@"message"]; -// -// [self recordEventForLevel:level type:RollbarTelemetryError data:data]; } - (void)recordNavigationEventForLevel:(RollbarLevel)level @@ -320,16 +266,6 @@ - (void)recordNavigationEventForLevel:(RollbarLevel)level toLocation:to extraData:extraData]; [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// [data setObject:from forKey:@"from"]; -// [data setObject:to forKey:@"to"]; -// -// [self recordEventForLevel:level type:RollbarTelemetryNavigation data:data]; } - (void)recordManualEventForLevel:(RollbarLevel)level @@ -341,13 +277,6 @@ - (void)recordManualEventForLevel:(RollbarLevel)level RollbarTelemetryManualBody *body = [[RollbarTelemetryManualBody alloc] initWithDictionary:extraData]; [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// [self recordEventForLevel:level type:RollbarTelemetryManual data:data]; } - (void)recordLogEventForLevel:(RollbarLevel)level @@ -361,15 +290,6 @@ - (void)recordLogEventForLevel:(RollbarLevel)level RollbarTelemetryLogBody *body = [[RollbarTelemetryLogBody alloc] initWithMessage:message extraData:extraData]; [self recordEventWithLevel:level eventBody:body]; - -// NSMutableDictionary *data = [NSMutableDictionary dictionary]; -// if (extraData) { -// [data addEntriesFromDictionary:extraData]; -// } -// -// [data setObject:message forKey:@"message"]; -// -// [self recordEventForLevel:level type:RollbarTelemetryLog data:data]; } #pragma mark - Tlemetry cache access methods From 03e55353f7962ce921f8305cf6a5e7b6686e229b Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Fri, 15 Apr 2022 18:59:45 -0700 Subject: [PATCH 07/11] feat: ref #145,#146, #147, #148 first cut --- .../RollbarCommon/DTOs/RollbarDTO+Protected.m | 18 ++ .../include/RollbarDTO+Protected.h | 30 +- .../DTOs/RollbarTelemetryOptions.m | 23 +- .../Sources/RollbarNotifier/Rollbar.m | 10 +- .../Sources/RollbarNotifier/RollbarLogger.m | 9 +- .../RollbarNotifier/RollbarTelemetry.m | 90 ++++-- .../RollbarNotifier/RollbarTelemetryThread.h | 44 +++ .../RollbarNotifier/RollbarTelemetryThread.m | 290 ++++++++++++++++++ .../include/RollbarTelemetry.h | 24 ++ .../include/RollbarTelemetryOptions.h | 4 + .../RollbarNotifierTelemetryTests.swift | 25 ++ 11 files changed, 522 insertions(+), 45 deletions(-) create mode 100644 RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.h create mode 100644 RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m diff --git a/RollbarCommon/Sources/RollbarCommon/DTOs/RollbarDTO+Protected.m b/RollbarCommon/Sources/RollbarCommon/DTOs/RollbarDTO+Protected.m index ac579ce1..3688717d 100644 --- a/RollbarCommon/Sources/RollbarCommon/DTOs/RollbarDTO+Protected.m +++ b/RollbarCommon/Sources/RollbarCommon/DTOs/RollbarDTO+Protected.m @@ -220,4 +220,22 @@ - (void)setInteger:(NSInteger)data forKey:(NSString *)key { [self setNumber:number forKey:key]; } +- (NSTimeInterval)safelyGetTimeIntervalByKey:(NSString *)key + withDefault:(NSTimeInterval)defaultValue { + + NSNumber *value = [self safelyGetNumberByKey:key]; + if (value) { + return value.doubleValue; + } + else { + return defaultValue; + } +} + +- (void)setTimeInterval:(NSTimeInterval)data forKey:(NSString *)key { + + NSNumber *number = @(data); + [self setNumber:number forKey:key]; +} + @end diff --git a/RollbarCommon/Sources/RollbarCommon/include/RollbarDTO+Protected.h b/RollbarCommon/Sources/RollbarCommon/include/RollbarDTO+Protected.h index 087902a0..3de15f77 100644 --- a/RollbarCommon/Sources/RollbarCommon/include/RollbarDTO+Protected.h +++ b/RollbarCommon/Sources/RollbarCommon/include/RollbarDTO+Protected.h @@ -51,19 +51,33 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Convenience API - (RollbarDTO *)safelyGetDataTransferObjectByKey:(NSString *)key; -- (void)setDataTransferObject:(RollbarDTO *)data forKey:(NSString *)key; +- (void)setDataTransferObject:(RollbarDTO *)data + forKey:(NSString *)key; - (RollbarTriStateFlag)safelyGetTriStateFlagByKey:(NSString *)key; -- (void)setTriStateFlag:(RollbarTriStateFlag)data forKey:(NSString *)key; +- (void)setTriStateFlag:(RollbarTriStateFlag)data + forKey:(NSString *)key; -- (BOOL)safelyGetBoolByKey:(NSString *)key withDefault:(BOOL)defaultValue; -- (void)setBool:(BOOL)data forKey:(NSString *)key; +- (BOOL)safelyGetBoolByKey:(NSString *)key + withDefault:(BOOL)defaultValue; +- (void)setBool:(BOOL)data + forKey:(NSString *)key; -- (NSUInteger)safelyGetUIntegerByKey:(NSString *)key withDefault:(NSUInteger)defaultValue; -- (void)setUInteger:(NSUInteger)data forKey:(NSString *)key; +- (NSUInteger)safelyGetUIntegerByKey:(NSString *)key + withDefault:(NSUInteger)defaultValue; +- (void)setUInteger:(NSUInteger)data + forKey:(NSString *)key; + +- (NSInteger)safelyGetIntegerByKey:(NSString *)key + withDefault:(NSInteger)defaultValue; +- (void)setInteger:(NSInteger)data + forKey:(NSString *)key; + +- (NSTimeInterval)safelyGetTimeIntervalByKey:(NSString *)key + withDefault:(NSTimeInterval)defaultValue; +- (void)setTimeInterval:(NSTimeInterval)data + forKey:(NSString *)key; -- (NSInteger)safelyGetIntegerByKey:(NSString *)key withDefault:(NSInteger)defaultValue; -- (void)setInteger:(NSInteger)data forKey:(NSString *)key; @end diff --git a/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarTelemetryOptions.m b/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarTelemetryOptions.m index 4f5c3289..33d6eb87 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarTelemetryOptions.m +++ b/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarTelemetryOptions.m @@ -7,6 +7,7 @@ static BOOL const DEFAULT_CAPTURE_LOG_FLAG = NO; static BOOL const DEFAULT_CAPTURE_CONNECTIVITY_FLAG = NO; static NSUInteger const DEFAULT_MAX_TELEMETRY_DATA = 10; +static NSTimeInterval const DEFAULT_AUTOCOLLECTION_INTERVAL_MEM_STATS = 0; #pragma mark - data field keys @@ -15,6 +16,7 @@ static NSString *const DFK_CAPTURE_CONNECTIVITY_FLAG = @"captureConnectivity"; static NSString *const DFK_MAX_TELEMETRY_DATA = @"maximumTelemetryData"; static NSString *const DFK_VIEW_INPUTS_SCRUBBER = @"vewInputsScrubber"; +static NSString *const DFK_AUTOCOLLECTION_INTERVAL_MEM_STATS = @"memoryStatsAutocollectionInterval"; #pragma mark - class implementation @@ -29,11 +31,12 @@ - (instancetype)initWithEnabled:(BOOL)enabled viewInputsScrubber:(RollbarScrubbingOptions *)viewInputsScrubber { self = [super initWithDictionary:@{ - DFK_ENABLED_FLAG:[NSNumber numberWithBool:enabled], - DFK_CAPTURE_LOG_FLAG:[NSNumber numberWithBool:captureLog], - DFK_CAPTURE_CONNECTIVITY_FLAG:[NSNumber numberWithBool:captureConnectivity], - DFK_VIEW_INPUTS_SCRUBBER:viewInputsScrubber.jsonFriendlyData, - DFK_MAX_TELEMETRY_DATA:[NSNumber numberWithUnsignedInt:DEFAULT_MAX_TELEMETRY_DATA] + DFK_ENABLED_FLAG : [NSNumber numberWithBool:enabled], + DFK_CAPTURE_LOG_FLAG : [NSNumber numberWithBool:captureLog], + DFK_CAPTURE_CONNECTIVITY_FLAG : [NSNumber numberWithBool:captureConnectivity], + DFK_VIEW_INPUTS_SCRUBBER : viewInputsScrubber.jsonFriendlyData, + DFK_MAX_TELEMETRY_DATA : [NSNumber numberWithUnsignedInt:DEFAULT_MAX_TELEMETRY_DATA], + DFK_AUTOCOLLECTION_INTERVAL_MEM_STATS : [NSNumber numberWithDouble:DEFAULT_AUTOCOLLECTION_INTERVAL_MEM_STATS], }]; return self; } @@ -119,4 +122,14 @@ - (void)setViewInputsScrubber:(RollbarScrubbingOptions *)scrubber { [self setDataTransferObject:scrubber forKey:DFK_VIEW_INPUTS_SCRUBBER]; } +- (NSTimeInterval)memoryStatsAutocollectionInterval { + NSTimeInterval result = [self safelyGetTimeIntervalByKey:DFK_AUTOCOLLECTION_INTERVAL_MEM_STATS + withDefault:DEFAULT_AUTOCOLLECTION_INTERVAL_MEM_STATS]; + return result; +} + +- (void)setMemoryStatsAutocollectionInterval:(NSTimeInterval)value { + [self setTimeInterval:value forKey:DFK_AUTOCOLLECTION_INTERVAL_MEM_STATS]; +} + @end diff --git a/RollbarNotifier/Sources/RollbarNotifier/Rollbar.m b/RollbarNotifier/Sources/RollbarNotifier/Rollbar.m index a0c87dfa..e22940ae 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/Rollbar.m +++ b/RollbarNotifier/Sources/RollbarNotifier/Rollbar.m @@ -5,6 +5,7 @@ #import "RollbarConfig.h" #import "RollbarDestination.h" #import "RollbarLoggingOptions.h" +#import "RollbarTelemetryThread.h" #import "RollbarTelemetryOptions.h" #import "RollbarTelemetryOptionsObserver.h" #import "RollbarScrubbingOptions.h" @@ -60,7 +61,6 @@ + (void)initWithAccessToken:(nullable NSString *)accessToken configuration:(nullable RollbarConfig *)configuration crashCollector:(nullable id)crashCollector { - [RollbarTelemetry sharedInstance]; // Load saved data, if any if (logger) { RollbarSdkLog(@"Rollbar has already been initialized."); @@ -108,12 +108,8 @@ + (void)updateConfiguration:(RollbarConfig *)configuration { } if (configuration && configuration.telemetry) { - [RollbarTelemetry sharedInstance].enabled = configuration.telemetry.enabled; - [RollbarTelemetry sharedInstance].scrubViewInputs = configuration.telemetry.viewInputsScrubber.enabled; - [RollbarTelemetry sharedInstance].viewInputsToScrub = - [NSSet setWithArray:configuration.telemetry.viewInputsScrubber.scrubFields].mutableCopy; - [[RollbarTelemetry sharedInstance] setCaptureLog:configuration.telemetry.captureLog]; - [[RollbarTelemetry sharedInstance] setDataLimit:configuration.telemetry.maximumTelemetryData]; + + [[RollbarTelemetry sharedInstance] configureWithOptions:configuration.telemetry]; } } diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m index f7b5d4bb..c3a613b1 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m @@ -9,6 +9,7 @@ #import "RollbarLogger.h" #import "RollbarLogger+Test.h" #import "RollbarThread.h" +#import "RollbarTelemetryThread.h" #import "RollbarReachability.h" #import #import "RollbarTelemetry.h" @@ -111,9 +112,14 @@ + (void)initialize { [self saveQueueState]; } + RollbarConfig *config = [RollbarConfig new]; + + // Setup the worker thread that atomatically collects pre-configured telemetry events (if any): + //[[RollbarTelemetryThread sharedInstance] configureWithOptions:config.telemetry]; + //[[RollbarTelemetryThread sharedInstance] start]; + // Setup the worker thread that sends the items that have been queued up in the item file set above: // TODO: !!! this needs to be redesigned taking in account multiple access tokens and endpoints !!! - RollbarConfig *config = [RollbarConfig new]; RollbarLogger *logger = [[RollbarLogger alloc] initWithConfiguration:config]; rollbarThread = [[RollbarThread alloc] initWithNotifier:logger @@ -164,6 +170,7 @@ - (instancetype)initWithAccessToken:(NSString *)accessToken { - (instancetype)initWithConfiguration:(RollbarConfig *)configuration { if ((self = [super init])) { + [self updateConfiguration:configuration]; NSString *cachesDirectory = [RollbarCachesDirectory directory]; diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m index f8df88cc..a8b11b5f 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetry.m @@ -3,6 +3,9 @@ #import "RollbarTelemetry.h" #import "RollbarCachesDirectory.h" +#import "RollbarTelemetryOptions.h" +#import "RollbarScrubbingOptions.h" +#import "RollbarTelemetryThread.h" #import "RollbarTelemetryEvent.h" #import "RollbarTelemetryBody.h" #import "RollbarTelemetryLogBody.h" @@ -18,6 +21,8 @@ static BOOL captureLog = false; +static RollbarTelemetry * _Nullable singleton = nil; + // this queue is used for serializing state changes to the various // state in this class: captureLog, limit, dataArray static dispatch_queue_t queue = nil; @@ -32,18 +37,7 @@ @implementation RollbarTelemetry { NSString *_dataFilePath; } -+ (instancetype)sharedInstance { - - static RollbarTelemetry *sharedInstance = nil; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - sharedInstance = [[RollbarTelemetry alloc] init]; - queue = dispatch_queue_create("com.rollbar.telemetryQueue", DISPATCH_QUEUE_SERIAL); - fileQueue = dispatch_queue_create("com.rollbar.telemetryFileQueue", DISPATCH_QUEUE_SERIAL); - }); - return sharedInstance; -} +#pragma mark - NSLog redirection + (void)NSLogReplacement:(NSString *)format, ... { @@ -63,6 +57,25 @@ + (void)NSLogReplacement:(NSString *)format, ... { va_end(args); } +#pragma mark - Singleton pattern + ++ (instancetype)sharedInstance { + + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + singleton = [[RollbarTelemetry alloc] init]; + queue = dispatch_queue_create("com.rollbar.telemetryQueue", DISPATCH_QUEUE_SERIAL); + fileQueue = dispatch_queue_create("com.rollbar.telemetryFileQueue", DISPATCH_QUEUE_SERIAL); + }); + return singleton; +} + ++ (BOOL)sharedInstanceExists { + + return (nil != singleton); +} + #pragma mark - Initializers - (instancetype)init { @@ -86,6 +99,22 @@ - (instancetype)init { #pragma mark - Config options +- (instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions { + + self.enabled = telemetryOptions.enabled; + self.scrubViewInputs = telemetryOptions.viewInputsScrubber.enabled; + self.viewInputsToScrub = [NSSet setWithArray:telemetryOptions.viewInputsScrubber.scrubFields].mutableCopy; + + [self setCaptureLog:telemetryOptions.captureLog]; + [self setDataLimit:telemetryOptions.maximumTelemetryData]; + + [[RollbarTelemetryThread sharedInstance] configureWithOptions:telemetryOptions]; + if (![RollbarTelemetryThread sharedInstance].active) { + + [[RollbarTelemetryThread sharedInstance] start]; + } +} + - (void)setCaptureLog:(BOOL)shouldCapture { dispatch_async(queue, ^{ @@ -101,16 +130,6 @@ - (void)setDataLimit:(NSInteger)dataLimit { }); } -- (void)trimDataArray { - - if (@available(iOS 10.0, macOS 10.12, *)) { - dispatch_assert_queue_debug(queue); - } - if (_limit > 0 && _dataArray.count > _limit) { - [_dataArray removeObjectsInRange:NSMakeRange(0, _dataArray.count - _limit)]; - } -} - #pragma mark - Telemetry data/event recording methods - (void)recordEvent:(nonnull RollbarTelemetryEvent *)event { @@ -292,7 +311,7 @@ - (void)recordLogEventForLevel:(RollbarLevel)level [self recordEventWithLevel:level eventBody:body]; } -#pragma mark - Tlemetry cache access methods +#pragma mark - Telemetry Data access methods -(nonnull NSArray *)getAllEvents { NSArray *telemetryData = [self getAllData]; @@ -344,7 +363,19 @@ - (void)clearAllData { }); } -#pragma mark - Data storage +#pragma mark - Telemetry Data manipulation + +- (void)trimDataArray { + + if (@available(iOS 10.0, macOS 10.12, *)) { + dispatch_assert_queue_debug(queue); + } + if (_limit > 0 && _dataArray.count > _limit) { + [_dataArray removeObjectsInRange:NSMakeRange(0, _dataArray.count - _limit)]; + } +} + +#pragma mark - Telemetry Data persistence // This is used for getting a read-only copy of our shared dataArray // which can later be written to a file. This method must be called @@ -389,4 +420,15 @@ - (void)loadTelemetryData { } } +//#pragma mark - Memory stats collection +// +//- (void)collectMemoryStats { +// +// NSObject *memoryStats = [RollbarMemoryUtil getMemoryStats]; +// +// [self recordManualEventForLevel:RollbarLevel_Info withData:@{ +// @"memory_stats" : memoryStats, +// }]; +//} + @end diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.h b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.h new file mode 100644 index 00000000..cc7053fc --- /dev/null +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.h @@ -0,0 +1,44 @@ +// +// RollbarTelemetryThread.h +// +// +// Created by Andrey Kornich on 2022-04-11. +// + +#import + +@class RollbarTelemetryOptions; + +NS_ASSUME_NONNULL_BEGIN + +@interface RollbarTelemetryThread : NSThread + +/// Configures this instance with provided options +/// @param telemetryOptions desired Telemetry options +- (instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions; + +/// Signifies that the thread is active or not. +@property(atomic) BOOL active; + +#pragma mark - Sigleton pattern + ++ (nonnull instancetype)sharedInstance; ++ (BOOL)sharedInstanceExists; + ++ (instancetype)new NS_UNAVAILABLE; ++ (instancetype)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (instancetype)alloc NS_UNAVAILABLE; ++ (id)copyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (id)mutableCopyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_UNAVAILABLE; +- (instancetype)initWithBlock:(void (^)(void))block NS_UNAVAILABLE; + +- (void)dealloc NS_UNAVAILABLE; +- (id)copy NS_UNAVAILABLE; +- (id)mutableCopy NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m new file mode 100644 index 00000000..1ca2b1ae --- /dev/null +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m @@ -0,0 +1,290 @@ +@import RollbarCommon; + +#import "RollbarTelemetryThread.h" +#import "RollbarTelemetryOptions.h" + +#import "RollbarTelemetry.h" +#import "RollbarTelemetryEvent.h" +#import "RollbarTelemetryBody.h" +#import "RollbarTelemetryManualBody.h" + +static RollbarTelemetryThread * _Nullable singleton = nil; + +@implementation RollbarTelemetryThread { + + @private NSTimer *_timer; + @private NSTimeInterval _collectionTimeInterval; + @private RollbarTelemetryOptions *_telemetryOptions; +} + +#pragma mark - Sigleton pattern + ++ (nonnull instancetype)sharedInstance { + + //static RollbarMemoryStatsDescriptors *singleton = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + + //singleton = [[[self class] alloc] initWithTarget:singleton selector:@selector(run) object:nil]; + singleton = [[self class] alloc]; + if ((singleton = [singleton initWithTarget:singleton //self + selector:@selector(run) + object:nil + ])) { + + singleton.name = [RollbarTelemetryThread className]; //@"RollbarTelemetryThread"; + + singleton->_telemetryOptions = nil; + + singleton->_collectionTimeInterval = 0; + + singleton.active = NO; + } + + }); + + return singleton; +} + ++ (BOOL)sharedInstanceExists { + + return (nil != singleton); +} + +- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument { + + if ((self = [super initWithTarget:target //self + selector:selector //@selector(run) + object:argument//nil + ])) { + + self.name = [RollbarTelemetryThread className]; //@"RollbarTelemetryThread"; + + self->_telemetryOptions = nil; + + self->_collectionTimeInterval = 0; + + self.active = NO; + } + + return self; +} + + + +//// Reset the worker thread that atomatically collects pre-configured telemetry events (if any): +//if (!rollbarTelemetryThread) { +// +// if (!rollbarTelemetryThread.isCancelled) { +// +// [rollbarTelemetryThread cancel]; +// } +// while (!rollbarTelemetryThread.isFinished) { +// +// [NSThread sleepForTimeInterval:0.1]; // [sec] +// } +// rollbarTelemetryThread = nil; +//} +//rollbarTelemetryThread = [[RollbarTelemetryThread alloc] initWithOptions: configuration.telemetry]; + + +- (instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions { + +// self->_active = YES; + + self->_telemetryOptions = telemetryOptions; + + if (![self setupTimer]) { + + return self; + } + + if (!self.executing) { + + [self start]; + } + + return self; +} + +- (BOOL)setupTimer { + + self->_collectionTimeInterval = [RollbarTelemetryThread calculateCollectionTimeInterval:self->_telemetryOptions]; + + if (self->_timer && self->_timer.timeInterval == self->_collectionTimeInterval) { + + // nothing fundamental needs reconfiguration... + //return (nil != self->_timer); + return !(0.0 == self->_timer.timeInterval); + } + + if (self->_timer) { + + // shut down the existing timer: + [self->_timer invalidate]; + while(self->_timer.valid) { + + //no-op... + } + self->_timer = nil; + } + + if (0.0 == self->_collectionTimeInterval) { + + // nothing to collect... + return NO; + } + + self->_timer = [NSTimer timerWithTimeInterval:self->_collectionTimeInterval + target:self + selector:@selector(attemptCollection) + userInfo:nil + repeats:YES + ]; +// NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; +// [runLoop addTimer:self->_timer forMode:NSDefaultRunLoopMode]; + + return YES; +} + ++ (NSTimeInterval)calculateCollectionTimeInterval:(nonnull RollbarTelemetryOptions *)telemetryOptions { + + // iterate through all the autocollection intervals existing in the telemetryOptions + // and find the shortest one, then divide it by 10 and return the value: + + NSTimeInterval intervals[] = { + telemetryOptions.memoryStatsAutocollectionInterval, + //add all other new auto-collection intervals defined within the telemetryOptions... + }; + + int intervalsCount = sizeof(intervals)/sizeof(NSTimeInterval); + switch (intervalsCount) { + case 0: + return 0; + case 1: + return intervals[0]; + default: { + NSTimeInterval min = intervals[0]; + int i = 1; + while (i < intervalsCount) { + if (intervals[i] < min) { + min = intervals[i]; + } + i++; + } + return min; + } + } +} + +- (void)start { + + if (!self.active && [self setupTimer]) { + + + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + + [super start]; + }); + } +} + +- (void)run { + + if (self.active) { + + return; + } + + @autoreleasepool { + +// NSTimeInterval timeIntervalInSeconds = self->_collectionTimeInterval; +// if (0.0 == timeIntervalInSeconds) { +// +// return; +// } +// +// _timer = [NSTimer timerWithTimeInterval:timeIntervalInSeconds +// target:self +// selector:@selector(attemptCollection) +// userInfo:nil +// repeats:YES +// ]; +// +// NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; +// [runLoop addTimer:_timer forMode:NSDefaultRunLoopMode]; + +// if (![self setupTimer]) { +// +// // nothing really to do... +// return; +// } + + self.active = YES; + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + [runLoop addTimer:self->_timer forMode:NSDefaultRunLoopMode]; + while (self.active) { + if (self->_timer) { + [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; + } + } + [runLoop run]; + } +} + +- (void)attemptCollection { + + if (self.cancelled) { + + if (self->_timer) { + + [self->_timer invalidate]; + self->_timer = nil; + } + + [NSThread exit]; + } + + @autoreleasepool { + + [self attemptMemoryStatsCollection]; + // add attempts of other auto-collections here... + } +} + +- (void)attemptMemoryStatsCollection { + +// [self collectMemoryStats]; +// return; + + static NSDate *nextCollection = nil; + if (!nextCollection) { + + [self collectMemoryStats]; + nextCollection = [[NSDate date] + dateByAddingTimeInterval:self->_telemetryOptions.memoryStatsAutocollectionInterval + ]; + } + else if ([[NSDate date] compare:nextCollection] == NSOrderedAscending) { + + [self collectMemoryStats]; + nextCollection = + [nextCollection dateByAddingTimeInterval:self->_telemetryOptions.memoryStatsAutocollectionInterval]; + } +} + +- (void)collectMemoryStats { + + NSObject *memoryStats = [RollbarMemoryUtil getMemoryStats]; + + [[RollbarTelemetry sharedInstance] recordManualEventForLevel:RollbarLevel_Info + withData:@{ + @"memory_stats" : memoryStats, + } + ]; +} + +@end diff --git a/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h b/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h index 942a4651..9544e856 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h +++ b/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h @@ -4,6 +4,7 @@ #import "RollbarSource.h" #import "RollbarTelemetryType.h" +@class RollbarTelemetryOptions; @class RollbarTelemetryEvent; @class RollbarTelemetryBody; @class RollbarTelemetryLogBody; @@ -22,12 +23,35 @@ /// Shared service instance/singleton + (nonnull instancetype)sharedInstance; +#pragma mark - Sigleton pattern + ++ (nonnull instancetype)sharedInstance; ++ (BOOL)sharedInstanceExists; + ++ (instancetype)new NS_UNAVAILABLE; ++ (instancetype)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (instancetype)alloc NS_UNAVAILABLE; ++ (id)copyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (id)mutableCopyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; + +- (void)dealloc NS_UNAVAILABLE; +- (id)copy NS_UNAVAILABLE; +- (id)mutableCopy NS_UNAVAILABLE; + +#pragma mark - NSLog redirection + /// NSLog replacement /// @param format NSLog entry format + (void)NSLogReplacement:(nonnull NSString *)format, ...; #pragma mark - Config options +/// Configures this instance with provided options +/// @param telemetryOptions desired Telemetry options +- (instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions; + /// Telemetry collection enable/disable switch @property (readwrite, atomic) BOOL enabled; diff --git a/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetryOptions.h b/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetryOptions.h index f16fd02f..5fb4a6df 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetryOptions.h +++ b/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetryOptions.h @@ -23,6 +23,10 @@ NS_ASSUME_NONNULL_BEGIN /// Telemetry scrubbing options @property (nonatomic, strong) RollbarScrubbingOptions *viewInputsScrubber; +/// Time interval for auto-collecting memtory stats +/// @note 0.0 means no collection! +@property (atomic) NSTimeInterval memoryStatsAutocollectionInterval; //[sec] + #pragma mark - initializers /// Initializer diff --git a/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift b/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift index 0d742d65..9604b7d4 100644 --- a/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift +++ b/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift @@ -8,9 +8,11 @@ import UnitTesting final class RollbarNotifierTelemetryTests: XCTestCase { override func setUp() { + super.setUp(); RollbarTestUtil.clearLogFile(); RollbarTestUtil.clearTelemetryFile(); + if Rollbar.currentConfiguration() != nil { print("Info: Rollbar already pre-configured!"); } @@ -25,6 +27,28 @@ final class RollbarNotifierTelemetryTests: XCTestCase { super.tearDown(); } + func testMemoryTelemetryAutocapture() { + + RollbarTestUtil.clearLogFile(); + RollbarTestUtil.clearTelemetryFile(); + + let config = RollbarConfig(); + config.destination.accessToken = RollbarTestHelper.getRollbarPayloadsAccessToken(); + config.destination.environment = RollbarTestHelper.getRollbarEnvironment(); + config.telemetry.enabled = true; + config.telemetry.memoryStatsAutocollectionInterval = 0.5; + + Rollbar.updateConfiguration(config); + + //let resultingConfig = Rollbar.currentConfiguration(); + Rollbar.criticalMessage("Rollbar will be testing memory telemetry!"); + RollbarTestUtil.waitForPesistenceToComplete(); + Thread.sleep(forTimeInterval: 2.0); + Rollbar.criticalMessage("Must contain memory telemetry!"); + RollbarTestUtil.waitForPesistenceToComplete(); + Thread.sleep(forTimeInterval: 3.0); + } + func testTelemetryCapture() { RollbarTestUtil.clearLogFile(); @@ -237,6 +261,7 @@ final class RollbarNotifierTelemetryTests: XCTestCase { } static var allTests = [ + ("testMemoryTelemetryAutocapture", testMemoryTelemetryAutocapture), ("testTelemetryCapture", testTelemetryCapture), ("testErrorReportingWithTelemetry", testErrorReportingWithTelemetry), ("testTelemetryViewEventScrubbing", testTelemetryViewEventScrubbing), From 03069e1d09c32cbf3ffd851e82641ddf5f77cc54 Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 18 Apr 2022 12:21:38 -0700 Subject: [PATCH 08/11] feat: ref #147, #148 code cleanup --- .../Sources/RollbarCommon/RollbarMemoryUtil.m | 13 ++++- .../RollbarCommon/include/RollbarMemoryUtil.h | 1 - .../RollbarNotifier/RollbarTelemetryThread.m | 56 ++----------------- .../include/RollbarTelemetry.h | 18 +++--- 4 files changed, 24 insertions(+), 64 deletions(-) diff --git a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m index 6388ef39..9168e2c6 100644 --- a/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m +++ b/RollbarCommon/Sources/RollbarCommon/RollbarMemoryUtil.m @@ -89,7 +89,12 @@ + (void)initialize { + (NSUInteger)getPhysicalMemoryInBytes { - unsigned long long bytesTotal = [[NSProcessInfo processInfo] physicalMemory]; + static unsigned long long bytesTotal = 0; + + if (0 == bytesTotal) { + + bytesTotal = [[NSProcessInfo processInfo] physicalMemory]; + } return (NSUInteger)bytesTotal; } @@ -112,7 +117,11 @@ + (NSString *)convertToHumanFriendlyFormat:(NSUInteger)bytesCount { + (NSUInteger)getPhysicalMemoryInMBs { - NSInteger result = [RollbarMemoryUtil convertToMBs:[RollbarMemoryUtil getPhysicalMemoryInBytes]]; + static NSInteger result = 0; + if (0 == result) { + + result = [RollbarMemoryUtil convertToMBs:[RollbarMemoryUtil getPhysicalMemoryInBytes]]; + } return result; } diff --git a/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h index 6eb0fa63..a3a6519d 100644 --- a/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h +++ b/RollbarCommon/Sources/RollbarCommon/include/RollbarMemoryUtil.h @@ -11,7 +11,6 @@ NS_ASSUME_NONNULL_BEGIN @interface RollbarMemoryUtil : NSObject - #pragma mark - memory stats getters + (nonnull NSDictionary *)getMemoryStats; diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m index 1ca2b1ae..beb77ce5 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m @@ -21,7 +21,6 @@ @implementation RollbarTelemetryThread { + (nonnull instancetype)sharedInstance { - //static RollbarMemoryStatsDescriptors *singleton = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -33,7 +32,7 @@ + (nonnull instancetype)sharedInstance { object:nil ])) { - singleton.name = [RollbarTelemetryThread className]; //@"RollbarTelemetryThread"; + singleton.name = [RollbarTelemetryThread rollbar_objectClassName]; //@"RollbarTelemetryThread"; singleton->_telemetryOptions = nil; @@ -54,9 +53,9 @@ + (BOOL)sharedInstanceExists { - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument { - if ((self = [super initWithTarget:target //self - selector:selector //@selector(run) - object:argument//nil + if ((self = [super initWithTarget:target + selector:selector + object:argument ])) { self.name = [RollbarTelemetryThread className]; //@"RollbarTelemetryThread"; @@ -71,28 +70,8 @@ - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullabl return self; } - - -//// Reset the worker thread that atomatically collects pre-configured telemetry events (if any): -//if (!rollbarTelemetryThread) { -// -// if (!rollbarTelemetryThread.isCancelled) { -// -// [rollbarTelemetryThread cancel]; -// } -// while (!rollbarTelemetryThread.isFinished) { -// -// [NSThread sleepForTimeInterval:0.1]; // [sec] -// } -// rollbarTelemetryThread = nil; -//} -//rollbarTelemetryThread = [[RollbarTelemetryThread alloc] initWithOptions: configuration.telemetry]; - - - (instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions { -// self->_active = YES; - self->_telemetryOptions = telemetryOptions; if (![self setupTimer]) { @@ -142,8 +121,6 @@ - (BOOL)setupTimer { userInfo:nil repeats:YES ]; -// NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; -// [runLoop addTimer:self->_timer forMode:NSDefaultRunLoopMode]; return YES; } @@ -201,28 +178,6 @@ - (void)run { @autoreleasepool { -// NSTimeInterval timeIntervalInSeconds = self->_collectionTimeInterval; -// if (0.0 == timeIntervalInSeconds) { -// -// return; -// } -// -// _timer = [NSTimer timerWithTimeInterval:timeIntervalInSeconds -// target:self -// selector:@selector(attemptCollection) -// userInfo:nil -// repeats:YES -// ]; -// -// NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; -// [runLoop addTimer:_timer forMode:NSDefaultRunLoopMode]; - -// if (![self setupTimer]) { -// -// // nothing really to do... -// return; -// } - self.active = YES; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:self->_timer forMode:NSDefaultRunLoopMode]; @@ -257,9 +212,6 @@ - (void)attemptCollection { - (void)attemptMemoryStatsCollection { -// [self collectMemoryStats]; -// return; - static NSDate *nextCollection = nil; if (!nextCollection) { diff --git a/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h b/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h index 9544e856..618f8aff 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h +++ b/RollbarNotifier/Sources/RollbarNotifier/include/RollbarTelemetry.h @@ -28,17 +28,17 @@ + (nonnull instancetype)sharedInstance; + (BOOL)sharedInstanceExists; -+ (instancetype)new NS_UNAVAILABLE; -+ (instancetype)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; -+ (instancetype)alloc NS_UNAVAILABLE; -+ (id)copyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; -+ (id)mutableCopyWithZone:(struct _NSZone *)zone NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; ++ (nonnull instancetype)allocWithZone:(nonnull struct _NSZone *)zone NS_UNAVAILABLE; ++ (nonnull instancetype)alloc NS_UNAVAILABLE; ++ (nullable id)copyWithZone:(nonnull struct _NSZone *)zone NS_UNAVAILABLE; ++ (nullable id)mutableCopyWithZone:(nonnull struct _NSZone *)zone NS_UNAVAILABLE; -- (instancetype)init NS_UNAVAILABLE; +- (nonnull instancetype)init NS_UNAVAILABLE; - (void)dealloc NS_UNAVAILABLE; -- (id)copy NS_UNAVAILABLE; -- (id)mutableCopy NS_UNAVAILABLE; +- (nonnull id)copy NS_UNAVAILABLE; +- (nonnull id)mutableCopy NS_UNAVAILABLE; #pragma mark - NSLog redirection @@ -50,7 +50,7 @@ /// Configures this instance with provided options /// @param telemetryOptions desired Telemetry options -- (instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions; +- (nonnull instancetype)configureWithOptions:(nonnull RollbarTelemetryOptions *)telemetryOptions; /// Telemetry collection enable/disable switch @property (readwrite, atomic) BOOL enabled; From b495d07b921fc9f017034744bc39b6286e76ce49 Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 18 Apr 2022 14:49:08 -0700 Subject: [PATCH 09/11] feat: ref #147, #148, #149 added unit-tests --- .../RollbarNotifier/RollbarTelemetryThread.m | 2 +- .../RollbarNotifierTelemetryTests.swift | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m index beb77ce5..27fe7260 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m @@ -58,7 +58,7 @@ - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullabl object:argument ])) { - self.name = [RollbarTelemetryThread className]; //@"RollbarTelemetryThread"; + self.name = [RollbarTelemetryThread rollbar_objectClassName]; //@"RollbarTelemetryThread"; self->_telemetryOptions = nil; diff --git a/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift b/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift index 9604b7d4..4684081a 100644 --- a/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift +++ b/RollbarNotifier/Tests/RollbarNotifierTests/RollbarNotifierTelemetryTests.swift @@ -32,6 +32,40 @@ final class RollbarNotifierTelemetryTests: XCTestCase { RollbarTestUtil.clearLogFile(); RollbarTestUtil.clearTelemetryFile(); + let config = RollbarConfig(); + config.destination.accessToken = RollbarTestHelper.getRollbarPayloadsAccessToken(); + config.destination.environment = RollbarTestHelper.getRollbarEnvironment(); + config.developerOptions.transmit = false; + config.telemetry.enabled = true; + config.telemetry.memoryStatsAutocollectionInterval = 0.5; + Rollbar.updateConfiguration(config); + + Thread.sleep(forTimeInterval: 5.0); + Rollbar.criticalMessage("Must contain memory telemetry!"); + RollbarTestUtil.waitForPesistenceToComplete(); + + let logItem = RollbarTestUtil.readFirstItemStringsFromLogFile()!; + let payload = RollbarPayload(jsonString: logItem); + let telemetryEvents = payload.data.body.telemetry!; + XCTAssertTrue(telemetryEvents.count > 0); + var totalMemoryStatsEvents = 0; + for event in telemetryEvents { + if (event.type == RollbarTelemetryType.manual) { + if let content = event.body as? RollbarTelemetryManualBody { + if !content.isEmpty && content.description.contains("memory_stats") { + totalMemoryStatsEvents += 1; + } + } + } + } + XCTAssertTrue(totalMemoryStatsEvents > 0); + } + + func testMemoryTelemetryAutocapture_Live() { + + RollbarTestUtil.clearLogFile(); + RollbarTestUtil.clearTelemetryFile(); + let config = RollbarConfig(); config.destination.accessToken = RollbarTestHelper.getRollbarPayloadsAccessToken(); config.destination.environment = RollbarTestHelper.getRollbarEnvironment(); @@ -262,6 +296,7 @@ final class RollbarNotifierTelemetryTests: XCTestCase { static var allTests = [ ("testMemoryTelemetryAutocapture", testMemoryTelemetryAutocapture), + ("testMemoryTelemetryAutocapture_Live", testMemoryTelemetryAutocapture_Live), ("testTelemetryCapture", testTelemetryCapture), ("testErrorReportingWithTelemetry", testErrorReportingWithTelemetry), ("testTelemetryViewEventScrubbing", testTelemetryViewEventScrubbing), From 4a284809c17f3640b3035203c47cd2e4ab63f2aa Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 18 Apr 2022 15:40:24 -0700 Subject: [PATCH 10/11] chore: incremented version --- CHANGELOG.md | 7 +++++++ RollbarAUL.podspec | 2 +- RollbarCommon.podspec | 2 +- RollbarDeploys.podspec | 2 +- RollbarKSCrash.podspec | 2 +- RollbarNotifier.podspec | 2 +- .../Sources/RollbarNotifier/DTOs/RollbarConfig.m | 2 +- RollbarPLCrashReporter.podspec | 2 +- RollbarSDK.experimental_podspec | 2 +- RollbarSwift.podspec | 2 +- 10 files changed, 16 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f136cf3b..a2f39954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,13 @@ The change log has moved to this repo's [GitHub Releases Page](https://github.co ## Release Notes +### 2.2.0 + +- feat: resolve #148 - MemTel: Implement the memory usage Telemetry auto-collection based on the config options. +- feat: resolve #147 - MemTel: Implement necessary Telemetry auto-collection options config settings with the first available option being the memory usage collection. +- feat: resolve #146 - MemTel: Define custom data fields for a Manual Telemetry event to keep the collected data. Implement helpers to manage that data. +- test: resolve #148 - MemTel: Add unit tests. + ### 2.1.0 - feat: resolve #141 - Apply developer options of the persisted payload when sending the payload diff --git a/RollbarAUL.podspec b/RollbarAUL.podspec index c7552930..fb41a9ab 100644 --- a/RollbarAUL.podspec +++ b/RollbarAUL.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarAUL" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC diff --git a/RollbarCommon.podspec b/RollbarCommon.podspec index d11d958c..1e34c20b 100644 --- a/RollbarCommon.podspec +++ b/RollbarCommon.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarCommon" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC diff --git a/RollbarDeploys.podspec b/RollbarDeploys.podspec index a75824d2..56df0257 100644 --- a/RollbarDeploys.podspec +++ b/RollbarDeploys.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarDeploys" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC diff --git a/RollbarKSCrash.podspec b/RollbarKSCrash.podspec index d78836aa..a4a52870 100644 --- a/RollbarKSCrash.podspec +++ b/RollbarKSCrash.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarKSCrash" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC diff --git a/RollbarNotifier.podspec b/RollbarNotifier.podspec index 1c38bf94..26ab0e65 100644 --- a/RollbarNotifier.podspec +++ b/RollbarNotifier.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarNotifier" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC diff --git a/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarConfig.m b/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarConfig.m index 0ddb117f..d6797b75 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarConfig.m +++ b/RollbarNotifier/Sources/RollbarNotifier/DTOs/RollbarConfig.m @@ -14,7 +14,7 @@ #pragma mark - constants -static NSString * const NOTIFIER_VERSION = @"2.0.3"; +static NSString * const NOTIFIER_VERSION = @"2.2.0"; static NSString * const NOTIFIER_NAME = @"rollbar-apple"; diff --git a/RollbarPLCrashReporter.podspec b/RollbarPLCrashReporter.podspec index 263d1334..dee1f8d8 100644 --- a/RollbarPLCrashReporter.podspec +++ b/RollbarPLCrashReporter.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarPLCrashReporter" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC diff --git a/RollbarSDK.experimental_podspec b/RollbarSDK.experimental_podspec index d61a9a4b..e859ecd6 100644 --- a/RollbarSDK.experimental_podspec +++ b/RollbarSDK.experimental_podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |sdk| # Rollbar SDK: # ============ - sdk.version = "2.0.3" + sdk.version = "2.2.0" sdk.name = "RollbarSDK" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." sdk.description = <<-DESC diff --git a/RollbarSwift.podspec b/RollbarSwift.podspec index 786dac9c..6d764b81 100644 --- a/RollbarSwift.podspec +++ b/RollbarSwift.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| - s.version = "2.0.3" + s.version = "2.2.0" s.name = "RollbarSwift" s.summary = "Application or client side SDK for interacting with the Rollbar API Server." s.description = <<-DESC From a194b84a1abab65dc8b1e77884731775ccd61193 Mon Sep 17 00:00:00 2001 From: Andrey Kornich Date: Mon, 18 Apr 2022 23:38:19 -0700 Subject: [PATCH 11/11] chore: code cleanup --- RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m | 4 ---- .../Sources/RollbarNotifier/RollbarTelemetryThread.m | 2 -- 2 files changed, 6 deletions(-) diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m index c3a613b1..9afe48b5 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarLogger.m @@ -114,10 +114,6 @@ + (void)initialize { RollbarConfig *config = [RollbarConfig new]; - // Setup the worker thread that atomatically collects pre-configured telemetry events (if any): - //[[RollbarTelemetryThread sharedInstance] configureWithOptions:config.telemetry]; - //[[RollbarTelemetryThread sharedInstance] start]; - // Setup the worker thread that sends the items that have been queued up in the item file set above: // TODO: !!! this needs to be redesigned taking in account multiple access tokens and endpoints !!! RollbarLogger *logger = [[RollbarLogger alloc] initWithConfiguration:config]; diff --git a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m index 27fe7260..26878a71 100644 --- a/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m +++ b/RollbarNotifier/Sources/RollbarNotifier/RollbarTelemetryThread.m @@ -25,7 +25,6 @@ + (nonnull instancetype)sharedInstance { dispatch_once(&onceToken, ^{ - //singleton = [[[self class] alloc] initWithTarget:singleton selector:@selector(run) object:nil]; singleton = [[self class] alloc]; if ((singleton = [singleton initWithTarget:singleton //self selector:@selector(run) @@ -94,7 +93,6 @@ - (BOOL)setupTimer { if (self->_timer && self->_timer.timeInterval == self->_collectionTimeInterval) { // nothing fundamental needs reconfiguration... - //return (nil != self->_timer); return !(0.0 == self->_timer.timeInterval); }