### Use get() to fetch metadata Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md Example demonstrating the instantiation of a provider and the subsequent retrieval of its metadata via the get method. ```swift let provider = Logger.MetadataProvider { ["app": "MyApp", "version": "1.0"] } let metadata = provider.get() print(metadata) // ["app": "MyApp", "version": "1.0"] ``` -------------------------------- ### act Configuration File Example Source: https://github.com/apple/swift-log/blob/main/CONTRIBUTING.md Example content for an .actrc file to set default flags for 'act', such as container architecture and remote name. ```bash --container-architecture=linux/amd64 --remote-name upstream --action-offline-mode ``` -------------------------------- ### Example: Multiplexing with MetadataProvider Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md Demonstrates initializing a multiplex handler while providing a custom metadata provider. ```swift let handlers = [fileHandler, stderrHandler] let provider = Logger.MetadataProvider { ["multiplex": "true"] } let multiplex = MultiplexLogHandler(handlers, metadataProvider: provider) ``` -------------------------------- ### Create a MetadataProvider instance Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md Example of initializing a provider with a closure that generates dynamic metadata. ```swift let provider = Logger.MetadataProvider { ["request-id": "\(UUID())", "timestamp": "\(Date())"] } ``` -------------------------------- ### Bug Report Example Source: https://github.com/apple/swift-log/blob/main/CONTRIBUTING.md An example of a detailed bug report including SwiftLog commit hash, context, reproduction steps, and system information. ```text SwiftLog commit hash: 4fe877816ad82627602377f415b6a66850214824 Context: While testing my application that uses with SwiftLog, I noticed that ... Steps to reproduce: 1. ... 2. ... 3. ... 4. ... $ swift --version Swift version 4.0.2 (swift-4.0.2-RELEASE) Target: x86_64-unknown-linux-gnu Operating system: Ubuntu Linux 16.04 64-bit $ uname -a Linux beefy.machine 4.4.0-101-generic #124-Ubuntu SMP Fri Nov 10 18:29:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux My system has IPv6 disabled. ``` -------------------------------- ### Manual Metadata Logging Example Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md Demonstrates the current method of explicitly passing metadata to each log call. This approach is error-prone and repetitive. ```swift logger.info("first this ...", metadata: ["trace-id": MyTracingLibrary.currentTraceID]) logger.info("... now this", metadata: ["trace-id": MyTracingLibrary.currentTraceID]) ``` -------------------------------- ### Entry equality check Source: https://github.com/apple/swift-log/blob/main/_autodocs/in-memory-log-handler.md Example demonstrating equality comparison for Entry values. ```swift let entry1 = InMemoryLogHandler.Entry(level: .info, message: "Hello", metadata: ["id": "1"]) let entry2 = InMemoryLogHandler.Entry(level: .info, message: "Hello", metadata: ["id": "1"]) assert(entry1 == entry2) ``` -------------------------------- ### get() Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md Invokes the metadata provider closure and returns the generated metadata dictionary. ```APIDOC ## get() ### Description Invokes the metadata provider closure and returns the generated metadata dictionary. ### Returns - **Logger.Metadata** - A dictionary containing the metadata provided by the closure. ### Example ```swift let provider = Logger.MetadataProvider { ["app": "MyApp", "version": "1.0"] } let metadata = provider.get() print(metadata) // ["app": "MyApp", "version": "1.0"] ``` ``` -------------------------------- ### Use withLogger for scoped logging Source: https://github.com/apple/swift-log/blob/main/_autodocs/task-local-logger.md Example demonstrating how to use an in-memory handler for a specific block of code. ```swift // Use in-memory handler for this scope let memHandler = InMemoryLogHandler() try withLogger(handler: memHandler, logLevel: .debug) { logger in logger.debug("Captured in memory") let captured = memHandler.entries } ``` -------------------------------- ### Configure metadata attributes Source: https://github.com/apple/swift-log/blob/main/_autodocs/logger.md Example of defining and assigning a custom attribute to metadata. ```swift public enum Sensitivity: Int64, Logger.MetadataValueAttributes.Attribute { case `public` = 1 case sensitive = 2 } var attributes = Logger.MetadataValueAttributes() attributes[Sensitivity.self] = .sensitive ``` -------------------------------- ### get() Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Reference/Logger-MetadataProvider.md Retrieves the current metadata from the provider. ```APIDOC ## get() ### Description Invokes the provider to retrieve the current set of metadata. ``` -------------------------------- ### Basic Logger Usage Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/index.md Import the Logging API and create a logger instance with a unique label to start logging messages. ```swift // Import the logging API import Logging // Create a logger with a label let logger = Logger(label: "MyLogger") // Use it to log messages logger.info("Hello World!") ``` -------------------------------- ### Service Lifecycle Integration Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0006-task-local-logger.md Example of binding a logger at the application entry point to propagate it through a service group. ```swift @main struct MyServer { static func main() async throws { let logger = Logger(label: "my-server") try await withLogger(logger) { _ in let serviceGroup = ServiceGroup( configuration: .init( services: [HTTPServer(), BackgroundWorker()], gracefulShutdownSignals: [.sigint], cancellationSignals: [.sigterm], logger: logger ) ) try await serviceGroup.run() } } } ``` -------------------------------- ### Example Log Statement with One-Off Metadata Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md Demonstrates how to add one-off metadata to a log statement. This metadata is merged with any metadata provided by the configured MetadataProvider. ```swift var baggage = Baggage.topLevel baggage.spanContext = SpanContext() Baggage.withValue(baggage) { test() } func test() { log.info("Test", metadata: ["oneOff": "42"]) // info [traceID: abc, spanID: 123, onOff: 42] Test } ``` -------------------------------- ### Example: Multiplexing Log Handlers Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md Demonstrates creating a multiplex handler with file and stderr outputs. The effective log level is automatically set to the most permissive level among the handlers. ```swift let fileHandler = FileLogHandler(label: "app", path: "/var/log/app.log") fileHandler.logLevel = .debug let stderrHandler = StreamLogHandler.standardError(label: "app") stderrHandler.logLevel = .warning let multiplex = MultiplexLogHandler([fileHandler, stderrHandler]) // multiplex.logLevel is now .debug (the minimum) ``` -------------------------------- ### Implement Custom Metadata Attributes Source: https://github.com/apple/swift-log/blob/main/_autodocs/types.md Examples of conforming to the Attribute protocol using both enums and structs. ```swift public enum Sensitivity: Int64, Sendable, Logger.MetadataValueAttributes.Attribute { case `public` = 1 case sensitive = 2 } public struct Priority: Sendable, Hashable, Logger.MetadataValueAttributes.Attribute { public let rawValue: Int64 public init(rawValue: Int64) { self.rawValue = rawValue } public static let low = Priority(rawValue: 1) public static let high = Priority(rawValue: 2) } ``` -------------------------------- ### Apply sensitivity attributes to metadata Source: https://github.com/apple/swift-log/blob/main/_autodocs/types.md Example of attaching sensitivity attributes to metadata values during initialization. ```swift let metadata: Logger.Metadata = [ "user-id": "\(userId, sensitivity: .public)", "api-key": "\(apiKey, sensitivity: .sensitive)" ] ``` -------------------------------- ### init(_:) Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Reference/Logger-MetadataProvider.md Initializes a new MetadataProvider instance. ```APIDOC ## init(_:) ### Description Initializes a new MetadataProvider with a closure that returns metadata. ### Parameters - **closure** (() -> Logger.Metadata) - Required - A closure that returns the metadata to be provided. ``` -------------------------------- ### Configure Metadata Provider and Logger Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md Demonstrates bootstrapping the logging system with a metadata provider and setting handler-level metadata. ```swift // Set up providers let systemProvider = Logger.MetadataProvider { ["environment": "prod", "app": "MyApp"] } LoggingSystem.bootstrap( { label, _ in StreamLogHandler.standardError(label: label, metadataProvider: systemProvider) }, metadataProvider: systemProvider ) var logger = Logger(label: "app") logger[metadataKey: "service"] = "api" // Handler metadata // This log call: logger.info("Request received", metadata: ["request-id": "123"]) ``` -------------------------------- ### Initializing the Logging System Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Reference/LoggingSystem.md Provides methods to bootstrap the logging system, optionally with custom metadata. ```APIDOC ## Initializing the Logging System ### Methods - ``bootstrap(_:)`` - ``bootstrap(_:metadataProvider:)`` ### Description These methods are used to initialize the logging system. The `bootstrap(_:)` method initializes with default metadata, while `bootstrap(_:metadataProvider:)` allows for a custom metadata provider. ``` -------------------------------- ### init(_:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md Initializes a new MetadataProvider with a closure that generates metadata. ```APIDOC ## init(_:) ### Description Creates a new metadata provider with a closure that generates metadata. ### Parameters - **provideMetadata** (@escaping @Sendable () -> Logger.Metadata) - Required - A closure that returns metadata as a dictionary. Must be sendable. ### Example ```swift let provider = Logger.MetadataProvider { ["request-id": "\(UUID())", "timestamp": "\(Date())"] } ``` ``` -------------------------------- ### Logger.MetadataValue.attributes Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0004-metadata-value-attributes.md A computed property on Logger.MetadataValue to get or set attributes associated with the value. ```APIDOC ## Logger.MetadataValue.attributes ### Description The attributes associated with this metadata value. Getting returns attributes for attributed carriers; setting replaces the value with an attributed carrier while preserving string representations where applicable. ``` -------------------------------- ### Bootstrap the Logging System Source: https://github.com/apple/swift-log/blob/main/_autodocs/INDEX.md Configure the logging backend during application startup. This must be called exactly once early in the application lifecycle. ```swift // Minimal bootstrap LoggingSystem.bootstrap(StreamLogHandler.standardError) // With metadata provider let provider = Logger.MetadataProvider { ["env": "prod"] } LoggingSystem.bootstrap( { label, mdProvider in StreamLogHandler.standardError(label: label, metadataProvider: mdProvider) }, metadataProvider: provider ) // Important: Call only once, early in application startup ``` -------------------------------- ### init(_:metadataProvider:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md Initializes a new MultiplexLogHandler with a collection of log handlers and an optional metadata provider. ```APIDOC ## init(_ handlers: [any LogHandler], metadataProvider: Logger.MetadataProvider?) ### Description Creates a multiplex handler with a custom metadata provider applied on top of underlying handlers' providers. ### Parameters - **handlers** ([any LogHandler]) - Required - An array of LogHandlers. Must not be empty. - **metadataProvider** (Logger.MetadataProvider?) - Optional - A metadata provider for this multiplex handler. ### Example ```swift let provider = Logger.MetadataProvider { ["multiplex": "true"] } let multiplex = MultiplexLogHandler(handlers, metadataProvider: provider) ``` ``` -------------------------------- ### Access MetadataValue attributes Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0004-metadata-value-attributes.md Computed property for getting or setting attributes on a MetadataValue instance. ```swift extension Logger.MetadataValue { /// The attributes associated with this metadata value, if any. /// /// **Getting:** When the value is a ``stringConvertible(_:)`` wrapping an attributed carrier, /// returns that carrier's attributes. For all other cases returns empty attributes. /// /// **Setting:** Replaces the value with `.stringConvertible(AttributedStringCarrier(...))` /// carrying the given attributes. For `.string` and `.stringConvertible` cases the string /// representation is preserved. For `.dictionary` and `.array` cases the setter is a no-op. public var attributes: Logger.MetadataValueAttributes { get set } } ``` -------------------------------- ### init(_:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md Initializes a new MultiplexLogHandler with a collection of log handlers. ```APIDOC ## init(_ handlers: [any LogHandler]) ### Description Creates a multiplex handler that routes logs to all provided handlers. The effective log level is automatically set to the minimum (most permissive) of all underlying handlers. ### Parameters - **handlers** ([any LogHandler]) - Required - An array of LogHandlers. Must not be empty. ### Example ```swift let multiplex = MultiplexLogHandler([fileHandler, stderrHandler]) ``` ``` -------------------------------- ### Access Metadata by Key Source: https://github.com/apple/swift-log/blob/main/_autodocs/stream-log-handler.md Uses the subscript to get or set individual metadata items by their key. ```swift var handler = StreamLogHandler.standardError(label: "app") handler[metadataKey: "request-id"] = "\(UUID())" ``` -------------------------------- ### Configure System-Wide Metadata Provider Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Initializes a static metadata provider and bootstraps the logging system to include these values in all log entries. ```swift let provider = Logger.MetadataProvider { [ "version": "1.0.0", "environment": "production" ] } LoggingSystem.bootstrap( { label, mdProvider in StreamLogHandler.standardError(label: label, metadataProvider: mdProvider) }, metadataProvider: provider ) ``` -------------------------------- ### Run Benchmarks Source: https://github.com/apple/swift-log/blob/main/CONTRIBUTING.md Command to run benchmarks for swift-log from the Benchmarks subfolder. ```bash swift package benchmark ``` -------------------------------- ### LoggingSystem.bootstrap(_:metadataProvider:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/logging-system.md Configures the global logging backend with both a custom handler factory and a system-wide metadata provider. ```APIDOC ## static func bootstrap(_ factory: @escaping @Sendable (String, Logger.MetadataProvider?) -> any LogHandler, metadataProvider: Logger.MetadataProvider?) ### Description Configures the global logging backend with both a custom handler factory and a system-wide metadata provider. This method can only be called once per process. ### Parameters - **factory** ((String, Logger.MetadataProvider?) -> any LogHandler) - Required - A closure that receives a logger label and the system metadata provider, returning a configured LogHandler. - **metadataProvider** (Logger.MetadataProvider?) - Optional - A metadata provider that automatically injects contextual metadata into all logs. ### Example ```swift LoggingSystem.bootstrap( { label, provider in StreamLogHandler.standardError(label: label, metadataProvider: provider) }, metadataProvider: metadataProvider ) ``` -------------------------------- ### Bootstrap Logging System with Metadata Provider Only Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md Bootstrap the logging system with only a metadata provider, useful when custom log handlers are configured separately. ```swift LoggingSystem.bootstrapMetadataProvider(.myTracer) ``` -------------------------------- ### subscript(metadataKey:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/in-memory-log-handler.md Allows getting or setting individual metadata items associated with the log handler by their key. ```APIDOC ## public subscript(metadataKey key: String) -> Logger.Metadata.Value? ### Description Get or set individual metadata items by key. ``` -------------------------------- ### Initialize metadata using literals Source: https://github.com/apple/swift-log/blob/main/_autodocs/types.md Demonstrates creating metadata using string interpolation, array literals, and dictionary literals. ```swift // String interpolation (preferred) let meta: Logger.Metadata = [ "user-id": "\(userId)", "count": "\(items.count)" ] // Array literal let arrayMeta: Logger.MetadataValue = ["item1", "item2", "item3"] // Dictionary literal let dictMeta: Logger.MetadataValue = ["nested": ["key": "value"]] ``` -------------------------------- ### Define MetadataProvider structure Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md The internal structure definition for the MetadataProvider, including the closure-based metadata provider and the get method. ```swift public struct MetadataProvider: Sendable { @usableFromInline internal let _provideMetadata: @Sendable () -> Metadata public init(_ provideMetadata: @escaping @Sendable () -> Metadata) public func get() -> Metadata } ``` -------------------------------- ### Configure Multi-Handler Logging Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Demonstrates initializing the logging system with multiple handlers and a custom metadata provider. Ensure this is called early in the application lifecycle before creating loggers. ```swift import Logging import InMemoryLogging // Set up multiple handlers for different purposes var debugHandler = StreamLogHandler.standardError(label: "app") debugHandler.logLevel = .debug debugHandler[metadataKey: "destination"] = "console" var testHandler = InMemoryLogHandler() testHandler.logLevel = .trace // Combine with multiplex let multiplex = MultiplexLogHandler([debugHandler, testHandler]) // Set metadata provider let provider = Logger.MetadataProvider { ["timestamp": "\(Date())", "pid": "\(ProcessInfo.processInfo.processIdentifier)"] } // Bootstrap LoggingSystem.bootstrap( { label, mdProvider in multiplex }, metadataProvider: provider ) // Use let logger = Logger(label: "myapp") logger.logLevel = .info logger[metadataKey: "service"] = "backend" logger.info("Application started") logger.debug("Debug details") // Only in memory handler and stderr logger.warning("Watch out") // In both handlers ``` -------------------------------- ### Scoped Logger Modification Example Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0006-task-local-logger.md Demonstrates using withLogger to replace inherited metadata within a nested scope. ```swift withLogger(mergingMetadata: ["request.id": "\(request.id)"]) { _ in // Background job: start a scope with metadata unrelated to the request. withLogger(metadata: ["job.id": "\(job.id)"]) { logger in logger.info("running") // metadata: job.id only — request.id wiped } } ``` -------------------------------- ### Bootstrap Logging System with Metadata Provider Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md Configure a global metadata provider when bootstrapping the logging system. This provider will be used by all log handlers unless overridden. ```swift LoggingSystem.bootstrap( metadataProvider: .myTracer, StreamLogHandler.standardOutput ) ``` -------------------------------- ### Define Custom Attribute Protocol Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0004-metadata-value-attributes.md Defines the Attribute protocol and provides examples for implementing it using enums or structs. ```swift extension Logger.MetadataValueAttributes { /// A protocol for defining custom metadata attributes. /// /// Conform to this protocol to define a custom attribute that can be stored in /// ``MetadataValueAttributes``. Each conforming type acts as both the key (identified /// by its metatype) and the value. /// /// This protocol is designed for **small, fixed-vocabulary attributes**. /// Each attribute value is stored as an `Int64` raw value, so attributes occupy minimal /// space (one inline slot without heap allocation for the common single-attribute case). /// /// ## Examples /// /// ```swift /// public enum Priority: Int64, Sendable, Logger.MetadataValueAttributes.Attribute { /// case low = 1 /// case high = 2 /// } /// ``` /// /// ```swift /// public struct Priority: Sendable, Hashable, Logger.MetadataValueAttributes.Attribute { /// public let rawValue: Int64 /// public init(rawValue: Int64) { /// self.rawValue = rawValue /// } /// public static let low = Priority(rawValue: 1) /// public static let high = Priority(rawValue: 2) /// } /// ``` public protocol Attribute: Sendable, RawRepresentable where RawValue == Int64 {} } ``` -------------------------------- ### Bootstrap and Log Messages in Swift Source: https://github.com/apple/swift-log/blob/main/_autodocs/INDEX.md Initializes the logging system using a standard error stream and demonstrates logging at various severity levels. ```swift import Logging // Bootstrap system (once, at startup) LoggingSystem.bootstrap(StreamLogHandler.standardError) // Create a logger let logger = Logger(label: "com.example.app") // Log at different levels logger.trace("Detailed trace") logger.debug("Debug information") logger.info("Informational message") logger.notice("Notable event") logger.warning("Warning condition") logger.error("Error condition") logger.critical("Critical failure") ``` -------------------------------- ### Logging with metadata Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0004-metadata-value-attributes.md Example of a log statement where specific metadata values lack context for handlers regarding privacy or redaction. ```swift logger.info("Login", metadata: [ "action": "\(action)", // safe to log "user_email": "\(email)", // should be redacted in production, but nothing tells the handler ]) ``` -------------------------------- ### Configure and use MultiplexLogHandler Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md Demonstrates initializing multiple StreamLogHandlers with distinct configurations and combining them into a single MultiplexLogHandler for the logging system. ```swift import Logging // Create multiple handlers with different configurations var fileHandler = StreamLogHandler.standardError(label: "app") fileHandler.logLevel = .debug fileHandler[metadataKey: "destination"] = "file" var stderrHandler = StreamLogHandler.standardError(label: "app") stderrHandler.logLevel = .warning stderrHandler[metadataKey: "destination"] = "stderr" // Combine them let multiplex = MultiplexLogHandler([fileHandler, stderrHandler]) // Bootstrap LoggingSystem.bootstrap { label in multiplex } // Use let logger = Logger(label: "myapp") logger.debug("Details") // Only to file (above file threshold, below stderr) logger.warning("Problem") // To both handlers ``` -------------------------------- ### Initialize with MetadataProvider Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md The initializer signature for creating a multiplex handler with a custom metadata provider. ```swift public init(_ handlers: [any LogHandler], metadataProvider: Logger.MetadataProvider?) ``` -------------------------------- ### Initialize MetadataProvider Source: https://github.com/apple/swift-log/blob/main/_autodocs/metadata-provider.md The initializer signature for creating a new metadata provider instance. ```swift public init(_ provideMetadata: @escaping @Sendable () -> Metadata) ``` -------------------------------- ### Create attributed metadata values Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0004-metadata-value-attributes.md Factory method and usage example for creating attributed metadata values without string interpolation. ```swift extension Logger.MetadataValue { /// Creates an attributed metadata value from a string-convertible value and attributes. public static func attributed( _ value: some CustomStringConvertible & Sendable, attributes: Logger.MetadataValueAttributes ) -> Self } ``` ```swift let value: Logger.MetadataValue = .attributed(userId, attributes: [Sensitivity.sensitive]) ``` -------------------------------- ### Configure and Export SwiftLog Targets Source: https://github.com/apple/swift-log/blob/main/cmake/modules/CMakeLists.txt Sets up the export file path, configures the package configuration file, and exports the project targets. ```cmake set(SwiftLog_EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/SwiftLogExports.cmake) configure_file(SwiftLogConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/SwiftLogConfig.cmake) get_property(SwiftLog_EXPORTS GLOBAL PROPERTY SwiftLog_EXPORTS) export(TARGETS ${SwiftLog_EXPORTS} FILE ${SwiftLog_EXPORTS_FILE}) ``` -------------------------------- ### Bootstrap with MetadataProvider Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Configures both the handler factory and a system-wide metadata provider. The factory must pass the provider to the created handlers. ```swift let contextProvider = Logger.MetadataProvider { ["timestamp": "\(Date())"] } LoggingSystem.bootstrap( { label, provider in StreamLogHandler.standardError(label: label, metadataProvider: provider) }, metadataProvider: contextProvider ) ``` -------------------------------- ### Custom Error Handling in LogHandler Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0003.md An example implementation of a `LogHandler` that customizes how errors are logged. It demonstrates accessing the `Error` object and serializing its message and type as metadata. ```swift struct ErrorLogHandler: LogHandler { func log( level: Logger.Level, message: Logger.Message, error: (any Error)?, metadata: Logger.Metadata?, source: String, file: String, function: String, line: UInt ) { var metadata = metadata ?? [: ] if let error { metadata.merge([ "error.message": "\(error)", "error.type": "\(String(reflecting: type(of: error)))", ]) { $1 } } // ... } /* ... */ } ``` -------------------------------- ### Configuring LogHandlers for Performance Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Shows how to filter log levels early and use a no-op handler for zero-overhead logging. ```swift var handler = StreamLogHandler.standardError(label: "app") handler.logLevel = .warning // Filter early to avoid processing debug logs // For performance-critical code LoggingSystem.bootstrap { _ in SwiftLogNoOpLogHandler() // No-op handler with zero overhead } ``` -------------------------------- ### Logging Ad-Hoc Item Name Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md This example demonstrates logging an ad-hoc, structured log entry with an item name that is not intended to be queried elsewhere or set in baggage metadata. ```swift log.info("Obtained item! Hooray!", metadata: ["item": "\(item)"]) ``` -------------------------------- ### LoggingSystem.bootstrap(_:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/logging-system.md Configures the global logging backend by providing a factory closure that creates LogHandler instances for each logger label. ```APIDOC ## static func bootstrap(_ factory: @escaping @Sendable (String) -> any LogHandler) ### Description Configures the global logging backend by providing a factory closure that creates LogHandler instances for each logger label. This method can only be called once per process. ### Parameters - **factory** ((String) -> any LogHandler) - Required - A closure that receives a logger label and returns a configured LogHandler instance. ### Example ```swift LoggingSystem.bootstrap(StreamLogHandler.standardError) let logger = Logger(label: "com.example.app") logger.info("This uses the bootstrapped handler") ``` ``` -------------------------------- ### init() Source: https://github.com/apple/swift-log/blob/main/_autodocs/in-memory-log-handler.md Initializes a new instance of the InMemoryLogHandler with empty storage. ```APIDOC ## init() ### Description Creates a new in-memory log handler with empty storage, ready to receive log messages. ### Signature `public init()` ### Example ```swift let handler = InMemoryLogHandler() let logger = Logger(label: "test", handler: handler) logger.info("Test message") ``` ``` -------------------------------- ### Correlating Logs with Baggage Trace ID Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md When a Baggage value with a trace ID surrounds log statements, they are automatically correlatable. This example shows how to set a trace ID in Baggage and then log events within that context. ```swift var baggage = Baggage.topLevel baggage.traceID = 42 Baggage.$current.withValue(baggage) { logger.info("Product fetched.", metadata: ["productId": "42"]) logger.info("Product purchased.", metadata: ["paymentMethod": "apple-pay"]) } // [trace-id: 42, productId: 42] Product fetched. // [trace-id: 42, paymentMethod: apple-pay] Product fetched. ``` -------------------------------- ### Specify Max Log Level Trait in Package.swift Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/DisableLogLevelsDuringCompilation.md Declare a package dependency with a specific maximum log level trait to control which log levels are compiled into your binary. This example sets the maximum level to Warning. ```swift // In your Package.swift: dependencies: [ .package( url: "https://github.com/apple/swift-log.git", from: "1.0.0", traits: ["MaxLogLevelWarning"] ) ] ``` -------------------------------- ### init(label:stream:metadataProvider:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/stream-log-handler.md Initializes a new StreamLogHandler with a specified label, output stream, and custom metadata provider. ```APIDOC ## init(label:stream:metadataProvider:) ### Description Creates a log handler for a custom text stream with a custom metadata provider. ### Parameters - **label** (String) - Required - The logger label identifier - **stream** (any TextOutputStream & Sendable) - Required - A sendable text output stream - **metadataProvider** (Logger.MetadataProvider?) - Optional - Custom metadata provider for this handler ### Example ```swift var output = FileOutputStream(path: "/var/log/app.log") let provider = Logger.MetadataProvider { ["environment": "production"] } let handler = StreamLogHandler(label: "app", stream: output, metadataProvider: provider) ``` ``` -------------------------------- ### Configure Production Logging Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Uses a MetadataProvider to inject environment details and configures a warning-level log handler. ```swift import Logging let provider = Logger.MetadataProvider { [ "version": "1.2.3", "environment": "production", "hostname": ProcessInfo.processInfo.hostName ] } LoggingSystem.bootstrap( { label, mdProvider in StreamLogHandler.standardError(label: label, metadataProvider: mdProvider) }, metadataProvider: provider ) var logger = Logger(label: "app") logger.logLevel = .warning // Only warnings and above ``` -------------------------------- ### init(label:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/logger.md Creates a new Logger instance with a unique label identifier. ```APIDOC ## init(label:) ### Description Creates a new `Logger` with the specified label using the global logging system's configured handler. ### Parameters - **label** (String) - Required - A unique identifier for this logger, typically a module name or subsystem identifier. ### Example ```swift let logger = Logger(label: "com.example.app") logger.info("Application started") ``` ``` -------------------------------- ### init(label:stream:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/stream-log-handler.md Initializes a new StreamLogHandler with a specified label and output stream. ```APIDOC ## init(label:stream:) ### Description Creates a log handler for a custom text stream using the system metadata provider. ### Parameters - **label** (String) - Required - The logger label identifier - **stream** (any TextOutputStream & Sendable) - Required - A sendable text output stream ### Example ```swift var customStream = FileOutputStream(path: "/tmp/app.log") let handler = StreamLogHandler(label: "app", stream: customStream) ``` ``` -------------------------------- ### Manually Populating Logger with Trace Metadata Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0001-metadata-providers.md Illustrates the manual process of populating a logger with trace metadata when explicit metadata providers are not available. This requires careful management to avoid losing contextual information. ```swift import Tracing import Logging let contextualLogger = InstrumentationSystem.tracer.populateTraceMetadata(logger) contextualLogger.info("Request received.") ``` -------------------------------- ### Initialize and use InMemoryLogHandler Source: https://github.com/apple/swift-log/blob/main/_autodocs/in-memory-log-handler.md Demonstrates creating a handler, attaching it to a logger, and accessing the collected entries. ```swift let handler = InMemoryLogHandler() let logger = Logger(label: "test", handler: handler) logger.info("Test message") print(handler.entries) // Access collected logs ``` -------------------------------- ### init(level:message:metadata:source:file:function:line:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/log-event.md Creates a log event without an associated error. ```APIDOC ## init(level:message:metadata:source:file:function:line:) ### Description Creates a log event without an associated error. ### Parameters - **level** (Logger.Level) - Required - The severity level of the event - **message** (Logger.Message) - Required - The log message - **metadata** (Logger.Metadata?) - Optional - Optional metadata for this event - **source** (String?) - Optional - Source module (derived from file if nil) - **file** (String) - Required - The source file path - **function** (String) - Required - The function name - **line** (UInt) - Required - The line number ### Example ```swift let event = LogEvent( level: .info, message: "User logged in", metadata: ["user-id": "42"], source: nil, file: "AuthService.swift", function: "handleLogin()", line: 127 ) ``` ``` -------------------------------- ### Configure StreamLogHandler Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Bootstraps the logging system to use standard output, standard error, or custom file streams. ```swift LoggingSystem.bootstrap(StreamLogHandler.standardOutput) ``` ```swift LoggingSystem.bootstrap(StreamLogHandler.standardError) ``` ```swift var stream = FileOutputStream(path: "/var/log/app.log") let handler = StreamLogHandler(label: "app", stream: stream) LoggingSystem.bootstrap { label in StreamLogHandler(label: label, stream: stream) } ``` ```swift let provider = Logger.MetadataProvider { ["environment": "production"] } LoggingSystem.bootstrap( { label, mdProvider in StreamLogHandler.standardError(label: label, metadataProvider: mdProvider) }, metadataProvider: provider ) ``` -------------------------------- ### Bootstrapping for Testing Source: https://github.com/apple/swift-log/blob/main/_autodocs/logging-system.md Configures the logging system to use an in-memory handler for testing purposes. ```swift LoggingSystem.bootstrap { label in InMemoryLogHandler() } ``` -------------------------------- ### Logger Initialization Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Reference/Logger.md Methods for creating new Logger instances. ```APIDOC ### init(label:) Initializes a new logger with a specific label. ### init(label:metadataProvider:) Initializes a new logger with a label and a metadata provider. ``` -------------------------------- ### Create and Use Loggers Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/UnderstandingLoggers.md Instantiate a logger and emit messages at different severity levels like info and error. ```swift logger.info("Processing request") // Something went wrong logger.error("Houston, we have a problem") ``` -------------------------------- ### Initialize a Logger Source: https://github.com/apple/swift-log/blob/main/_autodocs/logger.md Create a new Logger instance with a unique label to begin emitting log messages. ```swift let logger = Logger(label: "com.example.app") logger.info("Application started") ``` -------------------------------- ### View Source Code Organization Source: https://github.com/apple/swift-log/blob/main/_autodocs/INDEX.md Displays the directory structure of the swift-log repository. ```text Sources/Logging/ ├── Logger.swift (main Logger implementation) ├── LoggingSystem.swift (bootstrap) ├── LogHandler.swift (protocol definition) ├── LogEvent.swift (log event data) ├── MetadataProvider.swift (automatic metadata) ├── Logger+Attributes.swift (metadata attributes) ├── Logger+With.swift (task-local utilities) ├── Locks.swift (internal synchronization) └── Handlers/ ├── StreamLogHandler.swift (default handler) ├── MultiplexLogHandler.swift (multi-destination) └── SwiftLogNoOpLogHandler.swift (no-op) Sources/InMemoryLogging/ └── InMemoryLogHandler.swift (test handler) ``` -------------------------------- ### init(level:message:error:metadata:source:file:function:line:) Source: https://github.com/apple/swift-log/blob/main/_autodocs/log-event.md Creates a log event with an associated error. ```APIDOC ## init(level:message:error:metadata:source:file:function:line:) ### Description Creates a log event with an associated error. ### Parameters - **level** (Logger.Level) - Required - The severity level of the event - **message** (Logger.Message) - Required - The log message - **error** ((any Error)?) - Optional - An optional Error associated with this event - **metadata** (Logger.Metadata?) - Optional - Optional metadata for this event - **source** (String?) - Optional - Source module (derived from file if nil) - **file** (String) - Required - The source file path - **function** (String) - Required - The function name - **line** (UInt) - Required - The line number ### Example ```swift let event = LogEvent( level: .error, message: "Request failed", error: networkError, metadata: ["request-id": "abc123"], source: "NetworkLayer", file: "HTTPClient.swift", function: "performRequest()", line: 234 ) ``` ``` -------------------------------- ### LoggingSystem.metadataProvider Source: https://github.com/apple/swift-log/blob/main/_autodocs/logging-system.md Retrieves the system-wide metadata provider that was configured during the bootstrap process. ```APIDOC ## static var metadataProvider: Logger.MetadataProvider? ### Description Returns the system-wide metadata provider that was configured during bootstrap, if any. ### Returns The `Logger.MetadataProvider` configured at bootstrap, or `nil` if none was configured. ``` -------------------------------- ### Entry initializers Source: https://github.com/apple/swift-log/blob/main/_autodocs/in-memory-log-handler.md Initializers for creating log entries with or without associated errors. ```swift public init(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata) ``` ```swift public init(level: Logger.Level, message: Logger.Message, error: (any Error)?, metadata: Logger.Metadata) ``` -------------------------------- ### Bootstrap logging with standardOutput Source: https://github.com/apple/swift-log/blob/main/_autodocs/stream-log-handler.md Configures the logging system to use standard output for log messages. ```swift LoggingSystem.bootstrap(StreamLogHandler.standardOutput) let logger = Logger(label: "app") logger.info("Output goes to stdout") ``` -------------------------------- ### Initialize MultiplexLogHandler Source: https://github.com/apple/swift-log/blob/main/_autodocs/multiplex-log-handler.md The initializer signature for creating a multiplex handler. ```swift public init(_ handlers: [any LogHandler]) ``` -------------------------------- ### Implement metadataProvider support Source: https://github.com/apple/swift-log/blob/main/_autodocs/log-handler.md Allows automatic injection of contextual metadata into logs. ```swift var metadataProvider: Logger.MetadataProvider? { get set } ``` ```swift var metadataProvider: Logger.MetadataProvider? func log(event: LogEvent) { var allMetadata = self.metadata if let provider = self.metadataProvider { let provided = provider.get() allMetadata.merge(provided, uniquingKeysWith: { _, rhs in rhs }) } if let eventMetadata = event.metadata { allMetadata.merge(eventMetadata, uniquingKeysWith: { _, rhs in rhs }) } // Log with merged metadata } ``` -------------------------------- ### Library Logging: Trace, Debug, and Info Levels Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/BestPractices/001-ChoosingLogLevels.md Libraries should primarily use trace, debug, and info levels for logging. Trace is for detailed diagnostics, debug for high-level operational information, and info for issues not expressible through other means. ```swift logger.trace("Connection pool state", metadata: [ "active": "\(activeConnections)", "idle": "\(idleConnections)", "pending": "\(pendingRequests)" ]) ``` ```swift logger.debug("Database connection established", metadata: [ "host": "\(host)", "database": "\(database)", "connectionTime": "\(duration)" ]) ``` ```swift logger.info("Connection failed, retrying", metadata: [ "attempt": "\(attemptNumber)", "maxRetries": "\(maxRetries)", "host": "\(host)" ]) ``` -------------------------------- ### Configure Multiple Log Handlers in Swift Source: https://github.com/apple/swift-log/blob/main/_autodocs/INDEX.md Initializes the logging system with a multiplexer to route log messages to multiple destinations simultaneously. ```swift let fileHandler = StreamLogHandler.standardError(label: "app") let memHandler = InMemoryLogHandler() LoggingSystem.bootstrap { label in MultiplexLogHandler([fileHandler, memHandler]) } ``` -------------------------------- ### Recommended: Structured Logging with Metadata Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/BestPractices/002-StructuredLogging.md Use metadata to provide structured, searchable data alongside human-readable log messages. This is ideal for general information and error logging. ```swift logger.info( "Accepted connection", metadata: [ "connection.id": "\(id)", "connection.peer": "\(peer)", "connections.total": "\(count)" ] ) logger.error( "Database query failed", metadata: [ "query.retries": "\(retries)", "query.error": "\(error)", "query.duration": "\(duration)" ] ) ``` -------------------------------- ### Manual Logger Propagation Pattern Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0006-task-local-logger.md Demonstrates the traditional approach of threading a logger through function signatures to maintain metadata context. ```swift func handleHTTPRequest(_ request: HTTPRequest, logger: Logger) async throws { var logger = logger logger[metadataKey: "request.id"] = "\(request.id)" try await processBusinessLogic(request, logger: logger) } ``` -------------------------------- ### Display documentation file structure Source: https://github.com/apple/swift-log/blob/main/_autodocs/README.md Visual representation of the documentation hierarchy and module relationships. ```text logger.md Main logging API ├── Level enumeration ├── Message lazy evaluation ├── Metadata dictionary └── MetadataValue cases logging-system.md Global setup (call once) ├── bootstrap() for handlers ├── bootstrap() with metadata provider └── Default behavior log-handler.md Backend protocol ├── Core requirements ├── Value semantics ├── Example implementations └── Thread safety log-event.md Data passed to handlers ├── All log information ├── Lazy properties └── Modification patterns metadata-provider.md Automatic metadata ├── Creating providers ├── Merging providers └── Integration patterns task-local-logger.md Async context binding ├── Binding loggers ├── Layering metadata └── Scope modification stream-log-handler.md Default handler ├── Factory methods ├── Format and merging └── Output examples multiplex-log-handler.md Multiple handlers ├── Routing to many ├── Per-handler filtering └── Common patterns in-memory-log-handler.md Test handler ├── Collection mechanism ├── Entry structure └── Testing patterns types.md Type reference ├── All exported types ├── Relationships └── Conformances configuration.md Setup patterns ├── Bootstrap options ├── Common configurations └── Performance tuning INDEX.md Navigation hub ├── Quick reference ├── Common tasks └── Module structure ``` -------------------------------- ### Accessing System Metadata Provider Source: https://github.com/apple/swift-log/blob/main/_autodocs/logging-system.md Retrieves the system-wide metadata provider configured during bootstrap. ```swift if let provider = LoggingSystem.metadataProvider { let contextMetadata = provider.get() print("System metadata: \(contextMetadata)") } ``` -------------------------------- ### Convert Logger.Level to and from strings Source: https://github.com/apple/swift-log/blob/main/_autodocs/types.md Demonstrates printing a level as a string and initializing a level from a string value. ```swift let level = Logger.Level.info print(level) // "info" let parsed = Logger.Level(String("warning")) print(parsed) // Optional(warning) ``` -------------------------------- ### Complete Custom LogHandler Implementation Source: https://github.com/apple/swift-log/blob/main/_autodocs/log-handler.md A full implementation of a custom LogHandler, including metadata management and log event handling. ```swift import Logging public struct MyCustomLogHandler: LogHandler { private let label: String private var _metadata: Logger.Metadata = [:] private var _logLevel: Logger.Level = .info public var metadataProvider: Logger.MetadataProvider? public init(label: String) { self.label = label self.metadataProvider = LoggingSystem.metadataProvider } public var metadata: Logger.Metadata { get { self._metadata } set { self._metadata = newValue } } public var logLevel: Logger.Level { get { self._logLevel } set { self._logLevel = newValue } } public subscript(metadataKey key: String) -> Logger.Metadata.Value? { get { self.metadata[key] } set { self.metadata[key] = newValue } } public func log(event: LogEvent) { var allMetadata = self.metadata if let provider = self.metadataProvider { let provided = provider.get() allMetadata.merge(provided, uniquingKeysWith: { _, rhs in rhs }) } if let eventMetadata = event.metadata { allMetadata.merge(eventMetadata, uniquingKeysWith: { _, rhs in rhs }) } let metadataString = allMetadata.isEmpty ? "" : " \(allMetadata)" let message = "\(Date()) [\(event.level)] \(self.label): \(event.message)\(metadataString)" print(message) } } ``` -------------------------------- ### Bootstrapping Multiple Handlers Source: https://github.com/apple/swift-log/blob/main/_autodocs/logging-system.md Configures the logging system to use multiple handlers simultaneously via MultiplexLogHandler. ```swift LoggingSystem.bootstrap { label in let handlers = [ StreamLogHandler.standardError(label: label), FileLogHandler(label: label, path: "/var/log/app.log") ] return MultiplexLogHandler(handlers) } ``` -------------------------------- ### Configure Development Logging Source: https://github.com/apple/swift-log/blob/main/_autodocs/configuration.md Sets up a standard error log handler with debug level and development metadata. ```swift import Logging LoggingSystem.bootstrap(StreamLogHandler.standardError) var logger = Logger(label: "app") logger.logLevel = .debug logger[metadataKey: "environment"] = "development" ``` -------------------------------- ### Creating a multiplex log handler Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Reference/MultiplexLogHandler.md Initializes a new instance of MultiplexLogHandler. You can create a handler with a collection of other log handlers, or with a collection of handlers and a metadata provider. ```APIDOC ## Initializers ### `init(_:)` Initializes a new instance of `MultiplexLogHandler` with a collection of other log handlers. ### `init(_:metadataProvider:)` Initializes a new instance of `MultiplexLogHandler` with a collection of log handlers and a metadata provider. ``` -------------------------------- ### Creating a Swift Log no-op log handler Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Reference/SwiftLogNoOpLogHandler.md Initializes a new instance of SwiftLogNoOpLogHandler. The `init()` method creates a handler that discards all messages. The `init(_:)` method allows for initial configuration. ```APIDOC ## Initializers ### `init()` Initializes a new instance of `SwiftLogNoOpLogHandler` that discards all log messages. ### `init(_:)` Initializes a new instance of `SwiftLogNoOpLogHandler` with the specified configuration. ``` -------------------------------- ### Initialize StreamLogHandler with metadata provider Source: https://github.com/apple/swift-log/blob/main/_autodocs/stream-log-handler.md Creates a handler instance configured with both a custom stream and a metadata provider. ```swift var output = FileOutputStream(path: "/var/log/app.log") let provider = Logger.MetadataProvider { ["environment": "production"] } let handler = StreamLogHandler(label: "app", stream: output, metadataProvider: provider) ``` -------------------------------- ### Logger.Metadata Usage Source: https://github.com/apple/swift-log/blob/main/_autodocs/types.md Shows how to set and pass metadata to loggers. ```swift var logger = Logger(label: "app") logger[metadataKey: "service"] = "api" logger.info("Request received", metadata: [ "request-id": "\(UUID())", "method": "POST" ]) ``` -------------------------------- ### Structured Error Logging with Custom Metadata Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/Proposals/SLG-0003.md Demonstrates how to attach error information to a log entry using custom metadata keys for the error message. ```swift logger.warning("Something went wrong", metadata: ["error": "\(error)"]) ``` -------------------------------- ### Implement a Custom LogHandler in Swift Source: https://github.com/apple/swift-log/blob/main/Sources/Logging/Docs.docc/ImplementingALogHandler.md A complete implementation of a LogHandler that supports metadata providers and manual metadata merging. ```swift import Foundation import Logging public struct PrintLogHandler: LogHandler { private let label: String public var logLevel: Logger.Level = .info public var metadata: Logger.Metadata = [:] public var metadataProvider: Logger.MetadataProvider? public init(label: String) { self.label = label } public func log(event: LogEvent) { let timestamp = ISO8601DateFormatter().string(from: Date()) let levelString = event.level.rawValue.uppercased() // Merge handler metadata with message metadata let combinedMetadata = Self.prepareMetadata( base: self.metadata, provider: self.metadataProvider, explicit: event.metadata ) // Format metadata let metadataString = combinedMetadata.map { "\($0.key)=\($0.value)" }.joined(separator: ",") // Create log line and print to console let logLine = "\(label) \(timestamp) \(levelString) [\(metadataString)]: \(event.message)" print(logLine) } public subscript(metadataKey key: String) -> Logger.Metadata.Value? { get { return self.metadata[key] } set { self.metadata[key] = newValue } } static func prepareMetadata( base: Logger.Metadata, provider: Logger.MetadataProvider?, explicit: Logger.Metadata? ) -> Logger.Metadata? { var metadata = base let provided = provider?.get() ?? [:] guard !provided.isEmpty || !((explicit ?? [:]).isEmpty) else { // all per-log-statement values are empty return metadata } if !provided.isEmpty { metadata.merge(provided, uniquingKeysWith: { _, provided in provided }) } if let explicit = explicit, !explicit.isEmpty { metadata.merge(explicit, uniquingKeysWith: { _, explicit in explicit }) } return metadata } } ``` -------------------------------- ### Run CI Job with Bind Mount using act Source: https://github.com/apple/swift-log/blob/main/CONTRIBUTING.md Execute a CI job, like formatting checks, with a bind mount for the working directory to reflect changes directly. ```bash % act --bind workflow_call -j soundness --input format_check_enabled=true ```