-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enforce Sendable conformance for LogHandlers Swift-Log, and make Logger Sendable #217
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,7 +113,7 @@ | |
/// Please note that the above `LogHandler` will still pass the 'log level is a value' test above it iff the global log | ||
/// level has not been overridden. And most importantly it passes the requirement listed above: A change to the log | ||
/// level on one `Logger` should not affect the log level of another `Logger` variable. | ||
public protocol LogHandler { | ||
public protocol LogHandler: Sendable { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can't just do it like this, we'd need to follow the trickery with the sendable availability as explained in https://github.com/swift-server/guides/blob/main/docs/concurrency-adoption-guidelines.md#backwards-compatibility-of-declarations-and-checked-swift-concurrency So we'd need |
||
/// This method is called when a `LogHandler` must emit a log message. There is no need for the `LogHandler` to | ||
/// check if the `level` is above or below the configured `logLevel` as `Logger` already performed this check and | ||
/// determined that a message should be logged. | ||
|
@@ -126,7 +126,7 @@ public protocol LogHandler { | |
/// - file: The file the log message was emitted from. | ||
/// - function: The function the log line was emitted from. | ||
/// - line: The line the log message was emitted from. | ||
func log(level: Logger.Level, | ||
@Sendable func log(level: Logger.Level, | ||
message: Logger.Message, | ||
metadata: Logger.Metadata?, | ||
source: String, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ import WASILibc | |
/// | ||
/// logger.info("Hello World!") | ||
/// | ||
public struct Logger { | ||
public struct Logger: Sendable { | ||
@usableFromInline | ||
var handler: LogHandler | ||
|
||
|
@@ -707,15 +707,15 @@ extension Logger { | |
/// over `..., metadata: ["colors": .array([.string("\(user.topColor)"), .string("\(user.secondColor)")])` | ||
/// - prefer `logger.info("nested info", metadata: ["nested": ["fave-numbers": ["\(1)", "\(2)", "\(3)"], "foo": "bar"]])` | ||
/// over `..., metadata: ["nested": .dictionary(["fave-numbers": ...])])` | ||
public enum MetadataValue { | ||
public enum MetadataValue: Sendable { | ||
/// A metadata value which is a `String`. | ||
/// | ||
/// Because `MetadataValue` implements `ExpressibleByStringInterpolation`, and `ExpressibleByStringLiteral`, | ||
/// you don't need to type `.string(someType.description)` you can use the string interpolation `"\(someType)"`. | ||
case string(String) | ||
|
||
/// A metadata value which is some `CustomStringConvertible`. | ||
case stringConvertible(CustomStringConvertible) | ||
case stringConvertible(CustomStringConvertible & Sendable) | ||
|
||
/// A metadata value which is a dictionary from `String` to `Logger.MetadataValue`. | ||
/// | ||
|
@@ -734,7 +734,7 @@ extension Logger { | |
/// | ||
/// Log levels are ordered by their severity, with `.trace` being the least severe and | ||
/// `.critical` being the most severe. | ||
public enum Level: String, Codable, CaseIterable { | ||
public enum Level: String, Codable, CaseIterable, Sendable { | ||
/// Appropriate for messages that contain information normally of use only when | ||
/// tracing the execution of a program. | ||
case trace | ||
|
@@ -999,7 +999,7 @@ internal typealias CFilePointer = UnsafeMutablePointer<FILE> | |
/// A wrapper to facilitate `print`-ing to stderr and stdio that | ||
/// ensures access to the underlying `FILE` is locked to prevent | ||
/// cross-thread interleaving of output. | ||
internal struct StdioOutputStream: TextOutputStream { | ||
internal struct StdioOutputStream: TextOutputStream, Sendable { | ||
internal let file: CFilePointer | ||
internal let flushMode: FlushMode | ||
|
||
|
@@ -1074,6 +1074,8 @@ let systemStdout = WASILibc.stdout! | |
/// `StreamLogHandler` is a simple implementation of `LogHandler` for directing | ||
/// `Logger` output to either `stderr` or `stdout` via the factory methods. | ||
public struct StreamLogHandler: LogHandler { | ||
public typealias Stream = TextOutputStream & Sendable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. has to use the compatibility trickery |
||
|
||
/// Factory that makes a `StreamLogHandler` to directs its output to `stdout` | ||
public static func standardOutput(label: String) -> StreamLogHandler { | ||
return StreamLogHandler(label: label, stream: StdioOutputStream.stdout) | ||
|
@@ -1084,7 +1086,7 @@ public struct StreamLogHandler: LogHandler { | |
return StreamLogHandler(label: label, stream: StdioOutputStream.stderr) | ||
} | ||
|
||
private let stream: TextOutputStream | ||
private let stream: Stream | ||
private let label: String | ||
|
||
public var logLevel: Logger.Level = .info | ||
|
@@ -1106,7 +1108,7 @@ public struct StreamLogHandler: LogHandler { | |
} | ||
|
||
// internal for testing only | ||
internal init(label: String, stream: TextOutputStream) { | ||
internal init(label: String, stream: Stream) { | ||
self.label = label | ||
self.stream = stream | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't just do that like this; we need to support old platforms too