@@ -16,6 +16,13 @@ public enum SupabaseLogLevel: Int, Codable, CustomStringConvertible, Sendable {
16
16
}
17
17
}
18
18
19
+ @usableFromInline
20
+ package enum SupabaseLoggerTaskLocal {
21
+ @TaskLocal
22
+ @usableFromInline
23
+ package static var additionalContext : JSONObject = [ : ]
24
+ }
25
+
19
26
public struct SupabaseLogMessage : Codable , CustomStringConvertible , Sendable {
20
27
public let system : String
21
28
public let level : SupabaseLogLevel
@@ -24,6 +31,7 @@ public struct SupabaseLogMessage: Codable, CustomStringConvertible, Sendable {
24
31
public let function : String
25
32
public let line : UInt
26
33
public let timestamp : TimeInterval
34
+ public let additionalContext : JSONObject
27
35
28
36
@usableFromInline
29
37
init (
@@ -33,7 +41,8 @@ public struct SupabaseLogMessage: Codable, CustomStringConvertible, Sendable {
33
41
fileID: String ,
34
42
function: String ,
35
43
line: UInt ,
36
- timestamp: TimeInterval
44
+ timestamp: TimeInterval ,
45
+ additionalContext: JSONObject
37
46
) {
38
47
self . system = system
39
48
self . level = level
@@ -42,12 +51,17 @@ public struct SupabaseLogMessage: Codable, CustomStringConvertible, Sendable {
42
51
self . function = function
43
52
self . line = line
44
53
self . timestamp = timestamp
54
+ self . additionalContext = additionalContext
45
55
}
46
56
47
57
public var description : String {
48
58
let date = iso8601Formatter. string ( from: Date ( timeIntervalSince1970: timestamp) )
49
59
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
51
65
}
52
66
}
53
67
@@ -68,7 +82,8 @@ extension SupabaseLogger {
68
82
message: @autoclosure ( ) -> String ,
69
83
fileID: StaticString = #fileID,
70
84
function: StaticString = #function,
71
- line: UInt = #line
85
+ line: UInt = #line,
86
+ additionalContext: JSONObject = [ : ]
72
87
) {
73
88
let system = " \( fileID) " . split ( separator: " / " ) . first ?? " "
74
89
@@ -80,7 +95,11 @@ extension SupabaseLogger {
80
95
fileID: " \( fileID) " ,
81
96
function: " \( function) " ,
82
97
line: line,
83
- timestamp: Date ( ) . timeIntervalSince1970
98
+ timestamp: Date ( ) . timeIntervalSince1970,
99
+ additionalContext: additionalContext. merging (
100
+ SupabaseLoggerTaskLocal . additionalContext,
101
+ uniquingKeysWith: { _, new in new }
102
+ )
84
103
)
85
104
)
86
105
}
@@ -90,38 +109,89 @@ extension SupabaseLogger {
90
109
_ message: @autoclosure ( ) -> String ,
91
110
fileID: StaticString = #fileID,
92
111
function: StaticString = #function,
93
- line: UInt = #line
112
+ line: UInt = #line,
113
+ additionalContext: JSONObject = [ : ]
94
114
) {
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
+ )
96
123
}
97
124
98
125
@inlinable
99
126
public func debug(
100
127
_ message: @autoclosure ( ) -> String ,
101
128
fileID: StaticString = #fileID,
102
129
function: StaticString = #function,
103
- line: UInt = #line
130
+ line: UInt = #line,
131
+ additionalContext: JSONObject = [ : ]
104
132
) {
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
+ )
106
141
}
107
142
108
143
@inlinable
109
144
public func warning(
110
145
_ message: @autoclosure ( ) -> String ,
111
146
fileID: StaticString = #fileID,
112
147
function: StaticString = #function,
113
- line: UInt = #line
148
+ line: UInt = #line,
149
+ additionalContext: JSONObject = [ : ]
114
150
) {
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
+ )
116
159
}
117
160
118
161
@inlinable
119
162
public func error(
120
163
_ message: @autoclosure ( ) -> String ,
121
164
fileID: StaticString = #fileID,
122
165
function: StaticString = #function,
123
- line: UInt = #line
166
+ line: UInt = #line,
167
+ additionalContext: JSONObject = [ : ]
124
168
) {
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
126
196
}
127
197
}
0 commit comments