1616
1717import OSLog
1818internal import LiveKitWebRTC
19+ internal import LiveKitUniFFI
1920
2021// MARK: - Logger
2122
@@ -108,6 +109,7 @@ public struct PrintLogger: Logger {
108109/// A logger that logs to OSLog
109110/// - Parameter minLevel: The minimum level to log
110111/// - Parameter rtc: Whether to log WebRTC output
112+ /// - Parameter ffi: Whether to log Rust FFI output
111113open class OSLogger : Logger , @unchecked Sendable {
112114 private static let subsystem = " io.livekit.sdk "
113115
@@ -118,15 +120,15 @@ open class OSLogger: Logger, @unchecked Sendable {
118120
119121 private let minLevel : LogLevel
120122
121- public init ( minLevel: LogLevel = . info, rtc: Bool = false ) {
123+ public init ( minLevel: LogLevel = . info, rtc: Bool = false , ffi : Bool = true ) {
122124 self . minLevel = minLevel
123125
124- guard rtc else { return }
126+ if rtc {
127+ startRTCLogForwarding ( minLevel: minLevel)
128+ }
125129
126- let rtcLog = OSLog ( subsystem: Self . subsystem, category: " WebRTC " )
127- rtcLogger. severity = minLevel. rtcSeverity
128- rtcLogger. start { message, severity in
129- os_log ( " %{public}@ " , log: rtcLog, type: severity. osLogType, message)
130+ if ffi {
131+ startFFILogForwarding ( minLevel: minLevel)
130132 }
131133 }
132134
@@ -171,6 +173,33 @@ open class OSLogger: Logger, @unchecked Sendable {
171173 os_log ( " %{public}@ " , log: getOSLog ( for: type) , type: level. osLogType, " \( type) . \( function) \( message) \( metadata) " )
172174 }
173175 }
176+
177+ private func startRTCLogForwarding( minLevel: LogLevel ) {
178+ let rtcLog = OSLog ( subsystem: Self . subsystem, category: " WebRTC " )
179+
180+ rtcLogger. severity = minLevel. rtcSeverity
181+ rtcLogger. start { message, severity in
182+ os_log ( " %{public}@ " , log: rtcLog, type: severity. osLogType, message)
183+ }
184+ }
185+
186+ private func startFFILogForwarding( minLevel: LogLevel ) {
187+ Task ( priority: . utility) { [ weak self] in
188+ guard self != nil else { return } // don't initialize global level when releasing
189+ logForwardBootstrap ( level: minLevel. logForwardFilter)
190+
191+ let ffiLog = OSLog ( subsystem: Self . subsystem, category: " FFI " )
192+ let ffiStream = AsyncStream ( unfolding: logForwardReceive)
193+
194+ for await entry in ffiStream {
195+ guard self != nil else { return }
196+
197+ let message = " \( entry. target) \( entry. message) "
198+
199+ os_log ( " %{public}@ " , log: ffiLog, type: entry. level. osLogType, message)
200+ }
201+ }
202+ }
174203}
175204
176205// MARK: - Loggable
@@ -236,6 +265,15 @@ public enum LogLevel: Int, Sendable, Comparable, CustomStringConvertible {
236265 }
237266 }
238267
268+ var logForwardFilter : LogForwardFilter {
269+ switch self {
270+ case . debug: . debug
271+ case . info: . info
272+ case . warning: . warn
273+ case . error: . error
274+ }
275+ }
276+
239277 @inlinable
240278 public static func < ( lhs: LogLevel , rhs: LogLevel ) -> Bool {
241279 lhs. rawValue < rhs. rawValue
@@ -263,3 +301,15 @@ extension LKRTCLoggingSeverity {
263301 }
264302 }
265303}
304+
305+ extension LogForwardLevel {
306+ var osLogType : OSLogType {
307+ switch self {
308+ case . error: . error
309+ case . warn: . default
310+ case . info: . info
311+ case . debug, . trace: . debug
312+ @unknown default : . debug
313+ }
314+ }
315+ }
0 commit comments