Skip to content

Commit 4117c9b

Browse files
authored
Merge pull request jduquennoy#29 from serges147/master
2 parents 2528f78 + ab5a7e3 commit 4117c9b

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

Log4swift/Logger.swift

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ A logger is identified by a UTI identifier, it defines a threshold level and a d
4444

4545
/// The UTI string that identifies the logger. Example : product.module.feature
4646
public let identifier: String
47-
47+
4848
internal var parent: Logger?
4949

5050
private var thresholdLevelStorage: LogLevel
5151
private var appendersStorage: [Appender]
5252
private var asynchronousStorage = false
53+
private var timeProviderStorage: () -> Date = Date.init
5354

5455
/// If asynchronous is true, only the minimum of work will be done on the main thread, the rest will be deffered to a low priority background thread.
5556
/// The order of the messages will be preserved in async mode.
@@ -103,7 +104,30 @@ A logger is identified by a UTI identifier, it defines a threshold level and a d
103104
}
104105
}
105106

106-
107+
/// Gets/sets external time provider for log messages.
108+
/// Default behavior is just `Date()`.
109+
///
110+
/// Allows to "mock" the time - could be useful in unit tests
111+
/// which may run on some "virtual" time instead of real one.
112+
///
113+
/// Child loggers inherit this value so it's possible to set it only once
114+
/// (on the `rootLogger` for example) - entire sub-hierarchy of loggers will have it.
115+
///
116+
@objc
117+
public var timeProvider: () -> Date {
118+
get {
119+
if let parent = self.parent {
120+
return parent.timeProvider
121+
} else {
122+
return self.timeProviderStorage
123+
}
124+
}
125+
set {
126+
self.breakDependencyWithParent()
127+
self.timeProviderStorage = newValue
128+
}
129+
}
130+
107131
/// Creates a new logger with the given identifier, log level and appenders.
108132
/// The identifier will not be modifiable, and should not be an empty string.
109133
@objc
@@ -236,7 +260,7 @@ A logger is identified by a UTI identifier, it defines a threshold level and a d
236260
var info: LogInfoDictionary = [
237261
.LoggerName: self.identifier,
238262
.LogLevel: level,
239-
.Timestamp: NSDate().timeIntervalSince1970,
263+
.Timestamp: self.timeProvider().timeIntervalSince1970,
240264
.ThreadId: currentThreadId(),
241265
.ThreadName: currentThreadName()
242266
]
@@ -265,7 +289,7 @@ A logger is identified by a UTI identifier, it defines a threshold level and a d
265289
var info: LogInfoDictionary = [
266290
.LoggerName: self.identifier,
267291
.LogLevel: level,
268-
.Timestamp: NSDate().timeIntervalSince1970,
292+
.Timestamp: self.timeProvider().timeIntervalSince1970,
269293
.ThreadId: currentThreadId(),
270294
.ThreadName: currentThreadName()
271295
]
@@ -304,6 +328,7 @@ A logger is identified by a UTI identifier, it defines a threshold level and a d
304328
}
305329
self.thresholdLevelStorage = parent.thresholdLevel
306330
self.appendersStorage = parent.appenders
331+
self.timeProviderStorage = parent.timeProvider
307332
self.parent = nil
308333
}
309334

Log4swiftTests/LoggerTests.swift

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,18 @@ class LoggerTests: XCTestCase {
539539
XCTAssertTrue(sonIsAsynchronous)
540540
}
541541

542+
func testLoggerWithParentUsesParentTimeProvider() {
543+
let parentLogger = Logger(identifier: "parent.logger", level: .Info, appenders: [MemoryAppender()])
544+
let sonLogger = Logger(parentLogger: parentLogger, identifier: "son.logger")
545+
546+
// Execute
547+
let testDate = Date(timeIntervalSince1970: 42)
548+
parentLogger.timeProvider = { return testDate }
549+
550+
// Validate
551+
XCTAssertEqual(sonLogger.timeProvider(), testDate)
552+
}
553+
542554
func testChangingSonLoggerParameterBreakLinkWithParent() {
543555
let parentLogger = Logger(identifier: "parent.logger", level: .Info, appenders: [MemoryAppender()])
544556
let sonLogger = Logger(parentLogger: parentLogger, identifier: "son.logger")
@@ -565,7 +577,6 @@ class LoggerTests: XCTestCase {
565577
XCTAssertNil(sonLogger.parent)
566578
}
567579

568-
569580
func testSettingSonLoggerAsyncStatusBreakLinkWithParent() {
570581
let parentLogger = Logger(identifier: "parent.logger", level: .Info, appenders: [MemoryAppender()])
571582
let sonLogger = Logger(parentLogger: parentLogger, identifier: "son.logger")
@@ -579,6 +590,24 @@ class LoggerTests: XCTestCase {
579590
XCTAssertFalse(parentLogger.asynchronous)
580591
XCTAssertTrue(sonLogger.asynchronous)
581592
}
593+
594+
func testSettingSonLoggerTimeProviderBreakLinkWithParent() {
595+
let parentLogger = Logger(identifier: "parent.logger", level: .Info, appenders: [MemoryAppender()])
596+
let sonLogger = Logger(parentLogger: parentLogger, identifier: "son.logger")
597+
let testDate = (
598+
Date(timeIntervalSince1970: 42),
599+
Date(timeIntervalSince1970: 13)
600+
)
601+
parentLogger.timeProvider = { return testDate.0 }
602+
603+
// Execute
604+
sonLogger.timeProvider = { return testDate.1 }
605+
606+
// Validate
607+
XCTAssertNil(sonLogger.parent)
608+
XCTAssertEqual(parentLogger.timeProvider(), testDate.0)
609+
XCTAssertEqual(sonLogger.timeProvider(), testDate.1)
610+
}
582611

583612
func testLoggedTimeIsTakenWhenLogIsRequested() {
584613
let formatter = try! PatternFormatter(identifier:"testFormatter", pattern: "%d{'format':'%s'}")
@@ -599,7 +628,22 @@ class LoggerTests: XCTestCase {
599628
}
600629
}
601630

602-
631+
func testLoggedProvidedTime() {
632+
let formatter = try! PatternFormatter(identifier:"testFormatter", pattern: "%D{'format':'ss.SSS'}")
633+
let appender = MemoryAppender()
634+
appender.thresholdLevel = .Debug
635+
appender.formatter = formatter
636+
let logger = Logger(identifier: "test.identifier", level: .Debug, appenders: [appender])
637+
638+
logger.timeProvider = { Date(timeIntervalSince1970: 42.147) }
639+
640+
// Execute
641+
logger.debug("This is a debug message")
642+
643+
// Validate
644+
XCTAssertEqual(appender.logMessages[0].message, "42.147")
645+
}
646+
603647
func testLoggingStringWithPercentAndNoParametersDoesNotCrash() {
604648
let appender = MemoryAppender()
605649
appender.thresholdLevel = .Debug

0 commit comments

Comments
 (0)