Skip to content

Commit d326f08

Browse files
committed
Allow overriding the current logging subsystem
1 parent 02a1ad9 commit d326f08

File tree

5 files changed

+42
-9
lines changed

5 files changed

+42
-9
lines changed

Sources/LSPLogging/Logging.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121

2222
import Foundation
2323

24-
/// The subsystem that should be used for any logging by default.
25-
public let subsystem = "org.swift.sourcekit-lsp"
26-
2724
#if canImport(os) && !SOURCEKITLSP_FORCE_NON_DARWIN_LOGGER
2825
import os // os_log
2926

@@ -44,5 +41,5 @@ public typealias Signposter = NonDarwinSignposter
4441

4542
/// The logger that is used to log any messages.
4643
public var logger: Logger {
47-
Logger(subsystem: subsystem, category: LoggingScope.scope)
44+
Logger(subsystem: LoggingScope.subsystem, category: LoggingScope.scope)
4845
}

Sources/LSPLogging/LoggingScope.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,50 @@
1313
import Foundation
1414

1515
public final class LoggingScope {
16+
/// The name of the current logging subsystem or `nil` if no logging scope is set.
17+
@TaskLocal fileprivate static var _subsystem: String?
18+
1619
/// The name of the current logging scope or `nil` if no logging scope is set.
1720
@TaskLocal fileprivate static var _scope: String?
1821

22+
/// The name of the current logging subsystem.
23+
public static var subsystem: String {
24+
return _subsystem ?? "org.swift.sourcekit-lsp"
25+
}
26+
1927
/// The name of the current logging scope.
2028
public static var scope: String {
2129
return _scope ?? "default"
2230
}
2331
}
2432

33+
/// Logs all messages created from the operation to the given subsystem.
34+
///
35+
/// This overrides the current logging subsystem.
36+
///
37+
/// - Note: Since this stores the logging subsystem in a task-local value, it only works when run inside a task.
38+
/// Outside a task, this is a no-op.
39+
public func withLoggingSubsystemAndScope<Result>(
40+
subsystem: String,
41+
scope: String?,
42+
_ operation: () throws -> Result
43+
) rethrows -> Result {
44+
return try LoggingScope.$_subsystem.withValue(subsystem) {
45+
return try LoggingScope.$_scope.withValue(scope, operation: operation)
46+
}
47+
}
48+
49+
/// Same as `withLoggingSubsystemAndScope` but allows the operation to be `async`.
50+
public func withLoggingSubsystemAndScope<Result>(
51+
subsystem: String,
52+
scope: String?,
53+
_ operation: () async throws -> Result
54+
) async rethrows -> Result {
55+
return try await LoggingScope.$_subsystem.withValue(subsystem) {
56+
return try await LoggingScope.$_scope.withValue(scope, operation: operation)
57+
}
58+
}
59+
2560
/// Create a new logging scope, which will be used as the category in any log messages created from the operation.
2661
///
2762
/// This overrides the current logging scope.

Sources/SourceKitLSP/Clang/ClangLanguageService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fileprivate class ClangdStderrLogForwarder {
4545
// than 1000 bytes long but if we merge multiple lines into one message, we might easily exceed this limit.
4646
// b) It might be confusing why sometimes a single log message contains one line while sometimes it contains
4747
// multiple.
48-
let logger = Logger(subsystem: subsystem, category: "clangd-stderr")
48+
let logger = Logger(subsystem: LoggingScope.subsystem, category: "clangd-stderr")
4949
logger.info("\(String(data: self.buffer[...newlineIndex], encoding: .utf8) ?? "<invalid UTF-8>")")
5050
buffer = buffer[buffer.index(after: newlineIndex)...]
5151
}

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,8 @@ extension SourceKitLSPServer: MessageHandler {
826826

827827
let notificationID = notificationIDForLogging.fetchAndIncrement()
828828

829-
let signposter = Logger(subsystem: subsystem, category: "notification-\(notificationID)").makeSignposter()
829+
let signposter = Logger(subsystem: LoggingScope.subsystem, category: "notification-\(notificationID)")
830+
.makeSignposter()
830831
let signpostID = signposter.makeSignpostID()
831832
let state = signposter.beginInterval("Notification", id: signpostID, "\(type(of: params))")
832833
messageHandlingQueue.async(metadata: TaskMetadata(params)) {
@@ -875,7 +876,7 @@ extension SourceKitLSPServer: MessageHandler {
875876
id: RequestID,
876877
reply: @escaping (LSPResult<R.Response>) -> Void
877878
) {
878-
let signposter = Logger(subsystem: subsystem, category: "request-\(id)").makeSignposter()
879+
let signposter = Logger(subsystem: LoggingScope.subsystem, category: "request-\(id)").makeSignposter()
879880
let signpostID = signposter.makeSignpostID()
880881
let state = signposter.beginInterval("Request", id: signpostID, "\(R.self)")
881882

Tests/LSPLoggingTests/LoggingTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fileprivate func assertLogging(
2525
// nonisolated(unsafe) because calls of `assertLogging` do not log to `logHandler` concurrently.
2626
nonisolated(unsafe) var messages: [String] = []
2727
let logger = NonDarwinLogger(
28-
subsystem: subsystem,
28+
subsystem: LoggingScope.subsystem,
2929
category: "test",
3030
logLevel: logLevel,
3131
privacyLevel: privacyLevel,
@@ -75,7 +75,7 @@ final class LoggingTests: XCTestCase {
7575
// nonisolated(unsafe) because we only have a single call to `logger.log` and that cannot race.
7676
nonisolated(unsafe) var message: String = ""
7777
let logger = NonDarwinLogger(
78-
subsystem: subsystem,
78+
subsystem: LoggingScope.subsystem,
7979
category: "test",
8080
logHandler: {
8181
message = $0

0 commit comments

Comments
 (0)