@@ -5,7 +5,8 @@ import scala.collection.mutable
5
5
6
6
object Logger {
7
7
8
- val GLOBAL_LOGGER_NAME : String = " global"
8
+ final val GLOBAL_LOGGER_NAME = " global"
9
+ private final val ROOT_LOGGER_NAME = " "
9
10
10
11
// Not implemented, deprecated on JDK 1.8
11
12
// val global: Logger
@@ -14,30 +15,57 @@ object Logger {
14
15
15
16
private val loggers : mutable.Map [String , Logger ] = mutable.Map .empty
16
17
18
+ /** Find parent logger */
19
+ @ tailrec
20
+ private def findParentLoggerOf (name : String ): Logger = {
21
+ name match {
22
+ case null => // Anonymous logger
23
+ rootLogger
24
+ case ROOT_LOGGER_NAME =>
25
+ null
26
+ case _ =>
27
+ val parentName = name.substring(0 , name.lastIndexOf('.' ).max(0 ))
28
+ loggers.get(parentName) match {
29
+ case Some (l) => l
30
+ case None => findParentLoggerOf(parentName)
31
+ }
32
+ }
33
+ }
34
+
17
35
private def newLogger (name : String ): Logger = {
18
36
val logger = new Logger (name, null )
19
37
logger.setLevel(null )
20
38
logger.setUseParentHandlers(true )
21
- logger.setParent(rootLogger)
39
+ logger.setParent(findParentLoggerOf(name))
40
+ if (name != null ) {
41
+ updateChildLoggerParent(logger)
42
+ }
22
43
logger
23
44
}
24
45
46
+ private def updateChildLoggerParent (newParent : Logger ): Unit = {
47
+ val prefix = s " ${newParent.getName}. "
48
+ // Traverse all child loggers of the new parent
49
+ for ((name, childLogger) <- loggers if name.startsWith(prefix)) {
50
+ val currentParent = childLogger.getParent
51
+ // For example, when a new parent a.b is added:
52
+ // - if child is a.b.c.d (parent = null) => needs to be a.b.c.d (parent = a.b)
53
+ // - if child is a.b.c.e (parent = a.b.c) => no update is required.
54
+ if (currentParent == null || ! currentParent.getName.startsWith(prefix)) {
55
+ childLogger.setParent(newParent)
56
+ }
57
+ }
58
+ }
59
+
25
60
// Root is not visible to the outside but gives defaults
26
61
private [this ] val rootLogger : Logger = {
27
- val l = new Logger (" " , null )
28
- l.setLevel(defaultLogLevel)
29
- l.setUseParentHandlers(false )
30
- l.setParent(null )
31
- l
62
+ val root = getLogger(ROOT_LOGGER_NAME )
63
+ root.setLevel(defaultLogLevel)
64
+ root.setUseParentHandlers(false )
65
+ root
32
66
}
33
67
34
- private [this ] val globalLogger : Logger = {
35
- val l = new Logger (GLOBAL_LOGGER_NAME , null )
36
- l.setLevel(defaultLogLevel)
37
- l.setUseParentHandlers(true )
38
- l.setParent(rootLogger)
39
- l
40
- }
68
+ private [this ] val globalLogger : Logger = getLogger(GLOBAL_LOGGER_NAME )
41
69
42
70
def getGlobal (): Logger = globalLogger
43
71
@@ -51,20 +79,6 @@ object Logger {
51
79
// Not implemented, no resource bundle in scala.js
52
80
// def getLogger(name: String, resourceBundle: String): Logger
53
81
54
- private [logging] def findParent (logger : Logger ): Option [Logger ] = {
55
- @ tailrec
56
- def go (s : List [String ]): Option [Logger ] = s match {
57
- case Nil => None
58
-
59
- case b if loggers.contains(b.mkString(" ." )) =>
60
- loggers.get(b.mkString(" ." ))
61
-
62
- case b => go(b.dropRight(1 ))
63
- }
64
-
65
- go(Option (logger.getName).getOrElse(" " ).split(" \\ ." ).toList.dropRight(1 ))
66
- }
67
-
68
82
def getAnonymousLogger (): Logger = {
69
83
// No references to anonymous loggers are kept
70
84
newLogger(null )
@@ -315,7 +329,7 @@ class Logger(name: String, resourceBundle: String) {
315
329
316
330
def getUseParentHandlers (): Boolean = useParentsHandlers
317
331
318
- def getParent (): Logger = Logger .findParent( this ).getOrElse( parent)
332
+ def getParent (): Logger = parent
319
333
320
334
def setParent (parent : Logger ): Unit = this .parent = parent
321
335
}
0 commit comments