Logging (SDK Layer)#

HaapiLogger is shared across all layers — Driver, SDK, and UIKit/UIWidget — so a single configuration covers the entire stack. Configure it once at app startup, and include the SDK follow-up tags alongside the Driver tags. For the full concept (severity ordering, sensitive-value masking, custom sinks), see Logging and Observability .

What the SDK Layer Adds#

If you have already configured HaapiLogger at the Driver Layer, the only SDK-specific delta is the SDK follow-up tag set — the tag prefixes (HAAPI_SDK_FLOW, HAAPI_SDK_HTTP, HAAPI_SDK_MAPPING, HAAPI_SDK_OAUTH, and on Android HAAPI_SDK_STORAGE) that identify records emitted by the SDK Layer’s flow stepping, HTTP plumbing, payload mapping, and OAuth operations.

Configure SDK-Layer logging when you need to:

  • Diagnose flow-stepping bugsHAAPI_SDK_FLOW records every transition through the HAAPI state machine.
  • Trace OAuth token operationsHAAPI_SDK_OAUTH covers fetch, refresh, and revoke, including the dpop-nonce lifecycle that the SDK manages on your behalf.
  • Investigate payload-mapping failuresHAAPI_SDK_MAPPING reports when the SDK can’t deserialize a server response into its typed model.

If your app stays at the Driver Layer (no HaapiManager or OAuthTokenManager), skip the SDK-tag wiring; the SDK records do not exist on that path.

Configuration#

iOS and Android use follow-up tags differently. On iOS, tags are an emission gate — HaapiLogger.followUpTags defaults to an empty array, so nothing logs until you set it; the SDK Layer requires explicitly appending SdkFollowUpTag.allCases. On Android, tags have no behavioural effect on emission — enabled and setLevel(...) are the only gates, and tags travel through to your sink as labels. Adding the SDK Layer has no logger-side step beyond initialising the shared logger; if you want SDK-only output, filter by tag prefix inside your LogSink.log(...) (or at the LogCat command line).

Combine Driver and SDK follow-up tags when configuring in AppDelegate.application(_:didFinishLaunchingWithOptions:):

HaapiLogger.followUpTags = DriverFollowUpTag.allCases + SdkFollowUpTag.allCases
HaapiLogger.setLogType(LogType.info)

SDK follow-up tags include HAAPI_SDK_FLOW, HAAPI_SDK_HTTP, HAAPI_SDK_MAPPING, and HAAPI_SDK_OAUTH. Adding only DriverFollowUpTag.allCases silently suppresses every SDK-emitted record — a common cause of “the SDK isn’t logging anything”.

Sensitive-Value Masking#

HaapiLogger.isSensitiveValueMasked defaults to true and should remain true in any non-development build. The SDK Layer is where access tokens, refresh tokens, DPoP proofs, and dpop-nonce headers flow — disabling masking here surfaces them all in log output. When disabled, the logger emits an explicit warning every time it prints an unmasked sensitive value so the misconfiguration is hard to miss.

Setting isSensitiveValueMasked = false in a release build leaks the OAuth tokens and DPoP material handled by the SDK Layer into application logs. If those logs ship to a third-party crash reporter or observability backend, the leak follows them. Keep masking on outside of local debugging, and never combine isSensitiveValueMasked = false with a remote log sink.

Custom Sinks#

To route logs into a host application’s observability platform or crash reporter, register a LogSink implementation. The sink receives every log record with its level, follow-up tag, message, file, and line; it can filter, transform, or forward as needed.

final class MyLogSink: LogSink {
    func log(
        level: LogType,
        tag: FollowUpTag,
        message: String,
        file: String,
        line: Int
    ) {
        // Forward to the host app's crash reporter or analytics pipeline.
        // Keep this fast — sinks fire on the calling thread.
    }
}

HaapiLogger.add(sink: MyLogSink())

See Logging and Observability for the full sink contract and ordering guarantees.

Was this helpful?