Logging
Configure log levels, privacy settings, and custom log handlers to control how the Airship SDK logs messages.
The Airship SDK provides configurable log levels to help you debug issues without overwhelming the console. If you don’t configure logging, the SDK uses Info for development builds and Error for production builds with private privacy level.
Log levels
The log level acts as a minimum threshold—only logs at that level and higher will be logged. Available log levels, ordered from most to least verbose:
| Log Level | Prefix | Description |
|---|---|---|
| Verbose | [Airship] [V] | Highly detailed SDK status for deep debugging and troubleshooting |
| Debug | [Airship] [D] | General SDK status with more detailed information than Info |
| Info | [Airship] [I] | General SDK status and lifecycle events |
| Warning | [Airship] [W] | API deprecations, invalid setup, and other recoverable issues |
| Error | [Airship] [E] | Critical errors and exceptions that the SDK cannot gracefully handle |
| None | — | Disables all logging |
Log privacy levels
Control the visibility of log contents using privacy levels. This is especially useful when debugging release builds without exposing sensitive information.
- private (default): Uses
os.Loggerto log all messages at theprivatelevel. The content of most logs will be redacted and will not be visible in the Console app by default. Use this for production builds to protect sensitive data. - public: Sends all logs to
os.Loggerwith apublicprivacy level, preventing their content from being redacted. Use this when you need to capture detailed logs from release builds for debugging.
When using public privacy level, verbose and debug log messages are automatically elevated to info level because Console log doesn’t support those levels directly. This ensures all detailed logs are visible when debugging production builds.
Configuration
You can set separate log levels and privacy levels for development and production builds in your Airship config during takeOff.
Common configuration
Typical setup: more verbose logging for development, minimal logging for production:
Common logging configuration
var config = AirshipConfig()
// Development: verbose logging for debugging
config.developmentLogLevel = .verbose
config.developmentLogPrivacyLevel = .public
// Production: minimal logging to reduce noise
config.productionLogLevel = .error
config.productionLogPrivacyLevel = .private
try! Airship.takeOff(config)UAConfig *config = [UAConfig config];
// Development: verbose logging for debugging
config.developmentLogLevel = UAAirshipLogLevelVerbose;
// Production: minimal logging to reduce noise
config.productionLogLevel = UAAirshipLogLevelError;
// Privacy levels (set via AirshipConfig.plist)
// <key>developmentLogPrivacyLevel</key>
// <string>public</string>
// <key>productionLogPrivacyLevel</key>
// <string>private</string>
[UAirship takeOff:config error:&airshipError];Debugging production issues
When debugging issues in production builds, temporarily enable verbose logging to capture detailed SDK behavior:
Debugging production
var config = AirshipConfig()
// Production debugging: enable verbose logs
config.productionLogLevel = .verbose
config.productionLogPrivacyLevel = .public
try! Airship.takeOff(config)UAConfig *config = [UAConfig config];
// Production debugging: enable verbose logs
config.productionLogLevel = UAAirshipLogLevelVerbose;
// Set via AirshipConfig.plist:
// <key>productionLogPrivacyLevel</key>
// <string>public</string>
[UAirship takeOff:config error:&airshipError];Custom log handler
You can provide a custom log handler to intercept and handle all Airship log messages. This is useful when you need to integrate Airship logs with your own logging system or customize how logs are formatted or stored.
When a custom log handler is set, the default Airship log handler is completely replaced. Log level filtering is performed before your handler is called, so your handler will only receive logs that meet the configured log level threshold.
Implement the AirshipLogHandler protocol and set it on your Airship config:
import os.log
final class CustomLogHandler: AirshipLogHandler {
private let logger = Logger(subsystem: "com.yourapp.airship", category: "Airship")
func log(
logLevel: AirshipLogLevel,
message: String,
fileID: String,
line: UInt,
function: String
) {
// Forward to your logging system
let osLogLevel: OSLogType
switch logLevel {
case .verbose, .debug:
osLogLevel = .debug
case .info:
osLogLevel = .info
case .warning:
osLogLevel = .default
case .error:
osLogLevel = .error
case .none:
return
}
logger.log(level: osLogLevel, "\(message)")
// Optionally: send to remote logging service
// YourLoggingService.log(message, level: logLevel)
}
}
var config = AirshipConfig()
config.logHandler = CustomLogHandler()
try! Airship.takeOff(config)Categories