跳轉到

Logging and debugging

The SDK reports what it is doing through log entries. You decide where they go: print them, write them to a file, or attach them to a bug report.

Receive logs

Subscribe to Revue.logPublisher on Revue.shared. It publishes a RevueLogEntry for every log line, both from the SDK itself and from its network core. Entries arrive on the main thread, so you can update UI from the subscriber directly.

Each entry has a level, a source (the module that wrote it), a message and a timestamp, plus the file, line and function that produced it when they are known.

import RevueSDK
import Combine

/// Print every SDK log at warning level or above. Entries arrive on the main thread.
@MainActor
final class LogConsole {
    private var subscription: AnyCancellable?

    func start() {
        subscription = Revue.shared.logPublisher
            .filter { $0.level >= .warning }
            .sink { entry in
                print("[\(entry.level.name)] [\(entry.source)] \(entry.message)")
            }
    }

    func stop() {
        subscription = nil
    }
}

Log levels

RevueLogLevel has five levels, from most to least detailed:

Level Raw value Use
trace 0 Detailed tracing, such as network packets
debug 1 Debugging messages
info 2 General information
warning 3 Warnings
error 4 Errors

Choose the levels

Call setLogLevel(_:) on Revue.shared with the levels you want. It takes effect at once, without restarting the SDK, on any thread. Read the current selection from logLevel.

import RevueSDK

/// Choose which log levels to output. It takes effect at once.
func showWarningsAndErrors() {
    Revue.shared.setLogLevel([.warning, .error])
}

/// Turn off all SDK output.
func turnOffSdkLogs() {
    Revue.shared.setLogLevel([])
}

The set is a selection, not a minimum level: [.warning] does not include .error, and [.debug, .error] skips the levels in between. An empty set turns off all SDK output.

The default is [.warning, .error]. The setting covers the network core and the SDK's own log lines. Levels that are not selected are never produced, which also lowers the load on your subscriber. Your app's own print output is not affected.

On iOS, a Broadcast Upload Extension that shares the screen follows the same selection, including changes made while it is sharing. This needs an App Group; without one, the extension logs [.warning, .error]. Extension logs do not reach logPublisher. Read them in Console.app.

Set the levels at startup

Revue.Configuration has no log setting. The selection belongs to the process, so call setLogLevel(_:) before initialize(_:) to see the logs that initialize(_:) writes. Neither initialize(_:) nor destroy(_:) changes it.

import RevueSDK

/// See the logs that `initialize(_:)` writes: choose the levels first. The configuration has no log setting.
@MainActor
func initializeWithDebugLogs(_ configuration: Revue.Configuration) throws {
    Revue.shared.setLogLevel([.debug, .info, .warning, .error])
    try Revue.shared.initialize(configuration)
}