Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ find_package(ArgumentParser CONFIG REQUIRED)
find_package(SwiftCollections QUIET)
find_package(SwiftSystem CONFIG REQUIRED)
find_package(SwiftSyntax CONFIG REQUIRED)
find_package(SwiftCrypto CONFIG REQUIRED)

include(SwiftSupport)

Expand Down
12 changes: 9 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,17 @@ let package = Package(
// Logging support used in LSP modules.
.target(
name: "LSPLogging",
dependencies: [],
dependencies: [
.product(name: "Crypto", package: "swift-crypto")
],
exclude: ["CMakeLists.txt"]
),

.testTarget(
name: "LSPLoggingTests",
dependencies: [
"LSPLogging"
"LSPLogging",
"SKTestSupport",
]
),

Expand Down Expand Up @@ -207,7 +210,8 @@ let package = Package(
.target(
name: "LanguageServerProtocol",
dependencies: [
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core")
"LSPLogging",
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
],
exclude: ["CMakeLists.txt"]
),
Expand Down Expand Up @@ -266,6 +270,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
.package(url: "https://github.com/apple/swift-tools-support-core.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.2"),
.package(url: "https://github.com/apple/swift-syntax.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/apple/swift-crypto.git", from: "2.5.0"),
]
} else {
package.dependencies += [
Expand All @@ -274,5 +279,6 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
.package(path: "../swift-tools-support-core"),
.package(path: "../swift-argument-parser"),
.package(path: "../swift-syntax"),
.package(path: "../swift-crypto"),
]
}
16 changes: 13 additions & 3 deletions Sources/LSPLogging/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
add_library(LSPLogging STATIC
LogLevel.swift
Logging.swift)
CustomLogStringConvertible.swift
Error+ForLogging.swift
Logging.swift
LoggingScope.swift
NonDarwinLogging.swift
OrLog.swift
)
set_target_properties(LSPLogging PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
target_link_libraries(LSPLogging PRIVATE
$<$<NOT:$<PLATFORM_ID:Darwin>>:Foundation>)
$<$<NOT:$<PLATFORM_ID:Darwin>>:Foundation>
)

target_link_libraries(LSPLogging PUBLIC
Crypto
)
64 changes: 64 additions & 0 deletions Sources/LSPLogging/CustomLogStringConvertible.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Crypto
import Foundation

/// An object that can printed for logging and also offers a redacted description
/// when logging in contexts in which private information shouldn't be captured.
public protocol CustomLogStringConvertible: CustomStringConvertible {
/// A full description of the object.
var description: String { get }

/// A description of the object that doesn't contain any private information.
var redactedDescription: String { get }
}

/// When an NSObject is logged with OSLog in private mode and the object
/// implements `redactedDescription`, OSLog will log that information instead of
/// just logging `<private>`.
///
/// There currently is no way to get equivalent functionality in pure Swift. We
/// thus pass this object to OSLog, which just forwards to `description` or
/// `redactedDescription` of an object that implements `CustomLogStringConvertible`.
public class CustomLogStringConvertibleWrapper: NSObject {
private let underlyingObject: any CustomLogStringConvertible

fileprivate init(_ underlyingObject: any CustomLogStringConvertible) {
self.underlyingObject = underlyingObject
}

public override var description: String {
return underlyingObject.description
}

public var redactedDescription: String {
underlyingObject.redactedDescription
}
}

extension CustomLogStringConvertible {
/// Returns an object that can be passed to OSLog, which will print the
/// `redactedDescription` if logging of private information is disabled and
/// will log `description` otherwise.
public var forLogging: CustomLogStringConvertibleWrapper {
return CustomLogStringConvertibleWrapper(self)
}
}

extension String {
/// A hash value that can be logged in a redacted description without
/// disclosing any private information about the string.
public var hashForLogging: String {
return Insecure.MD5.hash(data: Data(self.utf8)).description
}
}
43 changes: 43 additions & 0 deletions Sources/LSPLogging/Error+ForLogging.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Foundation

/// A wrapper around `Error` that conforms to `CustomLogStringConvertible`.
private struct MaskedError: CustomLogStringConvertible {
let underlyingError: any Error

init(_ underlyingError: any Error) {
self.underlyingError = underlyingError
}

var description: String {
return "\(underlyingError)"
}

var redactedDescription: String {
let error = underlyingError as NSError
return "\(error.code): \(error.description.hashForLogging)"
}
}

extension Error {
/// A version of the error that can be used for logging and will only log the
/// error code and a hash of the description in privacy-sensitive contexts.
public var forLogging: CustomLogStringConvertibleWrapper {
if let error = self as? CustomLogStringConvertible {
return error.forLogging
} else {
return MaskedError(self).forLogging
}
}
}
94 changes: 0 additions & 94 deletions Sources/LSPLogging/LogLevel.swift

This file was deleted.

Loading