@@ -16,6 +16,13 @@ public enum SupabaseLogLevel: Int, Codable, CustomStringConvertible, Sendable {
1616 }
1717}
1818
19+ @usableFromInline
20+ package enum SupabaseLoggerTaskLocal {
21+ @TaskLocal
22+ @usableFromInline
23+ package static var additionalContext : JSONObject = [ : ]
24+ }
25+
1926public struct SupabaseLogMessage : Codable , CustomStringConvertible , Sendable {
2027 public let system : String
2128 public let level : SupabaseLogLevel
@@ -24,6 +31,7 @@ public struct SupabaseLogMessage: Codable, CustomStringConvertible, Sendable {
2431 public let function : String
2532 public let line : UInt
2633 public let timestamp : TimeInterval
34+ public let additionalContext : JSONObject
2735
2836 @usableFromInline
2937 init (
@@ -33,7 +41,8 @@ public struct SupabaseLogMessage: Codable, CustomStringConvertible, Sendable {
3341 fileID: String ,
3442 function: String ,
3543 line: UInt ,
36- timestamp: TimeInterval
44+ timestamp: TimeInterval ,
45+ additionalContext: JSONObject
3746 ) {
3847 self . system = system
3948 self . level = level
@@ -42,12 +51,17 @@ public struct SupabaseLogMessage: Codable, CustomStringConvertible, Sendable {
4251 self . function = function
4352 self . line = line
4453 self . timestamp = timestamp
54+ self . additionalContext = additionalContext
4555 }
4656
4757 public var description : String {
4858 let date = iso8601Formatter. string ( from: Date ( timeIntervalSince1970: timestamp) )
4959 let file = fileID. split ( separator: " . " , maxSplits: 1 ) . first. map ( String . init) ?? fileID
50- return " \( date) [ \( level) ] [ \( system) ] [ \( file) . \( function) : \( line) ] \( message) "
60+ var description = " \( date) [ \( level) ] [ \( system) ] [ \( file) . \( function) : \( line) ] \( message) "
61+ if !additionalContext. isEmpty {
62+ description += " \n context: \( additionalContext. description) "
63+ }
64+ return description
5165 }
5266}
5367
@@ -68,7 +82,8 @@ extension SupabaseLogger {
6882 message: @autoclosure ( ) -> String ,
6983 fileID: StaticString = #fileID,
7084 function: StaticString = #function,
71- line: UInt = #line
85+ line: UInt = #line,
86+ additionalContext: JSONObject = [ : ]
7287 ) {
7388 let system = " \( fileID) " . split ( separator: " / " ) . first ?? " "
7489
@@ -80,7 +95,11 @@ extension SupabaseLogger {
8095 fileID: " \( fileID) " ,
8196 function: " \( function) " ,
8297 line: line,
83- timestamp: Date ( ) . timeIntervalSince1970
98+ timestamp: Date ( ) . timeIntervalSince1970,
99+ additionalContext: additionalContext. merging (
100+ SupabaseLoggerTaskLocal . additionalContext,
101+ uniquingKeysWith: { _, new in new }
102+ )
84103 )
85104 )
86105 }
@@ -90,38 +109,89 @@ extension SupabaseLogger {
90109 _ message: @autoclosure ( ) -> String ,
91110 fileID: StaticString = #fileID,
92111 function: StaticString = #function,
93- line: UInt = #line
112+ line: UInt = #line,
113+ additionalContext: JSONObject = [ : ]
94114 ) {
95- log ( . verbose, message: message ( ) , fileID: fileID, function: function, line: line)
115+ log (
116+ . verbose,
117+ message: message ( ) ,
118+ fileID: fileID,
119+ function: function,
120+ line: line,
121+ additionalContext: additionalContext
122+ )
96123 }
97124
98125 @inlinable
99126 public func debug(
100127 _ message: @autoclosure ( ) -> String ,
101128 fileID: StaticString = #fileID,
102129 function: StaticString = #function,
103- line: UInt = #line
130+ line: UInt = #line,
131+ additionalContext: JSONObject = [ : ]
104132 ) {
105- log ( . debug, message: message ( ) , fileID: fileID, function: function, line: line)
133+ log (
134+ . debug,
135+ message: message ( ) ,
136+ fileID: fileID,
137+ function: function,
138+ line: line,
139+ additionalContext: additionalContext
140+ )
106141 }
107142
108143 @inlinable
109144 public func warning(
110145 _ message: @autoclosure ( ) -> String ,
111146 fileID: StaticString = #fileID,
112147 function: StaticString = #function,
113- line: UInt = #line
148+ line: UInt = #line,
149+ additionalContext: JSONObject = [ : ]
114150 ) {
115- log ( . warning, message: message ( ) , fileID: fileID, function: function, line: line)
151+ log (
152+ . warning,
153+ message: message ( ) ,
154+ fileID: fileID,
155+ function: function,
156+ line: line,
157+ additionalContext: additionalContext
158+ )
116159 }
117160
118161 @inlinable
119162 public func error(
120163 _ message: @autoclosure ( ) -> String ,
121164 fileID: StaticString = #fileID,
122165 function: StaticString = #function,
123- line: UInt = #line
166+ line: UInt = #line,
167+ additionalContext: JSONObject = [ : ]
124168 ) {
125- log ( . error, message: message ( ) , fileID: fileID, function: function, line: line)
169+ log (
170+ . error,
171+ message: message ( ) ,
172+ fileID: fileID,
173+ function: function,
174+ line: line,
175+ additionalContext: additionalContext
176+ )
177+ }
178+ }
179+
180+ @inlinable
181+ package func trace< R> (
182+ using logger: ( any SupabaseLogger ) ? ,
183+ @_inheritActorContext _ operation: @Sendable ( ) async throws -> R ,
184+ fileID: StaticString = #fileID,
185+ function: StaticString = #function,
186+ line: UInt = #line
187+ ) async rethrows -> R {
188+ logger? . debug ( " begin " , fileID: fileID, function: function, line: line)
189+ defer { logger? . debug ( " end " , fileID: fileID, function: function, line: line) }
190+
191+ do {
192+ return try await operation ( )
193+ } catch {
194+ logger? . debug ( " error: \( error) " , fileID: fileID, function: function, line: line)
195+ throw error
126196 }
127197}
0 commit comments