Skip to content

Commit 20a32b2

Browse files
authored
feat(apple): Add manual File I/O tracing for Swift (#15657)
1 parent 9eb3c50 commit 20a32b2

File tree

1 file changed

+49
-25
lines changed

1 file changed

+49
-25
lines changed

docs/platforms/apple/common/tracing/instrumentation/automatic-instrumentation.mdx

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -312,59 +312,87 @@ Starting with iOS 18, tvOS 18, and macOS 15 the Swift classes `Data` and `FileMa
312312
313313
### Manual File/IO Tracing
314314
315+
Starting with iOS 18.0, macOS 15.0, and tvOS 18.0, the Swift class `Data` can not be instrumented automatically anymore. Instead, you need to use Sentry-specific type extensions.
316+
315317
Starting with version 8.48.0, the Sentry SDK offers extensions for the types `Data` and `FileManager` to track reading and writing data, as well as creating, moving, copying, and deleting files.
316318
317-
The method signatures of the extension resemble the ones of the original types, but they add a span to the current transaction:
319+
The method signatures of these extensions resemble those of the original types, but they add a span to the current transaction. These methods can be used even when the Sentry SDK is not enabled—they will fall back to the original methods in that case.
320+
321+
**Behavior:**
322+
- The SDK only creates spans when there is an active transaction on the scope
323+
- Only file URLs are tracked (non-file URLs like HTTP URLs are ignored, as they are handled by network tracing)
324+
- File size is automatically tracked for read and write operations
325+
- Spans finish with `ok` status on success or `internalError` status if an exception is thrown
326+
- Exceptions thrown during operations are associated with the span
318327
319328
**Data Operations:**
320329
321-
- `Data.init(contentsOfUrlWithSentryTracing:)` for `Data(contentsOf:)`
322-
- `data.writeWithSentryTracing(to:options:)` for `data.write(to:)`
330+
- `Data.init(contentsOfWithSentryTracing:options:)` for `Data(contentsOf:options:)` - Creates spans with operation `file.read`
331+
- `data.writeWithSentryTracing(to:options:)` for `data.write(to:options:)` - Creates spans with operation `file.write`
323332
324333
```swift {tabTitle:Swift}
325334
// Read data from a file URL
326-
let data = Data(contentsOfUrlWithSentryTracing: url)
335+
let url = URL(fileURLWithPath: "/path/to/file.txt")
336+
let data = try Data(contentsOfWithSentryTracing: url)
337+
338+
// Read with options
339+
let dataWithOptions = try Data(contentsOfWithSentryTracing: url, options: [.alwaysMapped])
327340
328341
// Write data to a file URL
329-
data.writeWithSentryTracing(to: url)
342+
try data.writeWithSentryTracing(to: url)
343+
344+
// Write with options
345+
try data.writeWithSentryTracing(to: url, options: [.uncached])
330346
```
331347

332348
**FileManager Operations:**
333349

334-
- `FileManager.createFileWithSentryTracing(atPath:contents:attributes:)` for `FileManager.createFile(atPath:contents:attributes:)`
335-
- `FileManager.moveItemWithSentryTracing(at:to:)` for `FileManager.moveItem(at:to:)`
336-
- `FileManager.moveItemWithSentryTracing(atPath:toPath:)` for `FileManager.moveItem(atPath:toPath:)`
337-
- `FileManager.copyItemWithSentryTracing(at:to:)` for `FileManager.copyItem(at:to:)`
338-
- `FileManager.copyItemWithSentryTracing(atPath:toPath:)` for `FileManager.copyItem(atPath:toPath:)`
339-
- `FileManager.removeItemWithSentryTracing(at:)` for `FileManager.removeItem(at:)`
340-
- `FileManager.removeItemWithSentryTracing(atPath:)` for `FileManager.removeItem(atPath:)`
350+
- `FileManager.createFileWithSentryTracing(atPath:contents:attributes:)` for `FileManager.createFile(atPath:contents:attributes:)` - Creates spans with operation `file.write`
351+
- `FileManager.moveItemWithSentryTracing(at:to:)` for `FileManager.moveItem(at:to:)` - Creates spans with operation `file.rename`
352+
- `FileManager.moveItemWithSentryTracing(atPath:toPath:)` for `FileManager.moveItem(atPath:toPath:)` - Creates spans with operation `file.rename`
353+
- `FileManager.copyItemWithSentryTracing(at:to:)` for `FileManager.copyItem(at:to:)` - Creates spans with operation `file.copy`
354+
- `FileManager.copyItemWithSentryTracing(atPath:toPath:)` for `FileManager.copyItem(atPath:toPath:)` - Creates spans with operation `file.copy`
355+
- `FileManager.removeItemWithSentryTracing(at:)` for `FileManager.removeItem(at:)` - Creates spans with operation `file.delete`
356+
- `FileManager.removeItemWithSentryTracing(atPath:)` for `FileManager.removeItem(atPath:)` - Creates spans with operation `file.delete`
341357

342358
```swift {tabTitle:Swift}
343359
let fileManager = FileManager.default
344360

345361
// Create a file with given content
362+
let path = "/path/to/file.txt"
363+
let data = "Hello, World!".data(using: .utf8)
346364
fileManager.createFileWithSentryTracing(atPath: path, contents: data)
347365

366+
// Create with attributes
367+
let attributes: [FileAttributeKey: Any] = [
368+
.posixPermissions: 0o644
369+
]
370+
fileManager.createFileWithSentryTracing(atPath: path, contents: data, attributes: attributes)
371+
348372
// Move a file or directory
373+
let sourceUrl = URL(fileURLWithPath: "/path/to/source")
374+
let destinationUrl = URL(fileURLWithPath: "/path/to/destination")
349375
try fileManager.moveItemWithSentryTracing(at: sourceUrl, to: destinationUrl)
350-
try fileManager.moveItemWithSentryTracing(atPath: sourcePath, toPath: destinationPath)
376+
377+
// Move using paths
378+
try fileManager.moveItemWithSentryTracing(atPath: "/path/to/source", toPath: "/path/to/destination")
351379

352380
// Copy a file or directory
353381
try fileManager.copyItemWithSentryTracing(at: sourceUrl, to: destinationUrl)
354-
try fileManager.copyItemWithSentryTracing(atPath: sourcePath, toPath: destinationPath)
382+
try fileManager.copyItemWithSentryTracing(atPath: "/path/to/source", toPath: "/path/to/destination")
355383

356384
// Remove a file or directory
357385
try fileManager.removeItemWithSentryTracing(at: url)
358386
try fileManager.removeItemWithSentryTracing(atPath: path)
359387
```
360388

361-
We recommend you disable the swizzling of `NSData` and `NSFileManager` when using manual file I/O tracing, as the internal behavior of these classes differs between platform versions and can cause duplicate spans in your traces.
389+
**Important:** We recommend you disable the swizzling of `NSData` and `NSFileManager` when using manual file I/O tracing, as the internal behavior of these classes differs between platform versions and can cause duplicate spans in your traces.
362390

363391
```swift {tabTitle:Swift}
364392
import Sentry
365393

366394
SentrySDK.start { options in
367-
options.dsn = "___PUBLIC_DSN___";
395+
options.dsn = "___PUBLIC_DSN___"
368396
options.enableFileIOTracing = true
369397
options.enableDataSwizzling = false
370398
options.enableFileManagerSwizzling = false
@@ -393,17 +421,13 @@ SentrySDK.start { options in
393421
options.experimental.enableDataSwizzling = false
394422
options.experimental.enableFileManagerSwizzling = false
395423
}
396-
```
397424
398-
```objc {tabTitle:Objective-C}
399-
@import Sentry;
425+
// Reading a file with tracing enabled:
426+
let url = URL(fileURLWithPath: "/path/to/file.txt")
427+
let data = try Data(contentsOfWithSentryTracing: url, options: [.atomic])
400428
401-
[SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
402-
options.dsn = @"___PUBLIC_DSN___";
403-
options.enableFileIOTracing = YES;
404-
options.experimental.enableDataSwizzling = NO;
405-
options.experimental.enableFileManagerSwizzling = NO;
406-
}];
429+
// Writing to a file with tracing enabled:
430+
try data.writeWithSentryTracing(to: url, options: [.atomic])
407431
```
408432

409433
## Core Data Tracing

0 commit comments

Comments
 (0)