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
29 changes: 24 additions & 5 deletions Sources/SKLogging/LoggingScope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import Foundation
public final class LoggingScope {

/// The name of the default logging subsystem if no task-local value is set.
fileprivate static let defaultSubsystem: ThreadSafeBox<String?> = .init(initialValue: nil)
private static let defaultSubsystem = ThreadSafeBox<String?>(initialValue: nil)

/// Whether we have logged a fault that `subsystem` has been accessed without calling
/// `configureDefaultLoggingSubsystem` first.
private static let hasLoggedNoSubsystemConfiguredFault = AtomicBool(initialValue: false)

/// The name of the current logging subsystem or `nil` if no logging scope is set.
@TaskLocal fileprivate static var _subsystem: String?
Expand All @@ -31,9 +35,16 @@ public final class LoggingScope {
} else if let defaultSubsystem = defaultSubsystem.value {
return defaultSubsystem
} else {
Logger(subsystem: "org.swift.sklogging", category: "configuration")
.log(level: .fault, "default logging subsystem was not configured before first use")
return "org.swift"
if !hasLoggedNoSubsystemConfiguredFault.setAndGet(newValue: true) {
Logger(subsystem: "default", category: "sklogging")
.fault(
"""
Default logging subsystem was not configured before first use of SKLogging. \
Ensure that configureDefaultLoggingSubsystem is called before the first log call.
"""
)
}
return "default"
}
}

Expand All @@ -42,8 +53,16 @@ public final class LoggingScope {
return _scope ?? "default"
}

/// Set the logging subsystem that is used task local subsystem is set using `withLoggingSubsystemAndScope`.
///
/// Must be called before the first log call.
public static func configureDefaultLoggingSubsystem(_ subsystem: String) {
LoggingScope.defaultSubsystem.withLock { $0 = subsystem }
LoggingScope.defaultSubsystem.withLock { defaultSubsystem in
if let defaultSubsystem, defaultSubsystem != subsystem {
logger.log("Changing default log subsystem from \(defaultSubsystem) to \(subsystem)")
}
defaultSubsystem = subsystem
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdatomic.h>

typedef struct {
_Atomic(uint32_t) value;
Expand All @@ -32,6 +33,10 @@ static inline uint32_t atomic_uint32_get(CAtomicUInt32 *_Nonnull atomic) {
return atomic->value;
}

static inline uint32_t atomic_uint32_get_and_set(CAtomicUInt32 *_Nonnull atomic, uint32_t newValue) {
return __c11_atomic_exchange(&atomic->value, newValue, __ATOMIC_SEQ_CST);
}

static inline void atomic_uint32_set(CAtomicUInt32 *_Nonnull atomic, uint32_t newValue) {
atomic->value = newValue;
}
Expand Down
5 changes: 5 additions & 0 deletions Sources/ToolsProtocolsSwiftExtensions/Atomics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ import ToolsProtocolsCAtomics
atomic_uint32_set(atomic, newValue ? 1 : 0)
}
}

/// Sets the boolean to the new value and returns the previous value.
@_spi(SourceKitLSP) public func setAndGet(newValue: Bool) -> Bool {
return atomic_uint32_get_and_set(atomic, newValue ? 1 : 0) != 0
}
}

@_spi(SourceKitLSP) public final class AtomicUInt8: Sendable {
Expand Down
Loading