Skip to content

Commit

Permalink
Merge branch 'main' into philprime/introduction-xctestplan
Browse files Browse the repository at this point in the history
  • Loading branch information
philprime authored Feb 19, 2025
2 parents df947af + d33f2c8 commit e757311
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 105 deletions.
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ GEM
mime-types-data (3.2023.1003)
mini_magick (4.13.2)
mini_mime (1.1.5)
mini_portile2 (2.8.7)
mini_portile2 (2.8.8)
minitest (5.25.1)
molinillo (0.8.0)
multi_json (1.15.0)
Expand All @@ -242,7 +242,7 @@ GEM
naturally (2.2.1)
netrc (0.11.0)
nkf (0.2.0)
nokogiri (1.16.7)
nokogiri (1.18.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
optparse (0.5.0)
Expand Down
8 changes: 8 additions & 0 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,8 @@
A8F17B2E2901765900990B25 /* SentryRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B2D2901765900990B25 /* SentryRequest.m */; };
A8F17B342902870300990B25 /* SentryHttpStatusCodeRange.m in Sources */ = {isa = PBXBuildFile; fileRef = A8F17B332902870300990B25 /* SentryHttpStatusCodeRange.m */; };
D42E48572D48DF1600D251BC /* SentryBuildAppStartSpansTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D42E48562D48DF1600D251BC /* SentryBuildAppStartSpansTests.swift */; };
D43647EF2D5CF9E3001468E0 /* SentrySpanDataKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43647EE2D5CF9DC001468E0 /* SentrySpanDataKey.swift */; };
D43647F12D5CFB71001468E0 /* SentrySpanKeyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43647F02D5CFB71001468E0 /* SentrySpanKeyTests.swift */; };
D48724DB2D352597005DE483 /* SentryTraceOrigin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */; };
D48724DD2D354939005DE483 /* SentrySpanOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DC2D354934005DE483 /* SentrySpanOperation.swift */; };
D48724E02D3549CA005DE483 /* SentrySpanOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */; };
Expand Down Expand Up @@ -1958,6 +1960,8 @@
D46D45E82D5F40FA00A1CB35 /* SentryProfilerTests_Base.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = SentryProfilerTests_Base.xctestplan; path = Plans/SentryProfilerTests_Base.xctestplan; sourceTree = SOURCE_ROOT; };
D46D45E92D5F411700A1CB35 /* SentrySwiftUI_Base.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = SentrySwiftUI_Base.xctestplan; path = Plans/SentrySwiftUI_Base.xctestplan; sourceTree = SOURCE_ROOT; };
D46D45EA2D5F412100A1CB35 /* SentryTests_Base.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = SentryTests_Base.xctestplan; path = Plans/SentryTests_Base.xctestplan; sourceTree = SOURCE_ROOT; };
D43647EE2D5CF9DC001468E0 /* SentrySpanDataKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanDataKey.swift; sourceTree = "<group>"; };
D43647F02D5CFB71001468E0 /* SentrySpanKeyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentrySpanKeyTests.swift; sourceTree = "<group>"; };
D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTraceOrigin.swift; sourceTree = "<group>"; };
D48724DC2D354934005DE483 /* SentrySpanOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperation.swift; sourceTree = "<group>"; };
D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySpanOperationTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3827,6 +3831,7 @@
children = (
D48724DA2D352591005DE483 /* SentryTraceOrigin.swift */,
D48724DC2D354934005DE483 /* SentrySpanOperation.swift */,
D43647EE2D5CF9DC001468E0 /* SentrySpanDataKey.swift */,
);
path = Transactions;
sourceTree = "<group>";
Expand All @@ -3836,6 +3841,7 @@
children = (
D48724E12D354D16005DE483 /* SentryTraceOriginTests.swift */,
D48724DF2D3549C6005DE483 /* SentrySpanOperationTests.swift */,
D43647F02D5CFB71001468E0 /* SentrySpanKeyTests.swift */,
);
path = Transactions;
sourceTree = "<group>";
Expand Down Expand Up @@ -4999,6 +5005,7 @@
D82859432C3E753C009A28AA /* SentrySessionReplaySyncC.c in Sources */,
D833D57C2D10784800961E7A /* SentryRRWebOptionsEvent.swift in Sources */,
84A8891D28DBD28900C51DFD /* SentryDevice.mm in Sources */,
D43647EF2D5CF9E3001468E0 /* SentrySpanDataKey.swift in Sources */,
7B56D73324616D9500B842DA /* SentryConcurrentRateLimitsDictionary.m in Sources */,
8ECC674825C23A20000E2BF6 /* SentryTransaction.m in Sources */,
0A80E433291017C300095219 /* SentryWatchdogTerminationScopeObserver.m in Sources */,
Expand Down Expand Up @@ -5434,6 +5441,7 @@
7BF9EF7A2722B58900B5BBEF /* SentrySubClassFinderTests.swift in Sources */,
D48724E02D3549CA005DE483 /* SentrySpanOperationTests.swift in Sources */,
7B59398224AB47650003AAD2 /* SentrySessionTrackerTests.swift in Sources */,
D43647F12D5CFB71001468E0 /* SentrySpanKeyTests.swift in Sources */,
7B05A61824A4D14A00EF211D /* SentrySessionGeneratorTests.swift in Sources */,
D8CB742B294B1DD000A5F964 /* SentryUIApplicationTests.swift in Sources */,
63FE720920DA66EC00CDBAE8 /* XCTestCase+SentryCrash.m in Sources */,
Expand Down
53 changes: 37 additions & 16 deletions Sources/Sentry/SentryFileIOTracker.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ - (void)disable
- (BOOL)measureNSData:(NSData *)data
writeToFile:(NSString *)path
atomically:(BOOL)useAuxiliaryFile
origin:(NSString *)origin
method:(BOOL (^)(NSString *, BOOL))method
{
id<SentrySpan> span = [self startTrackingWritingNSData:data filePath:path];
id<SentrySpan> span = [self startTrackingWritingNSData:data filePath:path origin:origin];

BOOL result = method(path, useAuxiliaryFile);

Expand All @@ -74,10 +75,11 @@ - (BOOL)measureNSData:(NSData *)data
- (BOOL)measureNSData:(NSData *)data
writeToFile:(NSString *)path
options:(NSDataWritingOptions)writeOptionsMask
origin:(NSString *)origin
error:(NSError **)error
method:(BOOL (^)(NSString *, NSDataWritingOptions, NSError **))method
{
id<SentrySpan> span = [self startTrackingWritingNSData:data filePath:path];
id<SentrySpan> span = [self startTrackingWritingNSData:data filePath:path origin:origin];

BOOL result = method(path, writeOptionsMask, error);

Expand All @@ -88,9 +90,13 @@ - (BOOL)measureNSData:(NSData *)data
return result;
}

- (NSData *)measureNSDataFromFile:(NSString *)path method:(NSData * (^)(NSString *))method
- (NSData *)measureNSDataFromFile:(NSString *)path
origin:(NSString *)origin
method:(NSData * (^)(NSString *))method
{
id<SentrySpan> span = [self startTrackingReadingFilePath:path];
id<SentrySpan> span = [self startTrackingReadingFilePath:path
origin:origin
operation:SentrySpanOperation.fileRead];

NSData *result = method(path);

Expand All @@ -104,10 +110,13 @@ - (NSData *)measureNSDataFromFile:(NSString *)path method:(NSData * (^)(NSString

- (NSData *)measureNSDataFromFile:(NSString *)path
options:(NSDataReadingOptions)readOptionsMask
origin:(NSString *)origin
error:(NSError **)error
method:(NSData * (^)(NSString *, NSDataReadingOptions, NSError **))method
{
id<SentrySpan> span = [self startTrackingReadingFilePath:path];
id<SentrySpan> span = [self startTrackingReadingFilePath:path
origin:origin
operation:SentrySpanOperation.fileRead];

NSData *result = method(path, readOptionsMask, error);

Expand All @@ -121,6 +130,7 @@ - (NSData *)measureNSDataFromFile:(NSString *)path

- (NSData *)measureNSDataFromURL:(NSURL *)url
options:(NSDataReadingOptions)readOptionsMask
origin:(NSString *)origin
error:(NSError **)error
method:(NSData * (^)(NSURL *, NSDataReadingOptions, NSError **))method
{
Expand All @@ -131,7 +141,9 @@ - (NSData *)measureNSDataFromURL:(NSURL *)url
if (![url.scheme isEqualToString:NSURLFileScheme])
return method(url, readOptionsMask, error);

id<SentrySpan> span = [self startTrackingReadingFilePath:url.path];
id<SentrySpan> span = [self startTrackingReadingFilePath:url.path
origin:origin
operation:SentrySpanOperation.fileRead];

NSData *result = method(url, readOptionsMask, error);

Expand All @@ -146,11 +158,12 @@ - (NSData *)measureNSDataFromURL:(NSURL *)url
- (BOOL)measureNSFileManagerCreateFileAtPath:(NSString *)path
data:(NSData *)data
attributes:(NSDictionary<NSFileAttributeKey, id> *)attributes
origin:(NSString *)origin
method:
(BOOL (^)(NSString *_Nonnull, NSData *_Nonnull,
NSDictionary<NSFileAttributeKey, id> *_Nonnull))method
{
id<SentrySpan> span = [self startTrackingWritingNSData:data filePath:path];
id<SentrySpan> span = [self startTrackingWritingNSData:data filePath:path origin:origin];

BOOL result = method(path, data, attributes);

Expand All @@ -161,6 +174,7 @@ - (BOOL)measureNSFileManagerCreateFileAtPath:(NSString *)path
}

- (nullable id<SentrySpan>)spanForPath:(NSString *)path
origin:(NSString *)origin
operation:(NSString *)operation
size:(NSUInteger)size
{
Expand All @@ -179,19 +193,18 @@ - (BOOL)measureNSFileManagerCreateFileAtPath:(NSString *)path
ioSpan = [span startChildWithOperation:operation
description:[self transactionDescriptionForFile:path
fileSize:size]];
ioSpan.origin = SentryTraceOrigin.autoNSData;
ioSpan.origin = origin;
}];

if (ioSpan == nil) {
SENTRY_LOG_DEBUG(@"No transaction bound to scope. Won't track file IO operation.");
return nil;
}

SENTRY_LOG_DEBUG(
@"SentryNSDataTracker automatically started a new span with description: %@, operation: %@",
SENTRY_LOG_DEBUG(@"Automatically started a new span with description: %@, operation: %@",
ioSpan.description, operation);

[ioSpan setDataValue:path forKey:@"file.path"];
[ioSpan setDataValue:path forKey:SentrySpanDataKey.filePath];

[self mainThreadExtraInfo:ioSpan];

Expand Down Expand Up @@ -228,12 +241,19 @@ - (void)mainThreadExtraInfo:(id<SentrySpan>)span
}
}

- (nullable id<SentrySpan>)startTrackingWritingNSData:(NSData *)data filePath:(NSString *)path
- (nullable id<SentrySpan>)startTrackingWritingNSData:(NSData *)data
filePath:(NSString *)path
origin:(NSString *)origin
{
return [self spanForPath:path operation:SentrySpanOperation.fileWrite size:data.length];
return [self spanForPath:path
origin:origin
operation:SentrySpanOperation.fileWrite
size:data.length];
}

- (nullable id<SentrySpan>)startTrackingReadingFilePath:(NSString *)path
origin:(NSString *)origin
operation:(NSString *)operation
{
// Some iOS versions nest constructors calls. This counter help us avoid create more than one
// span for the same operation.
Expand All @@ -245,7 +265,7 @@ - (void)mainThreadExtraInfo:(id<SentrySpan>)span
if (count)
return nil;

return [self spanForPath:path operation:SentrySpanOperation.fileRead size:0];
return [self spanForPath:path origin:origin operation:operation size:0];
}

- (void)endTrackingFile
Expand All @@ -266,10 +286,11 @@ - (void)endTrackingFile

- (void)finishTrackingNSData:(NSData *)data span:(id<SentrySpan>)span
{
[span setDataValue:[NSNumber numberWithUnsignedInteger:data.length] forKey:@"file.size"];
[span setDataValue:[NSNumber numberWithUnsignedInteger:data.length]
forKey:SentrySpanDataKey.fileSize];
[span finish];

SENTRY_LOG_DEBUG(@"SentryNSDataTracker automatically finished span %@", span.description);
SENTRY_LOG_DEBUG(@"Automatically finished span %@", span.description);
}

- (BOOL)ignoreFile:(NSString *)path
Expand Down
5 changes: 5 additions & 0 deletions Sources/Sentry/SentryNSDataSwizzling.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ + (void)swizzle
measureNSData:self
writeToFile:path
atomically:useAuxiliaryFile
origin:SentryTraceOrigin.autoNSData
method:^BOOL(NSString *_Nonnull filePath, BOOL isAtomically) {
return SentrySWCallOriginal(filePath, isAtomically);
}];
Expand All @@ -60,6 +61,7 @@ + (void)swizzle
measureNSData:self
writeToFile:path
options:writeOptionsMask
origin:SentryTraceOrigin.autoNSData
error:error
method:^BOOL(
NSString *filePath, NSDataWritingOptions options, NSError **outError) {
Expand All @@ -77,6 +79,7 @@ + (void)swizzle
return [SentryNSDataSwizzling.shared.tracker
measureNSDataFromFile:path
options:options
origin:SentryTraceOrigin.autoNSData
error:error
method:^NSData *(NSString *filePath, NSDataReadingOptions options,
NSError **outError) {
Expand All @@ -91,6 +94,7 @@ + (void)swizzle
SentrySWReturnType(NSData *), SentrySWArguments(NSString * path), SentrySWReplacement({
return [SentryNSDataSwizzling.shared.tracker
measureNSDataFromFile:path
origin:SentryTraceOrigin.autoNSData
method:^NSData *(
NSString *filePath) { return SentrySWCallOriginal(filePath); }];
}),
Expand All @@ -105,6 +109,7 @@ + (void)swizzle
return [SentryNSDataSwizzling.shared.tracker
measureNSDataFromURL:url
options:options
origin:SentryTraceOrigin.autoNSData
error:error
method:^NSData *(NSURL *fileUrl, NSDataReadingOptions options,
NSError **outError) {
Expand Down
1 change: 1 addition & 0 deletions Sources/Sentry/SentryNSFileManagerSwizzling.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ + (void)swizzle
measureNSFileManagerCreateFileAtPath:path
data:data
attributes:attributes
origin:SentryTraceOrigin.autoNSData
method:^BOOL(NSString *path, NSData *data,
NSDictionary<NSFileAttributeKey, id>
*attributes) {
Expand Down
6 changes: 6 additions & 0 deletions Sources/Sentry/include/SentryFileIOTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ SENTRY_NO_INIT
- (BOOL)measureNSData:(NSData *)data
writeToFile:(NSString *)path
atomically:(BOOL)useAuxiliaryFile
origin:(NSString *)origin
method:(BOOL (^)(NSString *, BOOL))method;

/**
Expand All @@ -29,20 +30,23 @@ SENTRY_NO_INIT
- (BOOL)measureNSData:(NSData *)data
writeToFile:(NSString *)path
options:(NSDataWritingOptions)writeOptionsMask
origin:(NSString *)origin
error:(NSError **)error
method:(BOOL (^)(NSString *, NSDataWritingOptions, NSError **))method;

/**
* Measure NSData 'initWithContentsOfFile:' method.
*/
- (nullable NSData *)measureNSDataFromFile:(NSString *)path
origin:(NSString *)origin
method:(NSData *_Nullable (^)(NSString *))method;

/**
* Measure NSData 'initWithContentsOfFile:options:error:' method.
*/
- (nullable NSData *)measureNSDataFromFile:(NSString *)path
options:(NSDataReadingOptions)readOptionsMask
origin:(NSString *)origin
error:(NSError **)error
method:(NSData *_Nullable (^)(
NSString *, NSDataReadingOptions, NSError **))method;
Expand All @@ -52,6 +56,7 @@ SENTRY_NO_INIT
*/
- (nullable NSData *)measureNSDataFromURL:(NSURL *)url
options:(NSDataReadingOptions)readOptionsMask
origin:(NSString *)origin
error:(NSError **)error
method:(NSData *_Nullable (^)(
NSURL *, NSDataReadingOptions, NSError **))method;
Expand All @@ -62,6 +67,7 @@ SENTRY_NO_INIT
- (BOOL)measureNSFileManagerCreateFileAtPath:(NSString *)path
data:(NSData *)data
attributes:(NSDictionary<NSFileAttributeKey, id> *)attributes
origin:(NSString *)origin
method:(BOOL (^)(NSString *, NSData *,
NSDictionary<NSFileAttributeKey, id> *))method;

Expand Down
24 changes: 24 additions & 0 deletions Sources/Swift/Transactions/SentrySpanDataKey.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

/**
* Constants for span data field keys.
*
* These keys are used to attach additional data to spans in a standardized way.
*
* The keys follow [OpenTelemetry's semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/trace.md)
* for attributes and must be:
* - Lowercase
* - Use underscores for word separation
* - Follow the format `<namespace>.<attribute>` (e.g. `file.size`)
*
* See [Sentry SDK development documentation](https://develop.sentry.dev/sdk/telemetry/traces/span-data-conventions/) for
* more information.
*/
@objcMembers @objc(SentrySpanDataKey)
class SentrySpanDataKey: NSObject {
/// Used to set the number of bytes processed in a file span operation
static let fileSize = "file.size"

/// Used to set the path of the file in a file span operation
static let filePath = "file.path"
}
11 changes: 11 additions & 0 deletions Sources/Swift/Transactions/SentrySpanOperation.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import Foundation

/**
* Span operations are short string identifiers that categorize the type of operation a span is measuring.
*
* They follow a hierarchical dot notation format (e.g. 'ui.load.initial_display') to group related operations.
* These identifiers help organize and analyze performance data across different types of operations.
*
* See [Sentry SDK development documentation](https://develop.sentry.dev/sdk/telemetry/traces/span-operations/) for more information.
*/
@objcMembers @objc(SentrySpanOperation)
class SentrySpanOperation: NSObject {
static let appLifecycle = "app.lifecycle"
Expand All @@ -9,6 +17,9 @@ class SentrySpanOperation: NSObject {

static let fileRead = "file.read"
static let fileWrite = "file.write"
static let fileCopy = "file.copy"
static let fileRename = "file.rename"
static let fileDelete = "file.delete"

static let networkRequestOperation = "http.client"

Expand Down
1 change: 1 addition & 0 deletions Sources/Swift/Transactions/SentryTraceOrigin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ class SentryTraceOrigin: NSObject {
static let autoUITimeToDisplay = "auto.ui.time_to_display"
static let autoUIViewController = "auto.ui.view_controller"
static let manual = "manual"
static let manualFileData = "manual.file.data"
static let manualUITimeToDisplay = "manual.ui.time_to_display"
}
Loading

0 comments on commit e757311

Please sign in to comment.