diyamantina/openapiloggingmiddleware
Request and response logging middleware for Swift OpenAPI clients and servers.
Installation
.package(url: "https://github.com/diyamantina/OpenAPILoggingMiddleware", from: "1.3.0"),.target(
name: "MyApp",
dependencies: [
.product(name: "OpenAPILoggingMiddleware", package: "OpenAPILoggingMiddleware"),
]
),Quick Start
import OpenAPILoggingMiddleware
import OpenAPIAsyncHTTPClient
let logging = LoggingMiddleware(appName: "MyAPI", logPrefix: "client ")
let client = Client(
serverURL: serverURL,
transport: AsyncHTTPClientTransport(),
middlewares: [logging]
)Use the same middleware type on the generated server side:
try handler.registerHandlers(
on: transport,
serverURL: try Servers.Server1.url(),
middlewares: [LoggingMiddleware(appName: "MyAPI", logPrefix: "server ")]
)The default logger writes stream output, appends JSON records to a temporary file, and uses OSLog on Apple platforms.
Configuration
public init(
logger: Logger? = nil,
bodyLoggingConfiguration: BodyLoggingPolicy = .upTo(maxBytes: 2 * 1024 * 1024),
appName: String? = nil,
logPrefix: String = "",
requestLogLevel: Logger.Level = .debug,
responseLogLevel: Logger.Level = .debug,
errorLogLevel: Logger.Level = .error,
redactedHeaderFields: Set<HTTPField.Name> = LoggingMiddleware.defaultRedactedHeaderFields
)| Parameter | Default | Purpose | |---|---|---| | logger | default multiplex logger | Pass your own Logger to route events to custom log handlers. | | bodyLoggingConfiguration | .upTo(maxBytes: 2 MiB) | Controls whether request/response bodies are logged and how much is captured. | | appName | nil | Used to derive the JSON log file name. | | logPrefix | "" | Prepended to emitted log lines. Useful for distinguishing client and server instances. | | requestLogLevel | .debug | Log level for request entries. | | responseLogLevel | .debug | Log level for response entries. | | errorLogLevel | .error | Log level when the next middleware or transport throws. | | redactedHeaderFields | auth and cookie headers | Header names whose values are replaced by "<redacted>" before logging. |
Header Redaction
The default redaction set covers:
AuthorizationProxy-AuthorizationCookieSet-Cookie
// Default credential-header redaction.
let normal = LoggingMiddleware(appName: "api")
// Extend the default set.
let strict = LoggingMiddleware(
appName: "api",
redactedHeaderFields: LoggingMiddleware.defaultRedactedHeaderFields
.union([HTTPField.Name("X-Api-Key")!])
)
// Disable redaction. Avoid this in production.
let unsafe = LoggingMiddleware(appName: "api", redactedHeaderFields: [])Use HTTPFields.redacted(redacting:) when your own logging code needs the same scrubbing behavior.
Body Logging
BodyLoggingPolicy decides how request and response bodies are handled:
| Policy | Behavior | |---|---| | .never | Redacts every body. | | .upTo(maxBytes:) | Logs bodies up to the cap. Oversized bodies are summarized as <N bytes>. |
When the middleware consumes a body to log it, it re-wraps the bytes in a fresh HTTPBody before forwarding. Downstream middleware and handlers still receive a readable body.
Bundled Log Handlers
| Handler | Purpose | |---|---| | PrefixedStreamLogHandler | Writes readable metadata lines to stdout or another TextOutputStream. | | JSONFileLogHandler | Appends one structured JSON record per request to a file. | | OSLogHandler | Forwards events to Apple's unified logging system. Apple platforms only. | | ObserverLogHandler | Sends every log event to a closure for dashboards, tests, WebSocket streams, or analytics hooks. |
Pass a custom Logger when you want to compose your own handler stack with Logging.MultiplexLogHandler.
Companion Packages
stamps bearer tokens on generated OpenAPI clients and enforces bearer tokens in Vapor servers.
captures client IP and user-agent context for generated OpenAPI handlers.
Platform Support
| Platform | CI coverage | |---|---| | macOS 13+ | swift build and swift test | | Linux, Swift 6.0 container | swift build and swift test | | iOS 16+ | xcodebuild build for iOS Simulator | | tvOS 16+ | xcodebuild build for tvOS Simulator | | watchOS 9+ | xcodebuild build for watchOS Simulator |
OSLogHandler is Apple-only. Linux consumers can compose PrefixedStreamLogHandler, JSONFileLogHandler, and ObserverLogHandler.
Documentation
DocC is enabled:
swift package --allow-writing-to-directory ./docs generate-documentation \
--target OpenAPILoggingMiddleware \
--output-path ./docs/OpenAPILoggingMiddleware.doccarchiveTesting
The package ships with 74 tests across 12 suites covering:
- Client and server intercept paths.
- Header redaction.
- Body logging policy behavior and single-pass body re-wrapping.
- Stream, JSON file, OSLog-adjacent, and observer handler behavior.
- Concurrent request stress cases and malformed input handling.
- Public API and
Sendableconformance checks.
Run them with:
swift testContributing
Contributions are welcome. Read CONTRIBUTING.md for setup, style, and PR expectations. Security issues should be reported privately; see SECURITY.md.
License
MIT. See LICENSE.
Package Metadata
Repository: diyamantina/openapiloggingmiddleware
Default branch: main
README: README.md