-
Notifications
You must be signed in to change notification settings - Fork 19
Logging module #830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+1,259
−138
Merged
Logging module #830
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
ae01cc3
Logging module
gthea 4898e7a
Move Logger to Logging (git mv)
gthea 3929de1
Logging module extracted
gthea e962e3e
Update README
gthea c14ee52
Remove unnecessary imports
gthea 200833a
Restore Split Logger shim
gthea 7dd76dd
Fix comments
gthea 5a412df
Remove unnecessary rename
gthea 83f8ded
Expose Logging as product
gthea 1293b49
SplitModules product
gthea 57f0791
WIP kaban
gthea 74bd67c
Umbrella module
gthea f4cae2d
Merge branch 'logging-module' of github.com:splitio/ios-client into l…
gthea e41ac65
Update README
gthea 1c3e531
Update Split podspec
gthea 87833da
Merge with master
gthea f3d5f84
Improve comments
gthea 75dc3a0
Add Logging dependency to watchOs
gthea 342afb5
Increase test coverage
gthea 9b7b7eb
Add Logging tests to sonar report
gthea 5d9335e
Default date provider
gthea File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // | ||
| // DateProvider.swift | ||
| // Logging | ||
| // | ||
| // Created by Split SDK Team | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| /// Protocol for providing date/time functionality to the logging system | ||
| public protocol DateProvider { | ||
| /// Returns current time in milliseconds since epoch | ||
| func nowMillis() -> Int64 | ||
|
|
||
| /// Returns a formatted timestamp string for logging | ||
| func nowLabel() -> String | ||
| } | ||
|
|
||
| /// Default implementation that uses Foundation's Date | ||
| public struct DefaultDateProvider: DateProvider { | ||
| public init() {} | ||
|
|
||
| private static let formatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.dateFormat = "dd-MM-yyyy HH:mm:ss.SSS" | ||
| return formatter | ||
| }() | ||
|
|
||
| public func nowMillis() -> Int64 { | ||
| return Int64(Date().timeIntervalSince1970 * 1000) | ||
| } | ||
|
|
||
| public func nowLabel() -> String { | ||
| return Self.formatter.string(from: Date()) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // | ||
| // LogLevel.swift | ||
| // Logging | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| /// Log level enumeration for the Logging module | ||
| public enum LogLevel: String { | ||
| case verbose = "VERBOSE" | ||
| case debug = "DEBUG" | ||
| case info = "INFO" | ||
| case warning = "WARNING" | ||
| case error = "ERROR" | ||
| case none = "NONE" | ||
|
|
||
| /// Returns the numeric order of the log level (lower = more verbose) | ||
| public func order() -> Int { | ||
| switch self { | ||
| case .verbose: | ||
| return 0 | ||
| case .debug: | ||
| return 1 | ||
| case .info: | ||
| return 2 | ||
| case .warning: | ||
| return 3 | ||
| case .error: | ||
| return 4 | ||
| case .none: | ||
| return 5 | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // | ||
| // LogPrinter.swift | ||
| // Logging | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| /// Protocol to enable testing for Logger class | ||
| public protocol LogPrinter { | ||
| func stdout(_ items: Any...) | ||
| } | ||
|
|
||
| /// Default implementation that prints to stdout | ||
| public class DefaultLogPrinter: LogPrinter { | ||
| public init() {} | ||
|
|
||
| public func stdout(_ items: Any...) { | ||
| print(items) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| // | ||
| // Logger.swift | ||
| // Logging | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| /// Main logger class for the Logging module | ||
| public class Logger: @unchecked Sendable { | ||
| public var printer: LogPrinter = DefaultLogPrinter() | ||
| public var dateProvider: DateProvider = DefaultDateProvider() | ||
| private let tag: String = "SplitSDK" | ||
|
|
||
| public var level: LogLevel = .none | ||
|
|
||
| public static let shared: Logger = { | ||
| return Logger() | ||
| }() | ||
|
|
||
| private init() {} | ||
|
|
||
| private func log(level: LogLevel, msg: String, _ ctx: Any ...) { | ||
| if level.order() < self.level.order() { | ||
| return | ||
| } | ||
|
|
||
| let timeLabel = dateProvider.nowLabel() | ||
| if ctx.count == 0 { | ||
| printer.stdout(timeLabel, level.rawValue, tag, msg) | ||
| } else { | ||
| printer.stdout(timeLabel, level.rawValue, tag, msg, ctx[0]) | ||
| } | ||
| } | ||
|
|
||
| public static func v(_ message: String, _ context: Any ...) { | ||
| shared.log(level: .verbose, msg: message, context) | ||
| } | ||
|
|
||
| public static func d(_ message: String, _ context: Any ...) { | ||
| shared.log(level: .debug, msg: message, context) | ||
| } | ||
|
|
||
| public static func i(_ message: String, _ context: Any ...) { | ||
| shared.log(level: .info, msg: message, context) | ||
| } | ||
|
|
||
| public static func w(_ message: String, _ context: Any ...) { | ||
| shared.log(level: .warning, msg: message, context) | ||
| } | ||
|
|
||
| public static func e(_ message: String, _ context: Any ...) { | ||
| shared.log(level: .error, msg: message, context) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import Foundation | ||
|
|
||
| public struct LoggingInternal { | ||
| public init() {} | ||
| public func action() { | ||
| print("Logging ready.") | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| # Logging | ||
|
|
||
| ## What this module provides | ||
|
|
||
| - `Logger`: shared logger with convenience methods `Logger.v/d/i/w/e` | ||
| - `LogLevel`: logging level enum | ||
| - `LogPrinter`: output interface (default prints to stdout) | ||
| - `TimeChecker`: helper to measure and log time intervals | ||
| - `DateProvider`: timestamp + label formatting (ships with a `DefaultDateProvider` backed by `Foundation.Date`) | ||
|
|
||
| ## Usage | ||
|
|
||
| ### 1) Configure (optional) | ||
|
|
||
| The module ships with a `DefaultDateProvider` that uses `Foundation.Date`, so it works out of the box. You can still supply a custom `DateProvider` if you need different formatting or a custom clock: | ||
|
|
||
| ```swift | ||
| import Logging | ||
|
|
||
| // Optional: override the default provider | ||
| Logger.shared.dateProvider = MyCustomDateProvider() | ||
| Logger.shared.level = .info | ||
| ``` | ||
|
|
||
| ### 2) Log | ||
|
|
||
| ```swift | ||
| import Logging | ||
|
|
||
| Logger.i("SDK initialized") | ||
| Logger.w("Something looks off", ["context": "value"]) | ||
| Logger.e("Something failed") | ||
| ``` | ||
|
|
||
| ### Optional: customize output | ||
|
|
||
| ```swift | ||
| import Logging | ||
|
|
||
| final class MyPrinter: LogPrinter { | ||
| func stdout(_ items: Any...) { | ||
| // route to OSLog, a file, your analytics, etc. | ||
| } | ||
| } | ||
|
|
||
| Logger.shared.printer = MyPrinter() | ||
| ``` | ||
|
|
||
| ### Optional: TimeChecker | ||
|
|
||
| `TimeChecker` uses `Logger.shared.dateProvider` by default. | ||
|
|
||
| ```swift | ||
| import Logging | ||
|
|
||
| TimeChecker.start() | ||
| // ... do work ... | ||
| TimeChecker.logInterval("Finished work") | ||
| ``` | ||
|
|
||
| ## Notes | ||
|
|
||
| - If the consumer has its own log levels, do the mapping in the consumer module (e.g. map `YourLogLevel` → `LogLevel`). | ||
|
|
||
| ## Running tests | ||
|
|
||
| ### Swift Package Manager | ||
|
|
||
| From the repository root: | ||
|
|
||
| ```bash | ||
| swift test --filter LoggingTests | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // | ||
| // LogPrinterStub.swift | ||
| // LoggingTests | ||
| // | ||
| // Created by Javier Avrudsky on 08-Jul-2022. | ||
| // Copyright © 2022 Split. All rights reserved. | ||
| // | ||
|
|
||
| import Foundation | ||
| @testable import Logging | ||
|
|
||
| class LogPrinterStub: LogPrinter, @unchecked Sendable { | ||
|
|
||
| private(set) var logs = [String]() | ||
|
|
||
| private let queue = DispatchQueue(label: "Logging.LogPrinterStub", | ||
| target: .global()) | ||
|
|
||
| func stdout(_ items: Any...) { | ||
| queue.sync { | ||
| self.logs.append(items.map { "\($0)" }.joined(separator: ",")) | ||
| } | ||
| } | ||
|
|
||
| func clear() { | ||
| queue.sync { | ||
| self.logs.removeAll() | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we wrap this in IF DEBUG macros?