BufferedLogger is a tiny but thread-safe logger with a buffering and retrying mechanism for iOS.
You can use this framework...
github "yoheimuta/BufferedLogger"
pod "BufferedLogger"
For details, refer to a Demo project.
Posted log entries are buffered and emitted as a chunk on a routine schedule.
write method is ensured to call serially, which means it is run by a serial queue.
class MyWriter: Writer {
func write(_ chunk: Chunk, completion: @escaping (Bool) -> Void) {
// You can implement something useful like uploading logs to your server.
print("chunk is \(chunk)")
chunk.entries.forEach {
print("entry is \($0)")
}
completion(true)
}
}
You have to register your writer to the logger and can post your log with it from any thread.
A call to post method is no blocking.
import BufferedLogger
logger = BFLogger(writer: MyWriter())
logger.post("1".data(using: .utf8)!)
logger.post("2".data(using: .utf8)!)
logger.post("3".data(using: .utf8)!)
You can also create your configuration for buffering and emitting mechanism.
If you omit to define your configuration, default below is used. Each meaning is in a comment.
/// Config represents a configuration for buffering and writing logs.
public struct Config {
/// flushEntryCount is the maximum number of entries per one chunk.
/// When the number of entries of buffer reaches this count, it starts to write a chunk.
public let flushEntryCount: Int
/// flushInterval is a interval to write a chunk.
public let flushInterval: TimeInterval
/// retryRule is a rule of retry.
public let retryRule: RetryRule
/// maxEntryCountInStorage is a max count of entry to be saved in the storage.
/// When the number of entries in the storage reaches this count, it starts to
/// delete the older entries.
public let maxEntryCountInStorage: Int
/// storagePath is a path to the entries.
/// When you uses multiple BFLogger, you must set an unique path.
public let storagePath: String
public init(flushEntryCount: Int = 5,
flushInterval: TimeInterval = 10,
retryRule: RetryRule = DefaultRetryRule(retryLimit: 3),
maxEntryCountInStorage: Int = 1000,
storagePath: String = defaultStoragePath) {
self.flushEntryCount = flushEntryCount
self.flushInterval = flushInterval
self.retryRule = retryRule
self.maxEntryCountInStorage = maxEntryCountInStorage
self.storagePath = storagePath
}
/// default is a default configuration.
public static let `default` = Config()
}
BufferedLogger stores the unsent entries in the local storage when the application couldn't send log entries.
By default, it stores them in local files in the Library/Caches directory.
You can also define your own custom log entry storage backed by any storage system.
See the EntryStroage protocol for more details.
The MIT License (MIT)
Thank you to the Puree-Swift: https://github.com/cookpad/Puree-Swift
I inspired by this library for the elaborate design, interface and some implementation.