AlamofireNetworkActivityLogger is a Swift logging library for Alamofire 5+ that captures and prints detailed network activity — including cURL commands, headers, response bodies, and timing — using a modern, race-condition-free actor-based design backed by Swift Concurrency.
- Structured log levels: Choose between
.debug,.info, and.offto control verbosity. - cURL generation: Automatically formats outgoing requests as copy-pasteable
curlcommands. - Pretty-printed JSON: Response bodies are formatted for readability when possible.
- Request filtering: Optionally supply an
NSPredicateto suppress specific requests from logs. - Actor-based concurrency: Built with Swift's
actormodel — no locks, no races. - Async notification observation: Uses
AsyncStreamoverNotificationCenterfor safe, structured observation.
- iOS 17+ / macOS 14+ / tvOS 17+ / watchOS 10+ / visionOS 1+
- Swift 6+
- Alamofire 5.11+
Add the following to your Package.swift:
dependencies: [
.package(url: "https://github.com/aporat/AlamofireNetworkActivityLogger.git", from: "1.0.0")
]Then include "AlamofireNetworkActivityLogger" as a dependency in your target.
import AlamofireNetworkActivityLogger
Task {
await AlamofireNetworkLogger.shared.startLogging()
}Call this once early in your app's lifecycle (e.g. in AppDelegate or your app's init). All Alamofire requests will be logged automatically after this point.
Task {
await AlamofireNetworkLogger.shared.stopLogging()
}Task {
await AlamofireNetworkLogger.shared.setLevel(.info)
}| Level | Output |
|---|---|
.debug |
cURL command, headers, status code, body, timing |
.info |
HTTP method, URL, status code, timing |
.off |
Nothing (logging disabled) |
Use an NSPredicate to suppress specific requests from appearing in the logs:
Task {
await AlamofireNetworkLogger.shared.setFilterPredicate(NSPredicate { request, _ in
guard let url = (request as? URLRequest)?.url else { return false }
return url.absoluteString.contains("analytics")
})
}Any request where the predicate evaluates to true will be silently skipped.
.debug level:
---------------------
✅ [REQUEST] GET 'https://api.example.com/users'
cURL:
curl -v -H 'Accept: application/json' -H 'Authorization: Bearer abc123' "https://api.example.com/users"
✅ [RESPONSE] 200 [0.342s]
Headers: [
Content-Type: application/json
]
Body:
{
"id" : 1,
"name" : "Jane"
}
---------------------
.info level:
---------------------
✅ GET 'https://api.example.com/users'
✅ [RESPONSE] 200 [0.342s]
---------------------
Contributions are welcome! To contribute:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Commit your changes with clear, descriptive messages.
- Push your branch and open a pull request.
Please ensure your changes include appropriate tests and follow the existing code style.
This project is licensed under the MIT License. See the LICENSE file for details.