@@ -1290,46 +1290,58 @@ extension EventLoopFuture where Value: Sendable {
12901290 }
12911291}
12921292
1293+ /// A copy of the InMemoryLogHandler from swift-log, but modified to use NIOLockedValueBox instead of Mutex (for better platform availability).
12931294struct CollectEverythingLogHandler : LogHandler {
12941295 var metadata : Logger . Metadata = [ : ]
1296+ var metadataProvider : Logger . MetadataProvider ?
12951297 var logLevel : Logger . Level = . info
1296- let logStore : LogStore
1298+ private let logStore : LogStore
12971299
1298- final class LogStore : Sendable {
1299- struct Entry {
1300- var level : Logger . Level
1301- var message : String
1302- var metadata : [ String : String ]
1303- }
1304-
1305- private let logs = NIOLockedValueBox < [ Entry ] > ( [ ] )
1300+ /// A struct representing a log entry.
1301+ struct Entry : Sendable , Equatable {
1302+ /// The level we logged at.
1303+ var level : Logger . Level
1304+ /// The message which was logged.
1305+ var message : Logger . Message
1306+ /// The metadata which was logged.
1307+ var metadata : Logger . Metadata
1308+ }
13061309
1307- var allEntries : [ Entry ] {
1308- get {
1309- self . logs. withLockedValue { $0 }
1310- }
1311- set {
1312- self . logs. withLockedValue { $0 = newValue }
1313- }
1314- }
1310+ private final class LogStore : Sendable {
1311+ private let logs : NIOLockedValueBox < [ Entry ] > = . init( [ ] )
13151312
1316- func append( level: Logger . Level , message: Logger . Message , metadata: Logger . Metadata ? ) {
1313+ fileprivate func append( level: Logger . Level , message: Logger . Message , metadata: Logger . Metadata ) {
13171314 self . logs. withLockedValue {
13181315 $0. append (
13191316 Entry (
13201317 level: level,
1321- message: message. description ,
1322- metadata: metadata? . mapValues { $0 . description } ?? [ : ]
1318+ message: message,
1319+ metadata: metadata
13231320 )
13241321 )
13251322 }
13261323 }
1324+
1325+ fileprivate func clear( ) {
1326+ self . logs. withLockedValue {
1327+ $0. removeAll ( )
1328+ }
1329+ }
1330+
1331+ var entries : [ Entry ] {
1332+ self . logs. withLockedValue { $0 }
1333+ }
13271334 }
13281335
1329- init ( logStore: LogStore ) {
1336+ private init ( logStore: LogStore ) {
13301337 self . logStore = logStore
13311338 }
13321339
1340+ /// Create a new ``InMemoryLogHandler``.
1341+ init ( ) {
1342+ self . init ( logStore: . init( ) )
1343+ }
1344+
13331345 func log(
13341346 level: Logger . Level ,
13351347 message: Logger . Message ,
@@ -1339,7 +1351,14 @@ struct CollectEverythingLogHandler: LogHandler {
13391351 function: String ,
13401352 line: UInt
13411353 ) {
1342- self . logStore. append ( level: level, message: message, metadata: self . metadata. merging ( metadata ?? [ : ] ) { $1 } )
1354+ // Start with the metadata provider..
1355+ var mergedMetadata : Logger . Metadata = self . metadataProvider? . get ( ) ?? [ : ]
1356+ // ..merge in self.metadata, overwriting existing keys
1357+ mergedMetadata = mergedMetadata. merging ( self . metadata) { $1 }
1358+ // ..merge in metadata from this log call, overwriting existing keys
1359+ mergedMetadata = mergedMetadata. merging ( metadata ?? [ : ] ) { $1 }
1360+
1361+ self . logStore. append ( level: level, message: message, metadata: mergedMetadata)
13431362 }
13441363
13451364 subscript( metadataKey key: String ) -> Logger . Metadata . Value ? {
@@ -1350,6 +1369,34 @@ struct CollectEverythingLogHandler: LogHandler {
13501369 self . metadata [ key] = newValue
13511370 }
13521371 }
1372+
1373+ /// All logs that have been collected.
1374+ var entries : [ Entry ] {
1375+ self . logStore. entries
1376+ }
1377+
1378+ /// Clear all entries.
1379+ func clear( ) {
1380+ self . logStore. clear ( )
1381+ }
1382+ }
1383+
1384+ extension CollectEverythingLogHandler {
1385+ static func makeLogger(
1386+ logLevel: Logger . Level = . info,
1387+ function: String = #function
1388+ ) -> ( CollectEverythingLogHandler , Logger ) {
1389+ let handler = CollectEverythingLogHandler ( )
1390+
1391+ var logger = Logger (
1392+ label: " \( function) " ,
1393+ factory: { _ in
1394+ handler
1395+ }
1396+ )
1397+ logger. logLevel = logLevel
1398+ return ( handler, logger)
1399+ }
13531400}
13541401
13551402/// A ``HTTPClientResponseDelegate`` that buffers the incoming response parts for the consumer. The consumer can
0 commit comments