Skip to content

Commit f26d021

Browse files
maarztctrueden
authored andcommitted
Allow setting log levels for specified LogSources
1 parent 161b98a commit f26d021

File tree

6 files changed

+110
-21
lines changed

6 files changed

+110
-21
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ public void setLevel(final String classOrPackageName, final int level) {
8484
classAndPackageLevels.put(classOrPackageName, level);
8585
}
8686

87+
@Override
88+
public void setLevelForLogger(final String source, final int level) {
89+
rootLogger.getSource().subSource(source).setLogLevel(level);
90+
}
91+
8792
// -- Logger methods --
8893

8994
@Override

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ public void alwaysLog(final int level, final Object msg, final Throwable t) {
7777
}
7878

7979
public Logger subLogger(final String name, final int level) {
80-
return new DefaultLogger(this, source.subSource(name), level);
80+
LogSource source = getSource().subSource(name);
81+
int actualLevel = source.hasLogLevel() ? source.logLevel() : level;
82+
return new DefaultLogger(this, source, actualLevel);
8183
}
8284

8385
// -- Listenable methods --

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

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,30 @@ public interface LogService extends SciJavaService, Logger {
5050
/** System property to set for overriding the default logging level. */
5151
String LOG_LEVEL_PROPERTY = "scijava.log.level";
5252

53+
String LOG_LEVEL_BY_SOURCE_PROPERTY = "scijava.log.level.source";
54+
55+
/** Changes the log level of the root logger */
56+
void setLevel(int level);
57+
58+
/**
59+
* For messages that are logged directly to the LogService. The log level can
60+
* be set depending on the class that makes the log.
61+
*
62+
* @param classOrPackageName If this is the name of a class. Messages logged
63+
* directly by this class are logged, if the message's level is less
64+
* or equal to the given level. If this is a package, the same holds
65+
* for all classes in this package.
66+
* @param level Given level.
67+
*/
68+
void setLevel(String classOrPackageName, int level);
69+
70+
/**
71+
* Setting the log level for loggers depending on their {@link LogSource}.
72+
* This will only effect loggers that are created after is method has been
73+
* called.
74+
*/
75+
void setLevelForLogger(String source, int level);
76+
5377
// -- Deprecated --
5478

5579
/** @deprecated Use {@link LogLevel#NONE}. */
@@ -70,9 +94,4 @@ public interface LogService extends SciJavaService, Logger {
7094
/** @deprecated Use {@link LogLevel#TRACE}. */
7195
@Deprecated
7296
int TRACE = LogLevel.TRACE;
73-
74-
void setLevel(int level);
75-
76-
void setLevel(String classOrPackageName, int level);
77-
7897
}

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

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
*/
4646
public class LogSource {
4747

48+
public static final String SEPARATOR = ":";
49+
4850
private final LogSource parent;
4951

5052
private final List<String> path;
@@ -54,6 +56,8 @@ public class LogSource {
5456

5557
private String formatted = null;
5658

59+
private Integer logLevel;
60+
5761
private LogSource(LogSource parent, String name) {
5862
this.parent = parent;
5963
List<String> parentPath = parent.path();
@@ -73,6 +77,19 @@ public static LogSource newRoot() {
7377
return new LogSource();
7478
}
7579

80+
/**
81+
* Returns a log source with the given path.
82+
*
83+
* @param subPath Relative path to the source, divided by
84+
* {@link LogSource#SEPARATOR}.
85+
*/
86+
public LogSource subSource(final String subPath) {
87+
LogSource result = this;
88+
for (final String name : subPath.split(SEPARATOR))
89+
result = result.child(name);
90+
return result;
91+
}
92+
7693
/** Returns the list of strings which is represented by this LogSource. */
7794
public List<String> path() {
7895
return path;
@@ -84,22 +101,10 @@ public String name() {
84101
return path.get(path.size() - 1);
85102
}
86103

87-
/**
88-
* Returns the LogSource which represents the path of this LogSource extended
89-
* by name.
90-
*/
91-
public LogSource subSource(String name) {
92-
LogSource child = children.get(name);
93-
if (child != null) return child;
94-
child = new LogSource(this, name);
95-
children.putIfAbsent(name, child);
96-
return children.get(name);
97-
}
98-
99104
@Override
100105
public String toString() {
101106
if (formatted != null) return formatted;
102-
StringJoiner joiner = new StringJoiner(":");
107+
StringJoiner joiner = new StringJoiner(SEPARATOR);
103108
path.forEach(s -> joiner.add(s));
104109
formatted = joiner.toString();
105110
return formatted;
@@ -113,4 +118,28 @@ public boolean isRoot() {
113118
public LogSource parent() {
114119
return parent;
115120
}
121+
122+
public void setLogLevel(int logLevel) {
123+
this.logLevel = logLevel;
124+
}
125+
126+
public boolean hasLogLevel() {
127+
return logLevel != null;
128+
}
129+
130+
public int logLevel() {
131+
if (!hasLogLevel()) throw new IllegalStateException();
132+
return logLevel;
133+
}
134+
135+
// -- Helper methods --
136+
137+
private LogSource child(final String name) {
138+
if (name.isEmpty()) return this;
139+
LogSource child = children.get(name);
140+
if (child != null) return child;
141+
child = new LogSource(this, name);
142+
children.putIfAbsent(name, child);
143+
return children.get(name);
144+
}
116145
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ public void testClassLogLevelViaProperties() {
156156
assertEquals(LogLevel.ERROR, level);
157157
}
158158

159+
@Test
160+
public void testSubLoggerLogLevel() {
161+
final TestableLogService log = new TestableLogService();
162+
log.setLevel(LogLevel.ERROR);
163+
log.setLevelForLogger("foo:bar", LogLevel.TRACE);
164+
Logger sub = log.subLogger("foo").subLogger("bar");
165+
assertEquals(LogLevel.TRACE, sub.getLevel());
166+
}
167+
159168
@Test
160169
public void testPackageLogLevel() {
161170
final LogService log = new TestableLogService();

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@
3131

3232
package org.scijava.log;
3333

34-
import org.junit.Test;
34+
import static org.junit.Assert.assertEquals;
35+
import static org.junit.Assert.assertFalse;
36+
import static org.junit.Assert.assertSame;
37+
import static org.junit.Assert.assertTrue;
3538

3639
import java.util.Collections;
3740

38-
import static org.junit.Assert.*;
41+
import org.junit.Test;
3942

4043
/**
4144
* Tests {@link LogSource}
@@ -64,6 +67,14 @@ public void testChildIsUnique() {
6467
assertSame(a, b);
6568
}
6669

70+
@Test
71+
public void testLogSourceParse() {
72+
LogSource foo = LogSource.newRoot().subSource("foo");
73+
LogSource result = foo.subSource("Hello:World");
74+
LogSource expected = foo.subSource("Hello").subSource("World");
75+
assertEquals(expected, result);
76+
}
77+
6778
@Test
6879
public void testToString() {
6980
LogSource source = LogSource.newRoot().subSource("Hello").subSource("World");
@@ -90,4 +101,18 @@ public void testParent() {
90101
LogSource source = root.subSource("sub");
91102
assertSame(root, source.parent());
92103
}
104+
105+
@Test
106+
public void testUnsetLogLevel() {
107+
LogSource source = LogSource.newRoot();
108+
assertFalse(source.hasLogLevel());
109+
}
110+
111+
@Test
112+
public void testSetLogLevel() {
113+
LogSource source = LogSource.newRoot();
114+
source.setLogLevel(LogLevel.INFO);
115+
assertTrue(source.hasLogLevel());
116+
assertEquals(LogLevel.INFO, source.logLevel());
117+
}
93118
}

0 commit comments

Comments
 (0)