33
44import OSLog
55
6- open class Logging {
7- public static let shared = Logging ( )
8- public var logLevel : LogLevel = . none
6+ public enum Logging : Sendable {
97
10- public typealias LoggingCallback = ( _ message: String ) -> Void
11- public var loggingCallback : LoggingCallback ?
8+ // MARK: - Helper Types
129
13- private let logger = OSLog ( subsystem : Bundle . main . bundleIdentifier ?? " com.argmax.whisperkit " , category : " WhisperKit " )
10+ public typealias LoggingCallback = @ Sendable ( _ message : String ) -> Void
1411
15- @frozen
16- public enum LogLevel : Int {
12+ public enum LogLevel : Int , Sendable , Comparable {
1713 case debug = 1
1814 case info = 2
1915 case error = 3
2016 case none = 4
2117
22- func shouldLog( level: LogLevel ) -> Bool {
23- return self . rawValue <= level. rawValue
18+ var osLogType : OSLogType {
19+ switch self {
20+ case . debug: return . debug
21+ case . info: return . info
22+ case . error: return . error
23+ case . none: return . default
24+ }
25+ }
26+
27+ public static func < ( lhs: LogLevel , rhs: LogLevel ) -> Bool {
28+ lhs. rawValue < rhs. rawValue
2429 }
2530 }
2631
27- private init ( ) { }
32+ private actor Engine {
33+ var level : LogLevel
34+ var callback : LoggingCallback ?
35+ private let logger : Logger
36+
37+ init ( level: LogLevel = . none, callback: LoggingCallback ? = nil ) {
38+ self . level = level
39+ self . callback = callback
40+ self . logger = Logger (
41+ subsystem: Constants . Logging. subsystem,
42+ category: " WhisperKit "
43+ )
44+ }
2845
29- public func log( _ items: Any ... , separator: String = " " , terminator: String = " \n " , type: OSLogType ) {
30- let message = items. map { " \( $0) " } . joined ( separator: separator)
31- if let logger = loggingCallback {
32- logger ( message)
33- } else {
34- os_log ( " %{public}@ " , log: logger, type: type, message)
46+ func updateLogLevel( _ level: LogLevel ) {
47+ self . level = level
3548 }
36- }
3749
38- public static func debug( _ items: Any ... , separator: String = " " , terminator: String = " \n " ) {
39- if shared. logLevel. shouldLog ( level: . debug) {
40- shared. log ( items, separator: separator, terminator: terminator, type: . debug)
50+ func updateCallback( _ callback: LoggingCallback ? ) {
51+ self . callback = callback
4152 }
42- }
4353
44- public static func info( _ items: Any ... , separator: String = " " , terminator: String = " \n " ) {
45- if shared. logLevel. shouldLog ( level: . info) {
46- shared. log ( items, separator: separator, terminator: terminator, type: . info)
54+ func log( level: LogLevel , message: String ) {
55+ guard self . level != . none, self . level <= level else { return }
56+
57+ if let callback {
58+ callback ( message)
59+ } else {
60+ logger. log ( level: level. osLogType, " \( message, privacy: . public) " )
61+ }
4762 }
4863 }
4964
50- public static func error( _ items: Any ... , separator: String = " " , terminator: String = " \n " ) {
51- if shared. logLevel. shouldLog ( level: . error) {
52- shared. log ( items, separator: separator, terminator: terminator, type: . error)
65+ // MARK: - Properties
66+
67+ private static let engine = Engine ( )
68+
69+ public static func isLoggingEnabled( ) async -> Bool {
70+ let level = await engine. level
71+ return level != . none
72+ }
73+
74+ public static func updateLogLevel( _ level: LogLevel ) async {
75+ await engine. updateLogLevel ( level)
76+ }
77+
78+ public static func updateCallback( _ callback: LoggingCallback ? ) async {
79+ await engine. updateCallback ( callback)
80+ }
81+
82+ // MARK: - Convenience
83+
84+ public static func debug( _ message: String ) {
85+ dispatch ( level: . debug, message)
86+ }
87+
88+ public static func info( _ message: String ) {
89+ dispatch ( level: . info, message)
90+ }
91+
92+ public static func error( _ message: String ) {
93+ dispatch ( level: . error, message)
94+ }
95+
96+ private static func dispatch( level: LogLevel , _ message: String ) {
97+ Task ( priority: . utility) {
98+ await engine. log ( level: level, message: message)
5399 }
54100 }
55101}
56102
103+ // MARK: - Memory Usage
104+
57105public extension Logging {
58106 static func logCurrentMemoryUsage( _ message: String ) {
59107 let memoryUsage = getMemoryUsage ( )
@@ -78,15 +126,7 @@ public extension Logging {
78126 }
79127}
80128
81- @available ( * , deprecated, message: " Subject to removal in a future version. Use `Logging.logCurrentMemoryUsage(_:)` instead. " )
82- public func logCurrentMemoryUsage( _ message: String ) {
83- Logging . logCurrentMemoryUsage ( message)
84- }
85-
86- @available ( * , deprecated, message: " Subject to removal in a future version. Use `Logging.getMemoryUsage()` instead. " )
87- public func getMemoryUsage( ) -> UInt64 {
88- return Logging . getMemoryUsage ( )
89- }
129+ // MARK: - Feature Specific Logging
90130
91131extension Logging {
92132 enum AudioEncoding {
@@ -130,14 +170,13 @@ extension Logging {
130170 }
131171
132172 static func formatTimestamp( _ timestamp: Float ) -> String {
133- return String ( format: " %.2f " , timestamp)
173+ String ( format: " %.2f " , timestamp)
134174 }
135175
136176 static func formatTimeWithPercentage( _ time: Double , _ runs: Double , _ fullPipelineDuration: Double ) -> String {
137- let percentage = ( time * 1000 / fullPipelineDuration) * 100 // Convert to percentage
177+ let percentage = ( time * 1000 / fullPipelineDuration) * 100
138178 let runTime = runs > 0 ? time * 1000 / Double( runs) : 0
139179 let formattedString = String ( format: " %8.2f ms / %6.0f runs (%8.2f ms/run) %5.2f%% " , time * 1000 , runs, runTime, percentage)
140180 return formattedString
141181 }
142182}
143-
0 commit comments