From febcbbb17753efffead87320a470936ff07ebbd8 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 7 Oct 2022 11:07:42 +0200 Subject: [PATCH 1/2] feat: Custom measurements API --- .../iOS-Swift/iOS-Swift/ViewController.swift | 7 ++ Sources/Sentry/Public/SentryDefines.h | 81 +++++++++++++ Sources/Sentry/Public/SentrySpanProtocol.h | 22 ++++ Sources/Sentry/SentryNoOpSpan.m | 26 +++++ Sources/Sentry/SentrySpan.m | 26 +++++ Sources/Sentry/SentryTracer.m | 106 ++++++++++++++++++ 6 files changed, 268 insertions(+) diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index e0f465e8bda..95718d60a17 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -141,6 +141,13 @@ class ViewController: UIViewController { @IBAction func captureTransaction(_ sender: Any) { let transaction = SentrySDK.startTransaction(name: "Some Transaction", operation: "Some Operation") + + transaction.setMeasurement(name: "custom", value: 44, customUnit: "custom-unit") + transaction.setMeasurement(name: "none", value: 55) + transaction.setMeasurement(name: "duration", value: 1.23, durationUnit: .milliSecond) + transaction.setMeasurement(name: "information", value: 134.3, informationUnit: .gigabyte) + transaction.setMeasurement(name: "fraction", value: 9.3, fractionUnit: .percent) + let span = transaction.startChild(operation: "user", description: "calls out") DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: { diff --git a/Sources/Sentry/Public/SentryDefines.h b/Sources/Sentry/Public/SentryDefines.h index 48a7698048e..2012fa3a160 100644 --- a/Sources/Sentry/Public/SentryDefines.h +++ b/Sources/Sentry/Public/SentryDefines.h @@ -142,3 +142,84 @@ typedef NS_ENUM(NSInteger, SentryTransactionNameSource) { kSentryTransactionNameSourceComponent, kSentryTransactionNameSourceTask }; + +/** + * A time duration. + */ +typedef NS_ENUM(NSInteger, SentryDurationUnit) { + /** Nanosecond (`"nanosecond"`), 10^-9 seconds. */ + kSentryDurationUnitNanoSecond = 0, + /** Microsecond (`"microsecond"`), 10^-6 seconds. */ + kSentryDurationUnitMicroSecond, + /** Millisecond (`"millisecond"`), 10^-3 seconds. */ + kSentryDurationUnitMilliSecond, + /** Full second (`"second"`). */ + kSentryDurationUnitSecond, + /** Minute (`"minute"`), 60 seconds. */ + kSentryDurationUnitMinute, + /** Hour (`"hour"`), 3600 seconds. */ + kSentryDurationUnitHour, + /** Day (`"day"`), 86,400 seconds. */ + kSentryDurationUnitDay, + /** Week (`"week"`), 604,800 seconds. */ + kSentryDurationUnitWeek +} NS_SWIFT_NAME(DurationUnit); + +/** + * Size of information derived from bytes. + */ +typedef NS_ENUM(NSInteger, SentryInformationUnit) { + /** Bit (`"bit"`), corresponding to 1/8 of a byte. */ + kSentryInformationUnitBit, + + /** Byte (`"byte"`). */ + kSentryInformationUnitByte, + + /** Kilobyte (`"kilobyte"`), 10^3 bytes. */ + kSentryInformationUnitKilobyte, + + /** Kibibyte (`"kibibyte"`), 2^10 bytes. */ + kSentryInformationUnitKibibyte, + + /** Megabyte (`"megabyte"`), 10^6 bytes. */ + kSentryInformationUnitMegabyte, + + /** Mebibyte (`"mebibyte"`), 2^20 bytes. */ + kSentryInformationUnitMebibyte, + + /** Gigabyte (`"gigabyte"`), 10^9 bytes. */ + kSentryInformationUnitGigabyte, + + /** Gibibyte (`"gibibyte"`), 2^30 bytes. */ + kSentryInformationUnitGibibyte, + + /** Terabyte (`"terabyte"`), 10^12 bytes. */ + kSentryInformationUnitTerabyte, + + /** Tebibyte (`"tebibyte"`), 2^40 bytes. */ + kSentryInformationUnitTebibyte, + + /** Petabyte (`"petabyte"`), 10^15 bytes. */ + kSentryInformationUnitPetabyte, + + /** Pebibyte (`"pebibyte"`), 2^50 bytes. */ + kSentryInformationUnitPebibyte, + + /** Exabyte (`"exabyte"`), 10^18 bytes. */ + kSentryInformationUnitExabyte, + + /** Exbibyte (`"exbibyte"`), 2^60 bytes. */ + kSentryInformationUnitExbibyte +} NS_SWIFT_NAME(InformationUnit); + +/** + * Fractions such as percentages. + */ +typedef NS_ENUM(NSInteger, SentryFractionUnit) { + + /** Floating point fraction of `1`. */ + kSentryFractionUnitRatio = 0, + + /** Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. */ + kSentryFractionUnitPercent +} NS_SWIFT_NAME(FractionUnit); diff --git a/Sources/Sentry/Public/SentrySpanProtocol.h b/Sources/Sentry/Public/SentrySpanProtocol.h index 4fbc1abf50f..99c7fea58a2 100644 --- a/Sources/Sentry/Public/SentrySpanProtocol.h +++ b/Sources/Sentry/Public/SentrySpanProtocol.h @@ -87,6 +87,28 @@ NS_SWIFT_NAME(Span) */ - (void)removeTagForKey:(NSString *)key NS_SWIFT_NAME(removeTag(key:)); +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value NS_SWIFT_NAME(setMeasurement(name:value:)); + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + durationUnit:(SentryDurationUnit)durationUnit + NS_SWIFT_NAME(setMeasurement(name:value:durationUnit:)); + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + informationUnit:(SentryInformationUnit)informationUnit + NS_SWIFT_NAME(setMeasurement(name:value:informationUnit:)); + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + fractionUnit:(SentryFractionUnit)fractionUnit + NS_SWIFT_NAME(setMeasurement(name:value:fractionUnit:)); + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + customUnit:(NSString *)customUnit NS_SWIFT_NAME(setMeasurement(name:value:customUnit:)); + /** * Finishes the span by setting the end time. */ diff --git a/Sources/Sentry/SentryNoOpSpan.m b/Sources/Sentry/SentryNoOpSpan.m index 0ad045b7596..77ddd42bc0a 100644 --- a/Sources/Sentry/SentryNoOpSpan.m +++ b/Sources/Sentry/SentryNoOpSpan.m @@ -64,6 +64,32 @@ - (void)removeTagForKey:(NSString *)key { } +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +{ +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + durationUnit:(SentryDurationUnit)durationUnit +{ +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + informationUnit:(SentryInformationUnit)informationUnit +{ +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + fractionUnit:(SentryFractionUnit)fractionUnit +{ +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value customUnit:(NSString *)customUnit +{ +} + - (NSDictionary *)tags { return @{}; diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index 2dab3697943..06104e901be 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -89,6 +89,32 @@ - (void)removeTagForKey:(NSString *)key } } +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +{ +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + durationUnit:(SentryDurationUnit)durationUnit +{ +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + informationUnit:(SentryInformationUnit)informationUnit +{ +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + fractionUnit:(SentryFractionUnit)fractionUnit +{ +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value customUnit:(NSString *)customUnit +{ +} + - (NSDictionary *)tags { @synchronized(_tags) { diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 167363dc263..c212d123c22 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -61,6 +61,7 @@ @implementation SentryTracer { SentryAppStartMeasurement *appStartMeasurement; NSMutableDictionary *_tags; NSMutableDictionary *_data; + NSMutableDictionary *_measurements; dispatch_block_t _idleTimeoutBlock; NSMutableArray> *_children; @@ -160,6 +161,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti _waitForChildren = waitForChildren; _tags = [[NSMutableDictionary alloc] init]; _data = [[NSMutableDictionary alloc] init]; + _measurements = [[NSMutableDictionary alloc] init]; self.finishStatus = kSentrySpanStatusUndefined; self.idleTimeout = idleTimeout; self.dispatchQueueWrapper = dispatchQueueWrapper; @@ -395,6 +397,106 @@ - (void)removeTagForKey:(NSString *)key } } +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +{ + _measurements[name] = @{ @"value" : value, @"unit" : @"none" }; +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + durationUnit:(SentryDurationUnit)durationUnit +{ + _measurements[name] = + @{ @"value" : value, @"unit" : [self stringForDurationUnit:durationUnit] }; +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + informationUnit:(SentryInformationUnit)informationUnit +{ + _measurements[name] = + @{ @"value" : value, @"unit" : [self stringForInformationUnit:informationUnit] }; +} + +- (void)setMeasurement:(NSString *)name + value:(NSNumber *)value + fractionUnit:(SentryFractionUnit)fractionUnit +{ + _measurements[name] = + @{ @"value" : value, @"unit" : [self stringForFractionUnit:fractionUnit] }; +} + +- (void)setMeasurement:(NSString *)name value:(NSNumber *)value customUnit:(NSString *)customUnit +{ + _measurements[name] = @{ @"value" : value, @"unit" : customUnit }; +} + +- (NSString *)stringForDurationUnit:(SentryDurationUnit)duration +{ + switch (duration) { + case kSentryDurationUnitNanoSecond: + return @"nanosecond"; + case kSentryDurationUnitMicroSecond: + return @"microsecond"; + case kSentryDurationUnitMilliSecond: + return @"millisecond"; + case kSentryDurationUnitSecond: + return @"second"; + case kSentryDurationUnitMinute: + return @"minute"; + case kSentryDurationUnitHour: + return @"hour"; + case kSentryDurationUnitDay: + return @"day"; + case kSentryDurationUnitWeek: + return @"week"; + } +} + +- (NSString *)stringForInformationUnit:(SentryInformationUnit)informationUnit +{ + switch (informationUnit) { + case kSentryInformationUnitBit: + return @"bit"; + case kSentryInformationUnitByte: + return @"byte"; + case kSentryInformationUnitKilobyte: + return @"kilobyte"; + case kSentryInformationUnitKibibyte: + return @"kibibyte"; + case kSentryInformationUnitMegabyte: + return @"megabyte"; + case kSentryInformationUnitMebibyte: + return @"mebibyte"; + case kSentryInformationUnitGigabyte: + return @"gigabyte"; + case kSentryInformationUnitGibibyte: + return @"gibibyte"; + case kSentryInformationUnitTerabyte: + return @"terabyte"; + case kSentryInformationUnitTebibyte: + return @"tebibyte"; + case kSentryInformationUnitPetabyte: + return @"petabyte"; + case kSentryInformationUnitPebibyte: + return @"pebibyte"; + case kSentryInformationUnitExabyte: + return @"exabyte"; + case kSentryInformationUnitExbibyte: + return @"exbibyte"; + } +} + +- (NSString *)stringForFractionUnit:(SentryFractionUnit)fraction +{ + switch (fraction) { + case kSentryFractionUnitRatio: + return @"ratio"; + case kSentryFractionUnitPercent: + return @"percent"; + } +} + - (SentryTraceHeader *)toTraceHeader { return [self.rootSpan toTraceHeader]; @@ -727,6 +829,10 @@ - (void)addMeasurements:(SentryTransaction *)transaction } } #endif + + for (NSString *key in _measurements) { + [transaction setMeasurementValue:_measurements[key] forKey:key]; + } } - (id)buildSpan:(SentrySpanId *)parentId From 4ae6b3fba70002eeaa827e7659bdefc1e9397ee8 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Mon, 10 Oct 2022 11:45:16 +0200 Subject: [PATCH 2/2] Make API similar to NSMEasurement --- .../iOS-Swift/iOS-Swift/ViewController.swift | 7 +- Sentry.xcodeproj/project.pbxproj | 16 +++ Sources/Sentry/Public/Sentry.h | 2 + Sources/Sentry/Public/SentryMeasurement.h | 18 +++ Sources/Sentry/Public/SentryOptions.h | 4 +- Sources/Sentry/Public/SentrySpanProtocol.h | 24 +--- Sources/Sentry/Public/SentryUnit.h | 47 ++++++++ Sources/Sentry/SentryMeasurement.m | 24 ++++ Sources/Sentry/SentryNoOpSpan.m | 24 +--- Sources/Sentry/SentryOptions.m | 4 + Sources/Sentry/SentrySpan.m | 25 +--- Sources/Sentry/SentryTracer.m | 110 ++---------------- Sources/Sentry/SentryUnit.m | 54 +++++++++ 13 files changed, 184 insertions(+), 175 deletions(-) create mode 100644 Sources/Sentry/Public/SentryMeasurement.h create mode 100644 Sources/Sentry/Public/SentryUnit.h create mode 100644 Sources/Sentry/SentryMeasurement.m create mode 100644 Sources/Sentry/SentryUnit.m diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index 95718d60a17..632a9d36a08 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -142,11 +142,8 @@ class ViewController: UIViewController { @IBAction func captureTransaction(_ sender: Any) { let transaction = SentrySDK.startTransaction(name: "Some Transaction", operation: "Some Operation") - transaction.setMeasurement(name: "custom", value: 44, customUnit: "custom-unit") - transaction.setMeasurement(name: "none", value: 55) - transaction.setMeasurement(name: "duration", value: 1.23, durationUnit: .milliSecond) - transaction.setMeasurement(name: "information", value: 134.3, informationUnit: .gigabyte) - transaction.setMeasurement(name: "fraction", value: 9.3, fractionUnit: .percent) + transaction.setMeasurement(SentryMeasurement(name: "duration", value: 44, unit: SentryUnitDuration.nanoseconds)) + transaction.setMeasurement(SentryMeasurement(name: "duration-custom", value: 22, unit: SentryUnit(symbol: "custom"))) let span = transaction.startChild(operation: "user", description: "calls out") diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 51b3821838b..2d35832bcd6 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -492,6 +492,10 @@ 7BC8523724588115005A70F0 /* SentryDataCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC8523624588115005A70F0 /* SentryDataCategory.h */; }; 7BC852392458830A005A70F0 /* SentryEnvelopeItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7BC8523B2458849E005A70F0 /* SentryDataCategoryMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC8523A2458849E005A70F0 /* SentryDataCategoryMapperTests.swift */; }; + 7BC9A20028F41016001E7C4C /* SentryMeasurement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC9A1FF28F41016001E7C4C /* SentryMeasurement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BC9A20228F41350001E7C4C /* SentryUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC9A20128F41350001E7C4C /* SentryUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BC9A20428F4166D001E7C4C /* SentryMeasurement.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC9A20328F4166D001E7C4C /* SentryMeasurement.m */; }; + 7BC9A20628F41781001E7C4C /* SentryUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC9A20528F41781001E7C4C /* SentryUnit.m */; }; 7BCFA71627D0BB50008C662C /* SentryANRTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BCFA71527D0BB50008C662C /* SentryANRTracker.m */; }; 7BCFBD672681C95000BC27D8 /* SentryScopeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BCFBD662681C95000BC27D8 /* SentryScopeObserver.h */; }; 7BCFBD6D2681D0A900BC27D8 /* SentryCrashScopeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BCFBD6C2681D0A900BC27D8 /* SentryCrashScopeObserver.h */; }; @@ -1224,6 +1228,10 @@ 7BC8523624588115005A70F0 /* SentryDataCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDataCategory.h; path = include/SentryDataCategory.h; sourceTree = ""; }; 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeItemType.h; path = Public/SentryEnvelopeItemType.h; sourceTree = ""; }; 7BC8523A2458849E005A70F0 /* SentryDataCategoryMapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryDataCategoryMapperTests.swift; sourceTree = ""; }; + 7BC9A1FF28F41016001E7C4C /* SentryMeasurement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryMeasurement.h; path = Public/SentryMeasurement.h; sourceTree = ""; }; + 7BC9A20128F41350001E7C4C /* SentryUnit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryUnit.h; path = Public/SentryUnit.h; sourceTree = ""; }; + 7BC9A20328F4166D001E7C4C /* SentryMeasurement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryMeasurement.m; sourceTree = ""; }; + 7BC9A20528F41781001E7C4C /* SentryUnit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryUnit.m; sourceTree = ""; }; 7BC9CD4326A99F660047518E /* SentryUIViewControllerSwizzling+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryUIViewControllerSwizzling+Test.h"; sourceTree = ""; }; 7BCFA71427D0BAB7008C662C /* SentryANRTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryANRTracker.h; path = include/SentryANRTracker.h; sourceTree = ""; }; 7BCFA71527D0BB50008C662C /* SentryANRTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryANRTracker.m; sourceTree = ""; }; @@ -1612,6 +1620,10 @@ 7BD4BD4427EB29F50071F4FF /* SentryClientReport.m */, 7BD4BD4627EB2A3D0071F4FF /* SentryDiscardedEvent.h */, 7BD4BD4827EB2A5D0071F4FF /* SentryDiscardedEvent.m */, + 7BC9A1FF28F41016001E7C4C /* SentryMeasurement.h */, + 7BC9A20328F4166D001E7C4C /* SentryMeasurement.m */, + 7BC9A20128F41350001E7C4C /* SentryUnit.h */, + 7BC9A20528F41781001E7C4C /* SentryUnit.m */, ); name = Protocol; sourceTree = ""; @@ -2895,6 +2907,7 @@ 0A2D8DA8289BC905008720F6 /* SentryViewHierarchy.h in Headers */, 8EAE980C261E9F530073B6B3 /* SentryUIViewControllerPerformanceTracker.h in Headers */, 63FE717D20DA4C1100CDBAE8 /* SentryCrashCachedData.h in Headers */, + 7BC9A20028F41016001E7C4C /* SentryMeasurement.h in Headers */, 7BBC826D25DFCFDE005F1ED8 /* SentryInAppLogic.h in Headers */, 03BCC38A27E1BF49003232C7 /* SentryTime.h in Headers */, 7B0A54222521C21E00A71716 /* SentryFrameRemover.h in Headers */, @@ -2987,6 +3000,7 @@ 7DC27EC523997EB7006998B5 /* SentryAutoBreadcrumbTrackingIntegration.h in Headers */, 63FE707F20DA4C1000CDBAE8 /* SentryCrashVarArgs.h in Headers */, 03F84D2627DD414C008FE43F /* SentryThreadMetadataCache.hpp in Headers */, + 7BC9A20228F41350001E7C4C /* SentryUnit.h in Headers */, 7BB654FB253DC14A00887E87 /* SentryUserFeedback.h in Headers */, 7B8ECBFA26498907005FE2EF /* SentryAppStateManager.h in Headers */, 639FCFA01EBC804600778193 /* SentryException.h in Headers */, @@ -3414,6 +3428,7 @@ 8EAE9806261E87120073B6B3 /* SentryUIViewControllerPerformanceTracker.m in Sources */, D88817D826D7149100BF2251 /* SentryTraceContext.m in Sources */, 8EBF870926140D37001A6853 /* SentryPerformanceTracker.m in Sources */, + 7BC9A20428F4166D001E7C4C /* SentryMeasurement.m in Sources */, D859696B27BECD8F0036A46E /* SentryCoreDataTrackingIntegration.m in Sources */, 7BD86EC7264A641D005439DB /* SentrySysctl.m in Sources */, D859697327BECDD20036A46E /* SentryCoreDataSwizzling.m in Sources */, @@ -3430,6 +3445,7 @@ 0356A571288B4612008BF593 /* SentryProfilesSampler.m in Sources */, 63FE710B20DA4C1000CDBAE8 /* SentryCrashMach.c in Sources */, 63FE707720DA4C1000CDBAE8 /* Container+SentryDeepSearch.m in Sources */, + 7BC9A20628F41781001E7C4C /* SentryUnit.m in Sources */, 63FE71A020DA4C1100CDBAE8 /* SentryCrashInstallation.m in Sources */, 63FE713520DA4C1100CDBAE8 /* SentryCrashMemory.c in Sources */, 63FE714520DA4C1100CDBAE8 /* SentryCrashObjC.c in Sources */, diff --git a/Sources/Sentry/Public/Sentry.h b/Sources/Sentry/Public/Sentry.h index 8fb98787446..88391a59285 100644 --- a/Sources/Sentry/Public/Sentry.h +++ b/Sources/Sentry/Public/Sentry.h @@ -25,6 +25,7 @@ FOUNDATION_EXPORT const unsigned char SentryVersionString[]; #import "SentryHub.h" #import "SentryId.h" #import "SentryIntegrationProtocol.h" +#import "SentryMeasurement.h" #import "SentryMechanism.h" #import "SentryMechanismMeta.h" #import "SentryMessage.h" @@ -46,5 +47,6 @@ FOUNDATION_EXPORT const unsigned char SentryVersionString[]; #import "SentryThread.h" #import "SentryTraceHeader.h" #import "SentryTransactionContext.h" +#import "SentryUnit.h" #import "SentryUser.h" #import "SentryUserFeedback.h" diff --git a/Sources/Sentry/Public/SentryMeasurement.h b/Sources/Sentry/Public/SentryMeasurement.h new file mode 100644 index 00000000000..56a59b262b6 --- /dev/null +++ b/Sources/Sentry/Public/SentryMeasurement.h @@ -0,0 +1,18 @@ +#import "SentryDefines.h" +#import "SentrySerializable.h" +#import "SentryUnit.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryMeasurement : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithName:(NSString *)name value:(NSNumber *)value unit:(UnitType)unit; + +@property (nonatomic, copy, readonly) NSString *name; +@property (nonatomic, copy, readonly) NSNumber *value; +@property (readonly, copy) UnitType unit; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h index fec00739085..109478fafa7 100644 --- a/Sources/Sentry/Public/SentryOptions.h +++ b/Sources/Sentry/Public/SentryOptions.h @@ -3,7 +3,7 @@ NS_ASSUME_NONNULL_BEGIN -@class SentryDsn, SentrySdkInfo; +@class SentryDsn, SentrySdkInfo, SentryMeasurement; NS_SWIFT_NAME(Options) @interface SentryOptions : NSObject @@ -196,6 +196,8 @@ NS_SWIFT_NAME(Options) */ @property (nonatomic, assign) BOOL enableAutoPerformanceTracking; +- (void)setMeasurement:(SentryMeasurement *)measurement; + #if SENTRY_HAS_UIKIT /** * When enabled, the SDK tracks performance for UIViewController subclasses. The default is diff --git a/Sources/Sentry/Public/SentrySpanProtocol.h b/Sources/Sentry/Public/SentrySpanProtocol.h index 99c7fea58a2..67f3c856190 100644 --- a/Sources/Sentry/Public/SentrySpanProtocol.h +++ b/Sources/Sentry/Public/SentrySpanProtocol.h @@ -4,7 +4,7 @@ NS_ASSUME_NONNULL_BEGIN -@class SentrySpanId, SentryId, SentryTraceHeader; +@class SentrySpanId, SentryId, SentryTraceHeader, SentryMeasurement; NS_SWIFT_NAME(Span) @protocol SentrySpan @@ -87,27 +87,7 @@ NS_SWIFT_NAME(Span) */ - (void)removeTagForKey:(NSString *)key NS_SWIFT_NAME(removeTag(key:)); -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value NS_SWIFT_NAME(setMeasurement(name:value:)); - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - durationUnit:(SentryDurationUnit)durationUnit - NS_SWIFT_NAME(setMeasurement(name:value:durationUnit:)); - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - informationUnit:(SentryInformationUnit)informationUnit - NS_SWIFT_NAME(setMeasurement(name:value:informationUnit:)); - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - fractionUnit:(SentryFractionUnit)fractionUnit - NS_SWIFT_NAME(setMeasurement(name:value:fractionUnit:)); - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - customUnit:(NSString *)customUnit NS_SWIFT_NAME(setMeasurement(name:value:customUnit:)); +- (void)setMeasurement:(SentryMeasurement *)measurement; /** * Finishes the span by setting the end time. diff --git a/Sources/Sentry/Public/SentryUnit.h b/Sources/Sentry/Public/SentryUnit.h new file mode 100644 index 00000000000..d8ad32fb4fc --- /dev/null +++ b/Sources/Sentry/Public/SentryUnit.h @@ -0,0 +1,47 @@ +#import "SentryDefines.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SentryUnit : NSObject +SENTRY_NO_INIT + +- (instancetype)initWithSymbol:(NSString *)symbol; + +@property (readonly, copy) NSString *symbol; + +@end + +@interface SentryUnitDuration : SentryUnit +SENTRY_NO_INIT + +/** Nanosecond (`"nanosecond"`), 10^-9 seconds. */ +@property (class, readonly, copy) SentryUnitDuration *nanoseconds; + +// ... + +@end + +@interface SentryUnitInformation : SentryUnit +SENTRY_NO_INIT + +/** Bit (`"bit"`), corresponding to 1/8 of a byte. */ +@property (class, readonly, copy) SentryUnitInformation *bit; + +// ... + +@end + +@interface SentryUnitFraction : SentryUnit +SENTRY_NO_INIT + +/** Floating point fraction of `1`. */ +@property (class, readonly, copy) SentryUnitFraction *ratio; + +/** Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. */ +@property (class, readonly, copy) SentryUnitFraction *percent; + +// ... + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryMeasurement.m b/Sources/Sentry/SentryMeasurement.m new file mode 100644 index 00000000000..2012becba5c --- /dev/null +++ b/Sources/Sentry/SentryMeasurement.m @@ -0,0 +1,24 @@ +#import "SentryMeasurement.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryMeasurement + +- (instancetype)initWithName:(NSString *)name value:(NSNumber *)value unit:(SentryUnit *)unit +{ + if (self = [super init]) { + _name = name; + _value = value; + _unit = unit; + } + return self; +} + +- (NSDictionary *)serialize +{ + return @{ @"name" : self.name, @"value" : self.value, @"unit" : self.unit.symbol }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryNoOpSpan.m b/Sources/Sentry/SentryNoOpSpan.m index 77ddd42bc0a..b30c7e8db01 100644 --- a/Sources/Sentry/SentryNoOpSpan.m +++ b/Sources/Sentry/SentryNoOpSpan.m @@ -64,29 +64,7 @@ - (void)removeTagForKey:(NSString *)key { } -- (void)setMeasurement:(NSString *)name value:(NSNumber *)value -{ -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - durationUnit:(SentryDurationUnit)durationUnit -{ -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - informationUnit:(SentryInformationUnit)informationUnit -{ -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - fractionUnit:(SentryFractionUnit)fractionUnit -{ -} - -- (void)setMeasurement:(NSString *)name value:(NSNumber *)value customUnit:(NSString *)customUnit +- (void)setMeasurement:(SentryMeasurement *)measurement { } diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m index 150b7f440a6..02fac2d4729 100644 --- a/Sources/Sentry/SentryOptions.m +++ b/Sources/Sentry/SentryOptions.m @@ -20,6 +20,10 @@ @implementation SentryOptions +- (void)setMeasurement:(SentryMeasurement *)measurement +{ +} + + (NSArray *)defaultIntegrations { return @[ diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index 06104e901be..11037db7ebe 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -3,6 +3,7 @@ #import "NSDictionary+SentrySanitize.h" #import "SentryCurrentDate.h" #import "SentryLog.h" +#import "SentryMeasurement.h" #import "SentryNoOpSpan.h" #import "SentryTraceHeader.h" #import "SentryTracer.h" @@ -89,29 +90,7 @@ - (void)removeTagForKey:(NSString *)key } } -- (void)setMeasurement:(NSString *)name value:(NSNumber *)value -{ -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - durationUnit:(SentryDurationUnit)durationUnit -{ -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - informationUnit:(SentryInformationUnit)informationUnit -{ -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - fractionUnit:(SentryFractionUnit)fractionUnit -{ -} - -- (void)setMeasurement:(NSString *)name value:(NSNumber *)value customUnit:(NSString *)customUnit +- (void)setMeasurement:(SentryMeasurement *)measurement { } diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index c212d123c22..aae0aeb37a1 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -22,6 +22,7 @@ #import "SentryTransactionContext.h" #import "SentryUIViewControllerPerformanceTracker.h" #import +#import #import #import @@ -61,7 +62,7 @@ @implementation SentryTracer { SentryAppStartMeasurement *appStartMeasurement; NSMutableDictionary *_tags; NSMutableDictionary *_data; - NSMutableDictionary *_measurements; + NSMutableArray *_measurements; dispatch_block_t _idleTimeoutBlock; NSMutableArray> *_children; @@ -161,7 +162,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti _waitForChildren = waitForChildren; _tags = [[NSMutableDictionary alloc] init]; _data = [[NSMutableDictionary alloc] init]; - _measurements = [[NSMutableDictionary alloc] init]; + _measurements = [[NSMutableArray alloc] init]; self.finishStatus = kSentrySpanStatusUndefined; self.idleTimeout = idleTimeout; self.dispatchQueueWrapper = dispatchQueueWrapper; @@ -397,104 +398,9 @@ - (void)removeTagForKey:(NSString *)key } } -- (void)setMeasurement:(NSString *)name value:(NSNumber *)value +- (void)setMeasurement:(SentryMeasurement *)measurement { - _measurements[name] = @{ @"value" : value, @"unit" : @"none" }; -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - durationUnit:(SentryDurationUnit)durationUnit -{ - _measurements[name] = - @{ @"value" : value, @"unit" : [self stringForDurationUnit:durationUnit] }; -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - informationUnit:(SentryInformationUnit)informationUnit -{ - _measurements[name] = - @{ @"value" : value, @"unit" : [self stringForInformationUnit:informationUnit] }; -} - -- (void)setMeasurement:(NSString *)name - value:(NSNumber *)value - fractionUnit:(SentryFractionUnit)fractionUnit -{ - _measurements[name] = - @{ @"value" : value, @"unit" : [self stringForFractionUnit:fractionUnit] }; -} - -- (void)setMeasurement:(NSString *)name value:(NSNumber *)value customUnit:(NSString *)customUnit -{ - _measurements[name] = @{ @"value" : value, @"unit" : customUnit }; -} - -- (NSString *)stringForDurationUnit:(SentryDurationUnit)duration -{ - switch (duration) { - case kSentryDurationUnitNanoSecond: - return @"nanosecond"; - case kSentryDurationUnitMicroSecond: - return @"microsecond"; - case kSentryDurationUnitMilliSecond: - return @"millisecond"; - case kSentryDurationUnitSecond: - return @"second"; - case kSentryDurationUnitMinute: - return @"minute"; - case kSentryDurationUnitHour: - return @"hour"; - case kSentryDurationUnitDay: - return @"day"; - case kSentryDurationUnitWeek: - return @"week"; - } -} - -- (NSString *)stringForInformationUnit:(SentryInformationUnit)informationUnit -{ - switch (informationUnit) { - case kSentryInformationUnitBit: - return @"bit"; - case kSentryInformationUnitByte: - return @"byte"; - case kSentryInformationUnitKilobyte: - return @"kilobyte"; - case kSentryInformationUnitKibibyte: - return @"kibibyte"; - case kSentryInformationUnitMegabyte: - return @"megabyte"; - case kSentryInformationUnitMebibyte: - return @"mebibyte"; - case kSentryInformationUnitGigabyte: - return @"gigabyte"; - case kSentryInformationUnitGibibyte: - return @"gibibyte"; - case kSentryInformationUnitTerabyte: - return @"terabyte"; - case kSentryInformationUnitTebibyte: - return @"tebibyte"; - case kSentryInformationUnitPetabyte: - return @"petabyte"; - case kSentryInformationUnitPebibyte: - return @"pebibyte"; - case kSentryInformationUnitExabyte: - return @"exabyte"; - case kSentryInformationUnitExbibyte: - return @"exbibyte"; - } -} - -- (NSString *)stringForFractionUnit:(SentryFractionUnit)fraction -{ - switch (fraction) { - case kSentryFractionUnitRatio: - return @"ratio"; - case kSentryFractionUnitPercent: - return @"percent"; - } + [_measurements addObject:measurement]; } - (SentryTraceHeader *)toTraceHeader @@ -830,8 +736,10 @@ - (void)addMeasurements:(SentryTransaction *)transaction } #endif - for (NSString *key in _measurements) { - [transaction setMeasurementValue:_measurements[key] forKey:key]; + for (SentryMeasurement *measurement in _measurements) { + [transaction + setMeasurementValue:@{ @"value" : measurement.value, @"unit" : measurement.unit.symbol } + forKey:measurement.name]; } } diff --git a/Sources/Sentry/SentryUnit.m b/Sources/Sentry/SentryUnit.m new file mode 100644 index 00000000000..4912d91c61e --- /dev/null +++ b/Sources/Sentry/SentryUnit.m @@ -0,0 +1,54 @@ +#import "SentryUnit.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SentryUnit + +- (instancetype)initWithSymbol:(NSString *)symbol +{ + if (self = [super init]) { + _symbol = symbol; + } + return self; +} + +- (id)copyWithZone:(nullable NSZone *)zone +{ + return [[[self class] allocWithZone:zone] initWithSymbol:self.symbol]; +} + +@end + +@implementation SentryUnitDuration + ++ (SentryUnitDuration *)nanoseconds +{ + return [[SentryUnitDuration alloc] initWithSymbol:@"nanoseconds"]; +} + +@end + +@implementation SentryUnitInformation + ++ (SentryUnitDuration *)bit +{ + return [[SentryUnitDuration alloc] initWithSymbol:@"bit"]; +} + +@end + +@implementation SentryUnitFraction + ++ (SentryUnitFraction *)ratio +{ + return [[SentryUnitFraction alloc] initWithSymbol:@"ratio"]; +} + ++ (SentryUnitFraction *)percent +{ + return [[SentryUnitFraction alloc] initWithSymbol:@"percent"]; +} + +@end + +NS_ASSUME_NONNULL_END