Skip to content

Commit 45caa12

Browse files
authored
docs: update the documentation (#40)
1 parent 053fdea commit 45caa12

File tree

17 files changed

+329
-169
lines changed

17 files changed

+329
-169
lines changed

Sources/Log/Classes/Core/Formatters/Interfaces/ILogFormatter.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@
55

66
import Foundation
77

8-
/// Specifies the format to be used in the log message
8+
/// A protocol that defines the interface for transforming and styling log messages.
9+
///
10+
/// Types conforming to `ILogFormatter` act as individual steps in a formatting pipeline.
11+
/// They are responsible for taking a message string and augmenting it with additional
12+
/// information—such as timestamps, tags, or emojis—based on the message's severity.
913
public protocol ILogFormatter {
10-
/// Concatenates the specified attributes and generates the final log message
14+
/// Processes the input message and returns a decorated version of it.
15+
///
16+
/// This method is called by a `Logger` or a `Printer` strategy to prepare the
17+
/// message for final output. Since formatters are often used in a chain,
18+
/// the `message` parameter might already contain modifications from previous formatters.
1119
///
1220
/// - Parameters:
13-
/// - message: A `String` value that contains the message.
14-
/// - logLevel: A `LogLevel` value that contains the logging level.
21+
/// - message: The current string content of the log message.
22+
/// - logLevel: The `LogLevel` associated with the message, used to determine
23+
/// appropriate styling or metadata.
24+
/// - Returns: A transformed string containing the formatted log message.
1525
func format(message: String, with logLevel: LogLevel) -> String
1626
}

Sources/Log/Classes/Core/Formatters/PrefixLogFormatter.swift

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,49 @@
55

66
import Foundation
77

8-
/// A log formatter that adds a custom prefix to log messages.
8+
/// A log formatter that prepends a custom identifier and visual indicators to log messages.
9+
///
10+
/// `PrefixLogFormatter` is used to categorize logs by adding a string tag (e.g., a module name).
11+
/// It also automatically adds high-visibility emojis for critical levels like `.fault` and `.error`
12+
/// to help them stand out in dense log outputs.
913
public struct PrefixLogFormatter: ILogFormatter {
10-
// MARK: Properties
14+
// MARK: - Properties
1115

12-
/// The custom prefix to be added to log messages.
16+
/// The string identifier (e.g., "Network", "Auth") prepended to every log message.
1317
private let name: String
1418

15-
// MARK: Initialization
19+
// MARK: - Initialization
1620

17-
/// Creates a new `PrefixLogFormatter` instance with the specified prefix.
21+
/// Initializes a new formatter with a specific name.
1822
///
19-
/// - Parameter name: The custom prefix to be added to log messages.
23+
/// - Parameter name: The custom prefix string used to identify the source of the log.
2024
public init(name: String) {
2125
self.name = name
2226
}
2327

24-
// MARK: ILogFormatter
28+
// MARK: - ILogFormatter
2529

30+
/// Prepends the prefix and professional severity-based symbols to the log message.
31+
///
32+
/// The style is optimized for professional environments:
33+
/// - `.fault`: Uses the stop sign (⛔️) to indicate a critical, unrecoverable failure.
34+
/// - `.error`: Uses the warning sign (⚠️) to indicate a significant but recoverable issue.
35+
/// - `.info`: Uses the information circle (ℹ️) for high-level progress tracking.
36+
/// - `.debug`: Uses a simple diamond (🔹) for development-level details.
2637
public func format(message: String, with logLevel: LogLevel) -> String {
27-
switch logLevel {
38+
let symbol = switch logLevel {
2839
case .fault:
29-
"🚨🚨🚨 [\(name)] => \(message)"
40+
"⛔️ [\(name)]"
3041
case .error:
31-
"💣💥💣💥 [\(name)] => \(message)"
42+
"⚠️ [\(name)]"
43+
case .info:
44+
"ℹ️ [\(name)]"
45+
case .debug:
46+
"🔹 [\(name)]"
3247
default:
33-
"[\(name)] => \(message)"
48+
"[\(name)]"
3449
}
50+
51+
return "\(symbol) => \(message)"
3552
}
3653
}

Sources/Log/Classes/Core/Formatters/TimestampLogFormatter.swift

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,44 @@
55

66
import Foundation
77

8-
/// A log formatter that adds a timestamp to log messages.
8+
/// A log formatter that prepends a chronological timestamp to log messages.
9+
///
10+
/// `TimestampLogFormatter` is essential for tracing the sequence of events during
11+
/// application execution. It allows you to define a custom date format to match
12+
/// your specific debugging or analytics requirements.
913
open class TimestampLogFormatter: ILogFormatter {
10-
// MARK: Properties
14+
// MARK: - Properties
1115

12-
/// The date formatter.
16+
/// The internal date formatter used to convert the current system time into a string.
17+
///
18+
/// This property is lazily initialized to optimize performance and ensure the
19+
/// formatter is only created when the first log message is processed.
1320
private lazy var dateFormatter: DateFormatter = {
1421
let dateFormatter = DateFormatter()
1522
dateFormatter.dateFormat = dateFormat
1623
return dateFormatter
1724
}()
1825

19-
/// The date format string.
26+
/// The string pattern defining the appearance of the timestamp (e.g., "yyyy-MM-dd HH:mm:ss").
2027
private let dateFormat: String
2128

22-
// MARK: Initialization
29+
// MARK: - Initialization
2330

24-
/// Creates a new `PrefixFormatter` instance with the specified data formmater.
31+
/// Initializes a new `TimestampLogFormatter` with the specified date format.
2532
///
26-
/// - Parameter dateFormat: The date format string.
33+
/// - Parameter dateFormat: A string representing the desired date and time pattern.
2734
public init(dateFormat: String) {
2835
self.dateFormat = dateFormat
2936
}
3037

31-
// MARK: ILogFormatter
38+
// MARK: - ILogFormatter
3239

40+
/// Prepends a timestamp based on the current system time to the log message.
41+
///
42+
/// - Parameters:
43+
/// - message: The raw or previously formatted log message.
44+
/// - logLevel: The severity level (ignored by this specific formatter).
45+
/// - Returns: A string combining the timestamp and the message, separated by a space.
3346
public func format(message: String, with _: LogLevel) -> String {
3447
let timestamp = dateFormatter.string(from: Date())
3548
return [timestamp, message].joined(separator: " ")

Sources/Log/Classes/Core/Logger/ILogger.swift

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,37 @@
55

66
import Foundation
77

8-
/// A type that provides logging functionality.
8+
/// A protocol defining the public interface for a logging coordinator.
9+
///
10+
/// `ILogger` provides a set of methods for dispatching messages at various severity levels.
11+
/// Implementations should handle filtering based on the current configuration and ensure
12+
/// that log production has minimal impact on application performance.
913
public protocol ILogger {
10-
/// Dispatches the given message using the logger if the debug log level is set.
14+
/// Dispatches a message for fine-grained informational events useful for debugging.
1115
///
12-
/// - Parameter message: An autoclosure returning the message to log.
16+
/// - Parameter message: An autoclosure returning the string to log. The closure is
17+
/// evaluated only if the `.debug` log level is active, preventing unnecessary
18+
/// string construction.
1319
func debug(message: @autoclosure () -> String)
1420

15-
/// Dispatches the given message using the logger if the info log level is set.
21+
/// Dispatches an informational message that highlights the progress of the application.
1622
///
17-
/// - Parameter message: An autoclosure returning the message to log.
23+
/// - Parameter message: An autoclosure returning the string to log. The closure is
24+
/// evaluated only if the `.info` log level is active.
1825
func info(message: @autoclosure () -> String)
1926

20-
/// Dispatches the given message using the logger if the fault log level is set.
27+
/// Dispatches a message about a severe error or system-level fault.
2128
///
22-
/// - Parameter message: An autoclosure returning the message to log.
29+
/// Use this for critical issues that may require system-level attention or indicate
30+
/// a corruption of state.
31+
///
32+
/// - Parameter message: An autoclosure returning the string to log. The closure is
33+
/// evaluated only if the `.fault` is active.
2334
func fault(message: @autoclosure () -> String)
2435

25-
/// Dispatches the given message using the logger if the error log level is set.
36+
/// Dispatches a message about an error event that might still allow the application to continue running.
2637
///
27-
/// - Parameter message: An autoclosure returning the message to log.
38+
/// - Parameter message: An autoclosure returning the string to log. The closure is
39+
/// evaluated only if the `.error` log level is active.
2840
func error(message: @autoclosure () -> String)
2941
}

Sources/Log/Classes/Core/Logger/Logger.swift

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,75 @@ import Foundation
77

88
// MARK: - Logger
99

10-
/// A class responsible for logging functionality.
10+
/// A high-level logging coordinator responsible for filtering and dispatching log messages.
11+
///
12+
/// `Logger` acts as the central entry point for the logging system. It evaluates whether a message
13+
/// should be logged based on the current `logLevel` and then broadcasts allowed messages
14+
/// to a collection of `IPrinterStrategy` implementations.
1115
open class Logger {
1216
// MARK: Properties
1317

14-
/// The current log level for this logger.
15-
private var _logLevel: Atomic<LogLevel>
18+
/// A recursive lock used to synchronize access to the logger's mutable state.
19+
private let lock = NSRecursiveLock()
1620

17-
/// The current log level for this logger.
21+
/// Internal storage for the log level, protected by a lock.
22+
private var _logLevel: LogLevel
23+
24+
/// The active log level configuration for this logger.
25+
///
26+
/// This property uses a lock to ensure thread-safe read and write access.
1827
public var logLevel: LogLevel {
19-
get { _logLevel.value }
20-
set { _logLevel.value = newValue }
28+
lock.lock()
29+
defer { lock.unlock() }
30+
return _logLevel
2131
}
2232

23-
/// An array of printer strategies to handle the log output.
33+
/// The collection of output strategies (printers) that handle the actual delivery of log messages.
2434
let printers: [IPrinterStrategy]
2535

26-
// MARK: Initialization
36+
// MARK: - Initialization
2737

28-
/// Initializes a new Logger instance.
38+
/// Initializes a new `Logger` instance.
2939
///
3040
/// - Parameters:
31-
/// - printers: An array of printer strategies.
32-
/// - logLevel: The initial log level.
41+
/// - printers: An array of strategies defining where logs should be sent (e.g., Console, OSLog, File).
42+
/// - logLevel: The initial set of allowed log levels. Defaults to specific levels if not provided.
3343
public init(
3444
printers: [IPrinterStrategy],
3545
logLevel: LogLevel
3646
) {
3747
self.printers = printers
38-
_logLevel = Atomic(value: logLevel)
48+
_logLevel = logLevel
49+
}
50+
51+
/// Atomically updates the current log level using a transformation closure.
52+
///
53+
/// This method prevents race conditions that can occur when multiple threads try to
54+
/// modify the `logLevel` simultaneously (e.g., two threads trying to add different flags at once).
55+
///
56+
/// - Parameter transform: A closure that receives the current `LogLevel` and returns the new desired value.
57+
public func updateLogLevel(_ transform: (LogLevel) -> LogLevel) {
58+
lock.lock()
59+
defer { lock.unlock() }
60+
_logLevel = transform(_logLevel)
3961
}
4062

41-
// MARK: Private
63+
// MARK: - Private Methods
4264

43-
/// Passes the message to each receiver's printer.
65+
/// Dispatches a message to all registered printers if the log level is enabled.
4466
///
4567
/// - Parameters:
46-
/// - message: The message to dispatch.
47-
/// - logLevel: The message's level.
68+
/// - message: The string content to log.
69+
/// - logLevel: The severity level associated with this message.
4870
private func log(_ message: String, logLevel: LogLevel) {
4971
guard isLoggerEnabled(for: logLevel) else { return }
5072
printers.forEach { $0.log(message, logLevel: logLevel) }
5173
}
5274

53-
/// Checks if the given `LogLevel` is allowed by the receiver.
75+
/// Evaluates whether the current logger configuration allows a specific log level.
5476
///
55-
/// - Parameter logLevel: The log level to check.
77+
/// - Parameter logLevel: The level to validate against the current settings.
78+
/// - Returns: `true` if the level is included in the active `logLevel` set.
5679
private func isLoggerEnabled(for logLevel: LogLevel) -> Bool {
5780
self.logLevel.contains(logLevel)
5881
}
@@ -61,18 +84,26 @@ open class Logger {
6184
// MARK: ILogger
6285

6386
extension Logger: ILogger {
87+
/// Logs a message for debugging purposes.
88+
/// - Parameter message: A closure returning the string to log, evaluated only if `.debug` is enabled.
6489
public func debug(message: @autoclosure () -> String) {
6590
log(message(), logLevel: .debug)
6691
}
6792

93+
/// Logs an informational message highlighting application progress.
94+
/// - Parameter message: A closure returning the string to log, evaluated only if `.info` is enabled.
6895
public func info(message: @autoclosure () -> String) {
6996
log(message(), logLevel: .info)
7097
}
7198

99+
/// Logs a critical fault that may require system-level attention.
100+
/// - Parameter message: A closure returning the string to log, evaluated only if `.fault` is enabled.
72101
public func fault(message: @autoclosure () -> String) {
73102
log(message(), logLevel: .fault)
74103
}
75104

105+
/// Logs an error that occurred during execution.
106+
/// - Parameter message: A closure returning the string to log, evaluated only if `.error` is enabled.
76107
public func error(message: @autoclosure () -> String) {
77108
log(message(), logLevel: .error)
78109
}

Sources/Log/Classes/Core/Logger/Strategies/IPrinterStrategy.swift

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,27 @@
55

66
import Foundation
77

8-
/// A protocol that defines the behavior of a logging printer strategy
8+
/// A protocol that defines a strategy for processing and delivering log messages.
9+
///
10+
/// `IPrinterStrategy` combines the responsibilities of message formatting and
11+
/// final output delivery. Types conforming to this protocol use an array of
12+
/// `ILogFormatter` objects to transform raw messages before writing them
13+
/// to their respective destinations (e.g., Console, System Logs, or Files).
914
public protocol IPrinterStrategy {
10-
/// An array of log formatters to customize log message output.
15+
/// A collection of formatters used to process and style the log message content.
16+
///
17+
/// The formatters are typically applied in sequence to add metadata such as
18+
/// timestamps, emojis, or thread information.
1119
var formatters: [ILogFormatter] { get }
1220

13-
/// Logs a message with a specified log level.
21+
/// Processes and dispatches a log message.
22+
///
23+
/// Implementation should first pass the raw message through the `formatters`
24+
/// chain and then transmit the resulting string to the specific output target.
1425
///
1526
/// - Parameters:
16-
/// - message: A `String` value that contains the message to dispatch.
17-
/// - logLevel: A `LogLevel` value that contains the logging level.
27+
/// - message: The raw string content provided by the logger.
28+
/// - logLevel: The severity level used for both formatting decisions and
29+
/// target-specific severity mapping.
1830
func log(_ message: String, logLevel: LogLevel)
1931
}

Sources/Log/Classes/Core/Logger/Strategies/IStyleLogStrategy.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,31 @@ import Foundation
77

88
// MARK: - IStyleLogStrategy
99

10-
/// Specifies the format to be used in the log message
10+
/// A specialized printer strategy that focuses on styling log messages before output.
11+
///
12+
/// `IStyleLogStrategy` provides a default implementation for taking a raw log string
13+
/// and passing it through a chain of formatters. This ensures consistency in how
14+
/// logs look across different output targets (e.g., Console vs. OSLog).
1115
protocol IStyleLogStrategy: IPrinterStrategy {
12-
/// An array of log formatters to customize log message output.
16+
/// A collection of formatters used to customize the visual representation of the log.
1317
var formatters: [ILogFormatter] { get }
1418
}
1519

1620
extension IStyleLogStrategy {
17-
/// Format the message using formatting rules.
21+
/// Transforms a raw message into a formatted string by applying all registered formatters.
22+
///
23+
/// This method iterates through the `formatters` array in the order they were provided,
24+
/// allowing each formatter to append, prefix, or modify the string from the previous step.
1825
///
1926
/// - Parameters:
20-
/// - message: A `String` value that contains the message.
21-
/// - logLevel: A `LogLevel` value that contains the logging level.
27+
/// - message: The original raw string content to be logged.
28+
/// - logLevel: The severity level, which formatters use to determine styling
29+
/// (e.g., adding a 🔴 emoji for errors).
2230
///
23-
/// - Returns: Formatted message.
31+
/// - Returns: A final, fully styled string ready for output.
2432
func formatMessage(_ message: String, logLevel: LogLevel) -> String {
2533
var message = message
34+
// Sequentially transform the message string using the pipeline of formatters.
2635
formatters.forEach { message = $0.format(message: message, with: logLevel) }
2736
return message
2837
}

0 commit comments

Comments
 (0)