Skip to content

Commit f7f66b1

Browse files
maarztctrueden
authored andcommitted
Add Logger.subLogger methods
These methods allow to create a Logger instance that is a child of another Logger instance. Signed-off-by: Curtis Rueden <ctrueden@wisc.edu>
1 parent ac05b2f commit f7f66b1

File tree

5 files changed

+97
-23
lines changed

5 files changed

+97
-23
lines changed

src/main/java/org/scijava/log/AbstractLogService.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,7 @@ public AbstractLogService(final Properties properties) {
7272
LogService.LOG_LEVEL_PROPERTY + ":");
7373
}
7474

75-
// -- Logger methods --
76-
77-
@Override
78-
public int getLevel() {
79-
if (classAndPackageLevels.isEmpty()) return currentLevel;
80-
return getLevelForClass(CallingClassUtils.getCallingClass().getName(),
81-
currentLevel);
82-
}
75+
// -- AbstractLogService methods --
8376

8477
@Override
8578
public void setLevel(final int level) {
@@ -91,11 +84,30 @@ public void setLevel(final String classOrPackageName, final int level) {
9184
classAndPackageLevels.put(classOrPackageName, level);
9285
}
9386

87+
// -- Logger methods --
88+
9489
@Override
9590
public void alwaysLog(final int level, final Object msg, final Throwable t) {
9691
rootLogger.alwaysLog(level, msg, t);
9792
}
9893

94+
@Override
95+
public String getName() {
96+
return rootLogger.getName();
97+
}
98+
99+
@Override
100+
public int getLevel() {
101+
if (classAndPackageLevels.isEmpty()) return currentLevel;
102+
return getLevelForClass(CallingClassUtils.getCallingClass().getName(),
103+
currentLevel);
104+
}
105+
106+
@Override
107+
public Logger subLogger(String nameExtension, int level) {
108+
return rootLogger.subLogger(nameExtension, level);
109+
}
110+
99111
// -- Listenable methods --
100112

101113
@Override
@@ -162,17 +174,12 @@ private Map<String, Integer> setupMapFromProperties(Properties properties,
162174
private class RootLogger extends DefaultLogger {
163175

164176
public RootLogger() {
165-
super(LogLevel.NONE);
177+
super(AbstractLogService.this::notifyListeners, "", LogLevel.NONE);
166178
}
167179

168180
@Override
169181
public int getLevel() {
170182
return AbstractLogService.this.getLevel();
171183
}
172-
173-
@Override
174-
protected void messageLogged(LogMessage message) {
175-
AbstractLogService.this.notifyListeners(message);
176-
}
177184
}
178185
}

src/main/java/org/scijava/log/DefaultLogger.java

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,31 @@
4141
* @author Curtis Rueden
4242
*/
4343
@IgnoreAsCallingClass
44-
public class DefaultLogger implements Logger {
44+
public class DefaultLogger implements Logger, LogListener {
45+
46+
private final LogListener destination;
47+
48+
private final String name;
4549

4650
private final int level;
4751

4852
private final List<LogListener> listeners = new CopyOnWriteArrayList<>();
4953

50-
public DefaultLogger(final int level)
54+
public DefaultLogger(final LogListener destination, final String name,
55+
final int level)
5156
{
57+
this.destination = destination;
58+
this.name = name;
5259
this.level = level;
5360
}
5461

55-
// -- DefaultLogger methods --
62+
// -- Logger methods --
5663

57-
protected void messageLogged(final LogMessage message) {
58-
notifyListeners(message);
64+
@Override
65+
public String getName() {
66+
return name;
5967
}
6068

61-
// -- Logger methods --
62-
6369
@Override
6470
public int getLevel() {
6571
return level;
@@ -70,6 +76,10 @@ public void alwaysLog(final int level, final Object msg, final Throwable t) {
7076
messageLogged(new LogMessage(level, msg, t));
7177
}
7278

79+
public Logger subLogger(final String name, final int level) {
80+
return new DefaultLogger(this, name, level);
81+
}
82+
7383
// -- Listenable methods --
7484

7585
@Override
@@ -87,4 +97,13 @@ public void notifyListeners(final LogMessage message) {
8797
for (LogListener listener : listeners)
8898
listener.messageLogged(message);
8999
}
100+
101+
// -- LogListener methods --
102+
103+
@Override
104+
public void messageLogged(final LogMessage message) {
105+
for (LogListener listener : listeners)
106+
listener.messageLogged(message);
107+
destination.messageLogged(message);
108+
}
90109
}

src/main/java/org/scijava/log/Logger.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ default void log(final int level, final Throwable t) {
163163

164164
/**
165165
* Logs a message with an exception.
166-
*
166+
*
167167
* @param level The level at which the information will be logged. If the
168168
* current level (given by {@link #getLevel()} is below this one, no
169169
* logging is performed.
@@ -184,6 +184,24 @@ default void log(final int level, final Object msg, final Throwable t) {
184184
*/
185185
void alwaysLog(int level, Object msg, Throwable t);
186186

187+
/** Returns the name of this logger. */
188+
String getName();
189+
187190
/** Returns the log level of this logger. see {@link LogLevel} */
188191
int getLevel();
192+
193+
/**
194+
* Creates a sub logger, that forwards the message it gets to this logger. The
195+
* sub logger will have the same log level as this logger.
196+
*/
197+
default Logger subLogger(String name) {
198+
return subLogger(name, getLevel());
199+
}
200+
201+
/**
202+
* Creates a sub logger, that forwards the message it gets to this logger.
203+
*
204+
* @param level The log level of the sub logger.
205+
*/
206+
Logger subLogger(String name, int level);
189207
}

src/test/java/org/scijava/log/DefaultLoggerTest.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
package org.scijava.log;
3333

34+
import static org.junit.Assert.assertFalse;
3435
import static org.junit.Assert.assertTrue;
3536

3637
import org.junit.Before;
@@ -48,7 +49,7 @@ public class DefaultLoggerTest {
4849

4950
@Before
5051
public void setup() {
51-
logger = new DefaultLogger(LogLevel.INFO);
52+
logger = new DefaultLogger(message -> {}, "", LogLevel.INFO);
5253
listener = new TestLogListener();
5354
logger.addListener(listener);
5455
}
@@ -62,4 +63,30 @@ public void test() {
6263
assertTrue(listener.hasLogged(m -> m.text().equals("Hello World!")));
6364
assertTrue(listener.hasLogged(m -> m.level() == LogLevel.ERROR));
6465
}
66+
67+
@Test
68+
public void testSubLogger() {
69+
listener.clear();
70+
Logger sub = logger.subLogger("sub");
71+
72+
sub.error("Hello World!");
73+
74+
assertTrue(listener.hasLogged(m -> m.text().equals("Hello World!")));
75+
}
76+
77+
@Test
78+
public void testLogForwarding() {
79+
listener.clear();
80+
Logger sub = logger.subLogger("xyz");
81+
TestLogListener subListener = new TestLogListener();
82+
sub.addListener(subListener);
83+
84+
sub.error("Hello World!");
85+
logger.error("Goodbye!");
86+
87+
assertTrue(subListener.hasLogged(m -> m.text().equals("Hello World!")));
88+
assertFalse(subListener.hasLogged(m -> m.text().equals("Goodbye!")));
89+
assertTrue(listener.hasLogged(m -> m.text().equals("Hello World!")));
90+
assertTrue(listener.hasLogged(m -> m.text().equals("Goodbye!")));
91+
}
6592
}

src/test/java/org/scijava/log/LogServiceTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,14 @@ public void testListener() {
171171
TestableLogService logService = new TestableLogService();
172172
TestLogListener listener = new TestLogListener();
173173
String msg1 = "Hello World!";
174+
String msg2 = "foo bar";
174175
// process
175176
logService.addListener(listener);
176177
logService.error(msg1);
178+
logService.subLogger("xyz").debug(msg2);
177179
// test
178180
listener.hasLogged(m -> msg1.equals(m.text()));
181+
listener.hasLogged(m -> msg2.equals(m.text()));
179182
}
180183

181184
// -- Helper classes --

0 commit comments

Comments
 (0)