-
Notifications
You must be signed in to change notification settings - Fork 1
Observability
Covers environment configuration, logging, metrics, and tracing.
let dev = NetworkEnvironment.development(
baseURL: URL(string: "https://dev.api.example.com")!,
headers: ["X-Env": "dev"]
)
let prod = NetworkEnvironment.production(
baseURL: URL(string: "https://api.example.com")!
)
#if DEBUG
let environment = dev
#else
let environment = prod
#endif
var config = NetworkConfiguration(environment: environment)
config.environment.logLevel = environment.kind == .production ? .error : .debug
config.sslPinning = environment.kind == .production ? .certificateResources(["api"]) : .disabledEnvironmentKind is .development / .qa / .staging / .production. Each environment sets its
own base URL, default headers, timeout, and log level.
config.environment.logLevel = .basic // .none / .error / .basic / .verbose / .debug
config.logger = ConsoleNetworkLogger() // default; writes to os.Logger
config.redactedHeaders = ["x-internal-signature"]
config.redactedBodyKeys = ["ssn", "card_number"]
config.redactedQueryItems = ["session"] // on top of access_token, api_key, signature, code, ...| Level | Emits |
|---|---|
.none |
nothing |
.error |
failures only |
.basic |
method, URL, status, duration |
.verbose |
+ redacted headers |
.debug |
+ redacted bodies |
Authorization, Cookie, Set-Cookie, X-API-Key, and common token body keys are always
redacted, at every level, and sensitive query items (including the key name APIKeyAuth sends in
the query, automatically) are masked out of logged URLs too. A custom sink is any NetworkLogger
conformer (ship logs to your aggregator, and so on).
Best practice: keep sensitive fields out of logs by adding them to redactedBodyKeys and
redactedQueryItems.
let metrics = InMemoryMetrics()
config.metrics = metrics
let snapshot = await metrics.snapshot()
snapshot.requestCount
snapshot.successCount
snapshot.failureCount
snapshot.statusCodeHistogram // [200: 431, 404: 3, 500: 1]
snapshot.averageDuration
snapshot.p95Duration
snapshot.retryCount
snapshot.tokenRefreshCountFailure events sent to a NetworkMetrics sink carry no request or response body, and credential
headers and URL query secrets are masked, so a sink that forwards to an APM (Sentry, Datadog, and
so on) does not leak tokens or payloads.
InMemoryMetrics is an actor you inspect in tests; NoopMetrics is the default. A custom
NetworkMetrics conformer forwards events to your APM.
- Every request carries a unique
X-Request-ID. - Wrap a logical operation so its requests share one
X-Correlation-ID:
try await client.withCorrelation("checkout-\(orderID)") {
_ = try await client.request(CreateOrder(draft))
_ = try await client.request(ChargeCard(orderID))
}SwiftNetworkKit is source-available proprietary software (not open source). See FAQ Licensing and Support. Repo: https://github.com/ihusnainalii/SwiftNetworkKit · Docs: https://swiftnetworkkit.vercel.app/
Getting started
Guides
- Defining Endpoints
- Authentication and Token Refresh
- Security and Certificate Pinning
- Retry Policy
- Interceptors
- Request Management
- Caching
- Offline Request Queue
- Uploads Downloads and Progress
- Pagination and Batch
- Combine and SwiftUI
- Error Handling
- Observability
- Testing and Mocking
- Best Practices and a Complete Example
- Platform Notes, Thread Safety and Performance
Reference