Skip to content

mihaelamj/OpenAPILoggingMiddleware

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

OpenAPI Logging Middleware

Swift 6.0+ Platforms

A flexible, configurable logging middleware for OpenAPI client and server implementations with support for console, file, and OSLog logging.

Features

  • βœ… Dual Parameter System: Separate appName and logPrefix for clean file naming and formatted console output
  • βœ… Client & Server Support: Works with both ClientMiddleware and ServerMiddleware
  • βœ… Configurable Body Logging: Control how much request/response body data to log
  • βœ… Multiple Log Handlers: Simultaneous console (stream), JSON file, and OSLog logging
  • βœ… OSLog Integration: Native Apple unified logging system support (macOS 11+, iOS 14+)
  • βœ… Automatic File Naming: Generates clean filenames from app name and prefix

Usage

Basic Usage

import OpenAPILoggingMiddleware

// Client logging
let clientMiddleware = LoggingMiddleware(
    appName: "NSSpainAPI",
    logPrefix: "🚚 APIClient: "
)

// Server logging
let serverMiddleware = await LoggingMiddleware(
    appName: "NSSpainAPI",
    logPrefix: "πŸ–₯️ ApiServer: "
)

Advanced Configuration

let middleware = LoggingMiddleware(
    logger: customLogger,                              // Optional custom logger
    bodyLoggingConfiguration: .upTo(maxBytes: 2_000_000), // Log bodies up to 2MB
    appName: "MyApp",                                  // App identifier for files
    logPrefix: "πŸ”§ Service: "                          // Console output prefix
)

File Naming

The middleware automatically generates clean, organized log file names:

appName logPrefix File Names
"NSSpainAPI" "🚚 APIClient: " _NSSpainAPI_APIClient.json, _NSSpainAPI_APIClient.log
"NSSpainAPI" "πŸ–₯️ ApiServer: " _NSSpainAPI_ApiServer.json, _NSSpainAPI_ApiServer.log
"MyApp" "Client: " _MyApp_Client.json, _MyApp_Client.log
nil "🚚 APIClient: " _APIClient.json, _APIClient.log
nil "" _OpenAPILog.json, _OpenAPILog.log

File Naming Rules:

  1. With both appName and logPrefix: _<appName>_<cleanPrefix>.<ext>
  2. With appName only: _<appName>.<ext>
  3. With logPrefix only: _<cleanPrefix>.<ext>
  4. Neither provided: _OpenAPILog.<ext> (default)

Clean names are generated by:

  • Trimming whitespace
  • Removing spaces from prefix
  • Filtering to ASCII letters and numbers (removes emojis)

Log Output

Console Output (Stream)

Uses the logPrefix as-is for visual distinction:

🚚 APIClient: `method` = `GET`
🚚 APIClient: `path` = `/user/me`
🚚 APIClient: `statusCode` = `200`

JSON File Output

Structured JSON logs saved to Documents directory:

[
  {
    "timestamp": "16.10.2025. 14:30:45",
    "method": "GET",
    "path": "/user/me",
    "statusCode": "200",
    "responseBody": "{...}"
  }
]

OSLog Output (macOS 11+, iOS 14+)

Native Apple unified logging system integration. Logs appear in:

  • Console.app on macOS
  • Xcode Console during development
  • System log database for persistent storage

Subsystem: com.openapi Category: logging-middleware

Viewing OSLog Output

Real-Time Log Streaming

Method 1: Terminal (Recommended for Development)

Open Terminal and run:

# Stream ALL logs from the middleware in real-time
log stream --predicate 'subsystem == "com.openapi"' --level debug

This will show logs as they happen - you'll see each API request/response immediately.

Additional real-time filters:

# Filter by specific prefix (e.g., only APIClient logs)
log stream --predicate 'subsystem == "com.openapi" AND eventMessage CONTAINS "APIClient"' --level debug

# Show only errors in real-time
log stream --predicate 'subsystem == "com.openapi"' --level error

# Filter by specific HTTP method
log stream --predicate 'subsystem == "com.openapi" AND eventMessage CONTAINS "GET"' --level debug

Method 2: Console.app (GUI)

For a visual real-time log viewer:

  1. Open Console.app (press ⌘+Space, type "Console", press Enter)
  2. In the left sidebar, select your Mac under "Devices"
  3. In the search field (top-right), type: subsystem:com.openapi
  4. Click the "Start" button to begin streaming logs in real-time
  5. Logs will appear live as your app makes API calls

Tip: Keep Console.app open while running your app to see all logs in real-time with syntax highlighting!

Historical Logs

View past logs in Terminal:

# Show logs from the last hour
log show --predicate 'subsystem == "com.openapi"' --last 1h

# Show logs with specific text
log show --predicate 'subsystem == "com.openapi" AND eventMessage CONTAINS "GET"' --last 30m

# Export logs to a file
log show --predicate 'subsystem == "com.openapi"' --last 1d --style json > logs.json

Log Level Mapping:

swift-log Level OSLog Type Console.app Display
.trace .debug Debug
.debug .debug Debug
.info .info Info
.notice .default Default
.warning .error Error
.error .error Error
.critical .fault Fault

Privacy & Performance:

  • OSLog is highly optimized for performance
  • Logs are stored in a compressed binary format
  • Automatic log rotation and retention policies
  • System-level privacy controls for sensitive data

Architecture

The middleware uses a MultiplexLogHandler to direct log output to multiple destinations simultaneously. By default, it's configured with:

  • StreamLogHandler: Prints formatted logs to the console (stdout).
  • JSONFileLogHandler: Saves structured JSON logs to a file in the app's Documents directory.
  • OSLogHandler: Sends logs to Apple's unified logging system (macOS 11+, iOS 14+).

This architecture makes it easy to:

  • Monitor logs in real-time during development (console & OSLog)
  • Persist structured logs for analysis (JSON files)
  • Integrate with system-level logging tools (Console.app, log command)
  • Debug production issues using native Apple tools

Body Logging Policy

Control how request/response bodies are logged:

// Never log bodies (for sensitive data)
.never

// Log bodies up to specified size (default: 2MB)
.upTo(maxBytes: 1024 * 1024 * 2)

Log Metadata

Each log entry includes:

  • HTTP method
  • Request path
  • Base URL and full path
  • Request/response headers (JSON format)
  • Request/response body (based on policy)
  • Operation ID
  • Status code and reason
  • Error information (if failed)
  • Unique identifier per request

Log Destinations

File Locations

Log files are saved to the system Documents directory:

  • iOS/macOS: ~/Documents/
  • JSON logs: _<appName>_<prefix>.json

Console Output

  • Stream logs: Output to stdout (Xcode Console, Terminal)

OSLog (macOS 11+, iOS 14+)

  • System database: Managed by logd daemon
  • Location: /var/db/diagnostics/ (system-managed, not user-accessible)
  • Access: Use Console.app or log command (see Viewing OSLog Output)

Example Integration

ApiClient

self.loggingMiddleware = LoggingMiddleware(
    appName: "NSSpainAPI",
    logPrefix: "🚚 APIClient: "
)

self.client = Client(
    serverURL: serverURL,
    transport: transport,
    middlewares: [loggingMiddleware, authMiddleware]
)

ApiServer

let loggingMiddleware = await LoggingMiddleware(
    appName: "NSSpainAPI",
    logPrefix: "πŸ–₯️ ApiServer: "
)

try handler.registerHandlers(
    on: transport,
    serverURL: serverURL,
    middlewares: [loggingMiddleware]
)

Thread Safety

The LoggingMiddleware is an actor, ensuring thread-safe operation across concurrent requests.

Dependencies

  • swift-openapi-runtime - OpenAPI runtime support
  • swift-log - Logging backend
  • HTTPTypes - HTTP types

About

A flexible, configurable logging middleware for OpenAPI client and server implementations with support for both console and file logging.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages