-
Notifications
You must be signed in to change notification settings - Fork 6
Configurable Logging #34
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
Merged
Changes from 6 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
dc2586b
add logging
stevensJourney 1580762
Improve loggers
stevensJourney 7e9325b
optional tag usage
stevensJourney f3e9210
Added logger to readme
stevensJourney 28cff04
update test
stevensJourney 075ff0c
cleanup
stevensJourney 8f0911f
Update Sources/PowerSync/Kotlin/DatabaseLogger.swift
stevensJourney b2efe62
Update Sources/PowerSync/LoggerProtocol.swift
stevensJourney 12250ff
Update Sources/PowerSync/Logger.swift
stevensJourney 608cb46
fix typo
stevensJourney 23beb9a
cleanup print logger
stevensJourney 0285979
Cleanup protocol
stevensJourney 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,106 @@ | ||
import PowerSyncKotlin | ||
|
||
/// Adapts a Swift `LoggerProtocol` to Kermit's `LogWriter` interface. | ||
/// | ||
/// This allows Kotlin logging (via Kermit) to call into the Swift logging implementation. | ||
private class KermitLogWriterAdapter: Kermit_coreLogWriter { | ||
/// The underlying Swift log writer to forward log messages to. | ||
let logger: any LoggerProtocol | ||
|
||
/// Initializes a new adapter. | ||
/// | ||
/// - Parameter logger: A Swift log writer that will handle log output. | ||
init(logger: any LoggerProtocol) { | ||
self.logger = logger | ||
super.init() | ||
} | ||
|
||
/// Called by Kermit to log a message. | ||
/// | ||
/// - Parameters: | ||
/// - severity: The severity level of the log. | ||
/// - message: The content of the log message. | ||
/// - tag: A string categorizing the log. | ||
/// - throwable: An optional Kotlin exception (ignored here). | ||
override func log(severity: Kermit_coreSeverity, message: String, tag: String, throwable: KotlinThrowable?) { | ||
switch severity { | ||
case PowerSyncKotlin.Kermit_coreSeverity.verbose: | ||
return logger.debug(message, tag: tag) | ||
case PowerSyncKotlin.Kermit_coreSeverity.debug: | ||
return logger.debug(message, tag: tag) | ||
case PowerSyncKotlin.Kermit_coreSeverity.info: | ||
return logger.info(message, tag: tag) | ||
case PowerSyncKotlin.Kermit_coreSeverity.warn: | ||
return logger.warning(message, tag: tag) | ||
case PowerSyncKotlin.Kermit_coreSeverity.error: | ||
return logger.error(message, tag: tag) | ||
case PowerSyncKotlin.Kermit_coreSeverity.assert: | ||
return logger.fault(message, tag: tag) | ||
} | ||
} | ||
} | ||
|
||
/// A logger implementation that integrates with PowerSync's Kotlin core using Kermit. | ||
/// | ||
/// This class bridges Swift log writers with the Kotlin logging system and supports | ||
/// runtime configuration of severity levels and writer lists. | ||
internal class DatabaseLogger: LoggerProtocol { | ||
/// The underlying Kermit logger instance provided by the PowerSyncKotlin SDK. | ||
public let kLogger = PowerSyncKotlin.generateLogger(logger: nil) | ||
public let logger: any LoggerProtocol | ||
|
||
/// Initializes a new logger with an optional list of writers. | ||
/// | ||
/// - Parameter logger: A logger which will be called for each internal log operation | ||
init(_ logger: any LoggerProtocol) { | ||
self.logger = logger | ||
// Set to the lowest severity. The provided logger should filter by severity | ||
kLogger.mutableConfig.setMinSeverity(Kermit_coreSeverity.verbose) | ||
kLogger.mutableConfig.setLogWriterList( | ||
[KermitLogWriterAdapter(logger: logger)] | ||
) | ||
} | ||
|
||
/// Sets the minimum severity level that will be logged. | ||
/// | ||
/// Messages below this level will be ignored. | ||
/// | ||
/// - Parameter severity: The minimum `LogSeverity` to allow through. | ||
public func setMinSeverity(_ severity: LogSeverity) { | ||
logger.setMinSeverity(severity) | ||
} | ||
|
||
/// Sets the list of log writers that will receive log messages. | ||
/// | ||
/// This updates both the internal writer list and the Kermit logger's configuration. | ||
/// | ||
/// - Parameter writers: An array of Swift `LogWritterProtocol` implementations. | ||
stevensJourney marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
public func setWriters(_ writers: [any LogWriterProtocol]) { | ||
logger.setWriters(writers) | ||
} | ||
|
||
/// Logs a debug-level message. | ||
public func debug(_ message: String, tag: String?) { | ||
logger.debug(message, tag: tag) | ||
} | ||
|
||
/// Logs an info-level message. | ||
public func info(_ message: String, tag: String?) { | ||
logger.info(message, tag: tag) | ||
} | ||
|
||
/// Logs a warning-level message. | ||
public func warning(_ message: String, tag: String?) { | ||
logger.warning(message, tag: tag) | ||
} | ||
|
||
/// Logs an error-level message. | ||
public func error(_ message: String, tag: String?) { | ||
logger.error(message, tag: tag) | ||
} | ||
|
||
/// Logs a fault (assert-level) message, typically used for critical issues. | ||
public func fault(_ message: String, tag: String?) { | ||
logger.fault(message, tag: tag) | ||
} | ||
} |
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,97 @@ | ||
import OSLog | ||
|
||
/// A log writer which prints to the standard output | ||
/// | ||
/// This writer uses `os.Logger` on iOS 14+ and falls back to `print` for earlier versions. | ||
public class PrintLogWriter: LogWriterProtocol { | ||
|
||
/// Logs a message with a given severity and optional tag. | ||
/// | ||
/// - Parameters: | ||
/// - severity: The severity level of the message. | ||
/// - message: The content of the log message. | ||
/// - tag: An optional tag used to categorize the message. If empty, no brackets are shown. | ||
public func log(severity: LogSeverity, message: String, tag: String?) { | ||
let tagPrefix: String | ||
if let tag, !tag.isEmpty { | ||
tagPrefix = "[\(tag)] " | ||
} else { | ||
tagPrefix = "" | ||
} | ||
|
||
let message = "\(tagPrefix) \(message)" | ||
if #available(iOS 14.0, *) { | ||
let l = Logger() | ||
|
||
switch severity { | ||
case .info: | ||
l.info("\(message)") | ||
case .error: | ||
l.error("\(message)") | ||
case .debug: | ||
l.debug("\(message)") | ||
case .warning: | ||
l.warning("\(message)") | ||
case .fault: | ||
l.fault("\(message)") | ||
} | ||
} else { | ||
print("\(severity.stringValue): \(message)") | ||
} | ||
} | ||
} | ||
|
||
/// A default logger configuration that uses `PrintLogWritter` and filters messages by minimum severity. | ||
public class DefaultLogger: LoggerProtocol { | ||
public var minSeverirty: LogSeverity | ||
stevensJourney marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
public var writers: [any LogWriterProtocol] | ||
|
||
/// Initializes the default logger with an optional minimum severity level. | ||
/// | ||
/// - Parameters | ||
/// - minSeverity: The minimum severity level to log. Defaults to `.debug`. | ||
/// - writers: Optional writers which logs should be written to. Defaults to a `PrintLogWriter`. | ||
public init(minSeverity: LogSeverity = .debug, writers: [any LogWriterProtocol]? = nil ) { | ||
self.writers = writers ?? [ PrintLogWriter() ] | ||
self.minSeverirty = minSeverity | ||
} | ||
|
||
public func setWriters(_ writters: [any LogWriterProtocol]) { | ||
self.writers = writters | ||
} | ||
|
||
public func setMinSeverity(_ severity: LogSeverity) { | ||
self.minSeverirty = severity | ||
} | ||
|
||
|
||
public func debug(_ message: String, tag: String? = nil) { | ||
self.writeLog(message, severity: LogSeverity.debug, tag: tag) | ||
} | ||
|
||
public func error(_ message: String, tag: String? = nil) { | ||
self.writeLog(message, severity: LogSeverity.error, tag: tag) | ||
} | ||
|
||
public func info(_ message: String, tag: String? = nil) { | ||
self.writeLog(message, severity: LogSeverity.info, tag: tag) | ||
} | ||
|
||
public func warning(_ message: String, tag: String? = nil) { | ||
self.writeLog(message, severity: LogSeverity.warning, tag: tag) | ||
} | ||
|
||
public func fault(_ message: String, tag: String? = nil) { | ||
self.writeLog(message, severity: LogSeverity.fault, tag: tag) | ||
} | ||
|
||
private func writeLog(_ message: String, severity: LogSeverity, tag: String?) { | ||
if (severity.rawValue < self.minSeverirty.rawValue) { | ||
return | ||
} | ||
|
||
for writer in self.writers { | ||
writer.log(severity: severity, message: message, tag: tag) | ||
} | ||
} | ||
} |
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.
Uh oh!
There was an error while loading. Please reload this page.