Unify LoggerFragmentBuilder and LoggerSpacedFragmentBuilder#231
Unify LoggerFragmentBuilder and LoggerSpacedFragmentBuilder#2310xTim merged 2 commits intovapor:consolekit-5from
LoggerFragmentBuilder and LoggerSpacedFragmentBuilder#231Conversation
| } | ||
|
|
||
| /// A fragment that wraps another fragment, automatically separating its components with spaces. | ||
| @available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) |
There was a problem hiding this comment.
What in this requires adding availability annotations? And doesn't this affect anyone using a logger fragment?
There was a problem hiding this comment.
I think it's the use of integer generics that requires the annotation. Which makes it problematic IMO; I think Tahoe is too strict a requirement as of yet.
There was a problem hiding this comment.
I mean it's fine if it's scoped to just these APIs and the rest is fine which it looks like, but I'm not 100%.
Also Vapor 5 will be 26+ only given the Span usage so I'm happy to just bump that if necessary, but given the logger is used for more than Vapor I'd like to try and make it as permissive as possible
There was a problem hiding this comment.
Yes, it's for the integer generics. Tahoe would be required only for the LoggerFragment DSL though, the old API would still be available on older macOS versions.
Also, I guess macOS 27 would already be out when we release the definitive v5 of ConsoleKit.
|
To be honest, I'm a bit soured on the entire concept of "log fragments" and builders for them at this point. I've found that this (with a couple of additional supporting bits) works just fine for my needs: extension Logger {
/// A container for a formatter closure which accepts as input all parameters related to a log message and returns a
/// simple string containing the final raw output. Modeled after `Logger.MetadataProvider`.
public struct MessageFormatter: Sendable {
/// The type of a closure which accepts all parameters related to a log message and returns a formatted raw string.
///
/// See ``format(timestamp:event:)`` for details on the semantics of the closure's parameters.
public typealias Formatter = @Sendable (_ timestamp: Date, _ event: LogEvent) -> String
private let formatter: Formatter
/// Create a formatter with a formatter closure.
public init(_ formatter: @escaping Formatter) { self.formatter = formatter }
/// Apply the formatter to the given inputs and return its result.
///
/// - Parameters:
/// - timestamp: The timestamp of the log message.
/// - event: The `LogEvent` containing the various data representing the log message. The `metadata` field of the event will
/// contain the result of merging the logger's configured metadata, the metadata from the logger's configured metadata provider,
/// and the metadata specific to the specific log message,in that order.
/// - Returns: The formatted log message.
public func format(timestamp: Date, event: LogEvent) -> String { self.formatter(timestamp, event) }
}
}
/// A log handler which automatically applies a `Logger.MessageFormatter` to each log message it receives.
///
/// A per-message timestamp is provided for each log message, and the logger label is provided as a protocol requirement.
public protocol MessageFormattingLogHandler: LogHandler {
/// The label applied to the log handler at its creation.
var label: String { get }
/// The message formatter to be applied to each log message.
var messageFormatter: Logger.MessageFormatter { get set }
/// Log a preformatted message having the given parameters.
///
/// Although the log event has already been used in formatting the message, it is also provided here for the handler's usage.
/// The label is not passed to this method because it is already available via the protocol.
///
/// - Parameters:
/// - timestamp: The timestamp of the log message (always `Date.now` at the point that the message was logged).
/// - event: The `LogEvent` containing the various data representing the log message. The `metadata` field of the event will
/// contain the result of merging the logger's configured metadata, the metadata from the logger's configured metadata provider,
/// and the metadata specific to the specific log message,in that order.
func log(timestamp: Date, event: LogEvent)
} |
Merge
LoggerFragmentBuilderandLoggerSpacedFragmentBuilderusing a Integer Generic Parameter to specify the number of spaces to add between fragments