Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/file-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ run_unit_tests_for_prs: &run_unit_tests_for_prs
- "SentryTestUtils/**"
- "SentryTestUtilsDynamic/**"
- "SentryTestUtilsTests/**"
- "3rd-party-integrations/**"

# GH Actions
- ".github/workflows/test.yml"
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,38 @@ jobs:
device: "Apple TV"
scheme: "Sentry"

# This will be replaced once #6945 is merged.
swiftlog-integration-unit-tests:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m: We should consider adding a new workflow file for integrations separate to the main SDK tests, and to not further extend it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itaybre started working on a shared workflow we can use for integrations in #6945 which we can use when ready.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment to replace this once #6945 is ready.

name: SentrySwiftLog Unit Tests
if: needs.files-changed.outputs.run_unit_tests_for_prs == 'true'
needs: files-changed
runs-on: macos-15
steps:
- uses: actions/checkout@v6

- name: Select Xcode
run: ./scripts/ci-select-xcode.sh 16.4

- name: Setup local sentry-cocoa dependency
working-directory: 3rd-party-integrations/SentrySwiftLog
run: swift package edit sentry-cocoa --path ../..

- name: Run SwiftLog tests
working-directory: 3rd-party-integrations/SentrySwiftLog
run: swift test

- name: Archiving Raw Logs
uses: actions/upload-artifact@v5
if: ${{ failure() || cancelled() }}
with:
name: raw-output-swiftlog-integration
path: |
3rd-party-integrations/SentrySwiftLog/.build/**/*.log

- name: Run CI Diagnostics
if: failure()
run: ./scripts/ci-diagnostics.sh

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: New test job missing from required-check dependencies

The new swiftlog-integration-unit-tests job is not included in the unit-tests-required-check job's needs array. Since unit-tests-required-check is the required status check that gates merging, failures in the swiftlog integration tests won't block the PR from merging. The job runs but its result is never validated by the required check.

Fix in Cursor Fix in Web

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is relevant!

# This check validates that either all unit tests passed or were skipped, which allows us
# to make unit tests a required check with only running the unit tests when required.
# So, we don't have to run unit tests, for example, for Changelog or ReadMe changes.
Expand Down
100 changes: 100 additions & 0 deletions 3rd-party-integrations/SentrySwiftLog/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# --- macOS ---

# General
.DS_Store
__MACOSX/
.AppleDouble
.LSOverride
Icon[]

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# --- Swift ---

# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## User settings
xcuserdata/

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm

.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build/

# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# --- Xcode ---

## User settings
xcuserdata/

# Archive
*.xcarchive
34 changes: 34 additions & 0 deletions 3rd-party-integrations/SentrySwiftLog/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// swift-tools-version:6.0
import PackageDescription

let package = Package(
name: "SentrySwiftLog",
platforms: [.iOS(.v15), .macOS(.v10_14), .tvOS(.v15), .watchOS(.v8), .visionOS(.v1)],
products: [
.library(
name: "SentrySwiftLog",
targets: ["SentrySwiftLog"]
)
],
dependencies: [
.package(url: "https://github.com/apple/swift-log", from: "1.5.0"),
.package(url: "https://github.com/getsentry/sentry-cocoa", from: "9.0.0")
],
targets: [
.target(
name: "SentrySwiftLog",
dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "Sentry", package: "sentry-cocoa")
]
),
.testTarget(
name: "SentrySwiftLogTests",
dependencies: [
"SentrySwiftLog",
.product(name: "Logging", package: "swift-log"),
.product(name: "Sentry", package: "sentry-cocoa")
]
)
]
)
113 changes: 113 additions & 0 deletions 3rd-party-integrations/SentrySwiftLog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Sentry SwiftLog Integration

A [SwiftLog](https://github.com/apple/swift-log) handler that forwards log entries to Sentry's structured logging system, automatically capturing application logs with full context including metadata, source location, and log levels.

> [!NOTE]
> This repo is a mirror of [github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa). The source code lives in `3rd-party-integrations/SentrySwiftLog/`. This allows users to import only what they need via SPM while keeping all integration code in the main repository.

## Installation

### Swift Package Manager

Add the following dependencies to your `Package.swift` or Xcode package dependencies:

```swift
dependencies: [
.package(url: "https://github.com/getsentry/sentry-cocoa-swiftlog", from: "1.0.0")
]
```

## Quick Start

```swift
import Sentry
import Logging

SentrySDK.start { options in
options.dsn = "YOUR_DSN"
options.enableLogs = true
}

var handler = SentryLogHandler(logLevel: .info)
handler.metadata["app_version"] = "1.0.0"
handler.metadata["environment"] = "production"

LoggingSystem.bootstrap { _ in handler }

let logger = Logger(label: "com.example.app")

logger.info("User logged in", metadata: ["userId": "12345"])
logger.error("Payment failed", metadata: ["errorCode": 500])
logger.warning("API rate limit approaching", metadata: ["remaining": 10])

logger.info("User action", metadata: [
"userId": "12345",
"action": "purchase"
])
```

## Configuration

### Log Level Threshold

Set the minimum log level for messages to be sent to Sentry. Messages below the configured threshold will be filtered out and not sent to Sentry.

```swift
let handler = SentryLogHandler(logLevel: .trace)
```

### Handler Metadata

Add metadata that will be included with all log entries. Handler metadata is merged with call-site metadata, with call-site metadata taking precedence.

```swift
var handler = SentryLogHandler(logLevel: .info)
handler.metadata["app_version"] = "1.0.0"
handler.metadata["environment"] = "production"
```

You can also access metadata using subscript syntax:

```swift
handler[metadataKey: "app_version"] = "1.0.0"
let version = handler[metadataKey: "app_version"]
```

## Log Level Mapping

`swift-log` levels are automatically mapped to Sentry log levels:

| swift-log Level | Sentry Log Level |
| --------------- | ---------------- |
| `.trace` | `.trace` |
| `.debug` | `.debug` |
| `.info` | `.info` |
| `.notice` | `.info` |
| `.warning` | `.warn` |
| `.error` | `.error` |
| `.critical` | `.fatal` |

## Metadata Handling

The handler supports all `swift-log` metadata types including strings, dictionaries, arrays, and string convertible types (numbers, booleans, etc.). All metadata is automatically prefixed with `swift-log.` in Sentry attributes (e.g., `swift-log.userId`, `swift-log.user.id`). See the Quick Start section above for examples of each metadata type.

## Automatic Attributes

The handler automatically includes the following attributes with every log entry:

- `sentry.origin`: `"auto.logging.swift-log"`
- `swift-log.level`: The original swift-log level
- `swift-log.source`: The log source
- `swift-log.file`: The source file name
- `swift-log.function`: The function name
- `swift-log.line`: The line number

## Documentation

- [Sentry Cocoa SDK Documentation](https://docs.sentry.io/platforms/apple/)
- [Sentry Logs Documentation](https://docs.sentry.io/platforms/apple/logs/)
- [SwiftLog Repo](https://github.com/apple/swift-log)

## License

This integration follows the same license as the Sentry Cocoa SDK. See the [LICENSE](https://github.com/getsentry/sentry-cocoa/blob/main/LICENSE.md) file for details.
Loading
Loading