ConfigurationGlobals.swift 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Software License Agreement (BSD License)
  2. //
  3. // Copyright (c) 2010-2025, Deusty, LLC
  4. // All rights reserved.
  5. //
  6. // Redistribution and use of this software in source and binary forms,
  7. // with or without modification, are permitted provided that the following conditions are met:
  8. //
  9. // * Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. //
  12. // * Neither the name of Deusty nor the names of its contributors may be used
  13. // to endorse or promote products derived from this software without specific
  14. // prior written permission of Deusty, LLC.
  15. #if canImport(Synchronization)
  16. public import Synchronization
  17. #endif
  18. #if SWIFT_PACKAGE
  19. public import CocoaLumberjack
  20. #endif
  21. #if canImport(Synchronization)
  22. #if compiler(>=6.0) && !COCOAPODS // CocoaPods seems to merge the modules.
  23. @available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *)
  24. extension DDLogLevel: @retroactive AtomicRepresentable {}
  25. #else
  26. @available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *)
  27. extension DDLogLevel: AtomicRepresentable {}
  28. #endif
  29. @available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *)
  30. private let _dynamicLogLevel = Atomic(DDLogLevel.all)
  31. #endif
  32. private let _dynamicLogLevelLock = NSLock()
  33. nonisolated(unsafe) private var _dynamicLogLevelStorage = DDLogLevel.all
  34. private func _readDynamicLogLevel() -> DDLogLevel {
  35. #if canImport(Synchronization)
  36. if #available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *) {
  37. return _dynamicLogLevel.load(ordering: .relaxed)
  38. }
  39. #endif
  40. _dynamicLogLevelLock.lock()
  41. defer { _dynamicLogLevelLock.unlock() }
  42. return _dynamicLogLevelStorage
  43. }
  44. private func _writeDynamicLogLevel(_ newValue: DDLogLevel) {
  45. #if canImport(Synchronization)
  46. if #available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *) {
  47. _dynamicLogLevel.store(newValue, ordering: .relaxed)
  48. return
  49. }
  50. #endif
  51. _dynamicLogLevelLock.lock()
  52. defer { _dynamicLogLevelLock.unlock() }
  53. _dynamicLogLevelStorage = newValue
  54. }
  55. /// The log level that can dynamically limit log messages (vs. the static ``DDDefaultLogLevel``). This log level will only be checked, if the message passes the ``DDDefaultLogLevel``.
  56. public nonisolated(unsafe) var dynamicLogLevel: DDLogLevel {
  57. get {
  58. _readDynamicLogLevel()
  59. }
  60. set {
  61. _writeDynamicLogLevel(newValue)
  62. }
  63. }
  64. /// Resets the ``dynamicLogLevel`` to ``DDLogLevel/all``.
  65. /// - SeeAlso: ``dynamicLogLevel``
  66. @inlinable
  67. public func resetDynamicLogLevel() {
  68. dynamicLogLevel = .all
  69. }
  70. @available(*, deprecated, message: "Please use dynamicLogLevel", renamed: "dynamicLogLevel")
  71. public var defaultDebugLevel: DDLogLevel {
  72. get {
  73. dynamicLogLevel
  74. }
  75. set {
  76. dynamicLogLevel = newValue
  77. }
  78. }
  79. @available(*, deprecated, message: "Please use resetDynamicLogLevel", renamed: "resetDynamicLogLevel")
  80. public func resetDefaultDebugLevel() {
  81. resetDynamicLogLevel()
  82. }
  83. #if canImport(Synchronization)
  84. @available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *)
  85. private let _asyncLoggingEnabled = Atomic(true)
  86. #endif
  87. private let _asyncLoggingEnabledLock = NSLock()
  88. nonisolated(unsafe) private var _asyncLoggingEnabledStorage = true
  89. private func _readAsyncLoggingEnabled() -> Bool {
  90. #if canImport(Synchronization)
  91. if #available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *) {
  92. return _asyncLoggingEnabled.load(ordering: .relaxed)
  93. }
  94. #endif
  95. _asyncLoggingEnabledLock.lock()
  96. defer { _asyncLoggingEnabledLock.unlock() }
  97. return _asyncLoggingEnabledStorage
  98. }
  99. private func _writeAsyncLoggingEnabled(_ newValue: Bool) {
  100. #if canImport(Synchronization)
  101. if #available(macOS 15, iOS 18, tvOS 18, watchOS 11, visionOS 2, *) {
  102. _asyncLoggingEnabled.store(newValue, ordering: .relaxed)
  103. return
  104. }
  105. #endif
  106. _asyncLoggingEnabledLock.lock()
  107. defer { _asyncLoggingEnabledLock.unlock() }
  108. _asyncLoggingEnabledStorage = newValue
  109. }
  110. /// If `true`, all logs (except errors) are logged asynchronously by default.
  111. public nonisolated(unsafe) var asyncLoggingEnabled: Bool {
  112. get {
  113. _readAsyncLoggingEnabled()
  114. }
  115. set {
  116. _writeAsyncLoggingEnabled(newValue)
  117. }
  118. }