4242 * Base class for {@link LogService} implementations.
4343 *
4444 * @author Johannes Schindelin
45+ * @author Curtis Rueden
4546 */
47+ @ IgnoreAsCallingClass
4648public abstract class AbstractLogService extends AbstractService implements
4749 LogService
4850{
4951
5052 private int currentLevel = levelFromEnvironment ();
5153
52- private final Map <String , Integer > classAndPackageLevels =
53- new HashMap <>();
54-
55- // -- abstract methods --
56-
57- /**
58- * Displays a message.
59- *
60- * @param msg the message to display.
61- */
62- protected abstract void log (final String msg );
63-
64- /**
65- * Displays an exception.
66- *
67- * @param t the exception to display.
68- */
69- protected abstract void log (final Throwable t );
54+ private final Map <String , Integer > classAndPackageLevels ;
7055
7156 // -- constructor --
7257
@@ -75,160 +60,21 @@ public AbstractLogService() {
7560 }
7661
7762 public AbstractLogService (final Properties properties ) {
78- // check SciJava log level system properties for initial logging levels
79-
80- // global log level property
81- final String logProp = properties .getProperty (LOG_LEVEL_PROPERTY );
82- final int level = LogLevel .value (logProp );
83- if (level >= 0 ) setLevel (level );
84-
85- if (getLevel () == 0 )
86- setLevel (levelFromEnvironment ());
87-
88- // populate custom class- and package-specific log level properties
89- final String logLevelPrefix = LOG_LEVEL_PROPERTY + ":" ;
90- for (final Object propKey : properties .keySet ()) {
91- if (!(propKey instanceof String )) continue ;
92- final String propName = (String ) propKey ;
93- if (!propName .startsWith (logLevelPrefix )) continue ;
94- final String classOrPackageName =
95- propName .substring (logLevelPrefix .length ());
96- setLevel (classOrPackageName , LogLevel .value (properties .getProperty (propName )));
97- }
98-
99- }
100-
101- // -- helper methods --
102-
103- protected void log (final int level , final Object msg , final Throwable t ) {
104- if (level > getLevel ()) return ;
105-
106- if (msg != null || t == null ) {
107- log (level , msg );
108- }
109- if (t != null ) log (t );
110- }
111-
112- protected void log (final int level , final Object msg ) {
113- final String prefix = LogLevel .prefix (level );
114- log ((prefix == null ? "" : prefix + " " ) + msg );
115- }
116-
117- // -- LogService methods --
118-
119- @ Override
120- public void debug (final Object msg ) {
121- log (LogLevel .DEBUG , msg , null );
122- }
123-
124- @ Override
125- public void debug (final Throwable t ) {
126- log (LogLevel .DEBUG , null , t );
127- }
128-
129- @ Override
130- public void debug (final Object msg , final Throwable t ) {
131- log (LogLevel .DEBUG , msg , t );
132- }
133-
134- @ Override
135- public void error (final Object msg ) {
136- log (LogLevel .ERROR , msg , null );
137- }
138-
139- @ Override
140- public void error (final Throwable t ) {
141- log (LogLevel .ERROR , null , t );
142- }
143-
144- @ Override
145- public void error (final Object msg , final Throwable t ) {
146- log (LogLevel .ERROR , msg , t );
147- }
148-
149- @ Override
150- public void info (final Object msg ) {
151- log (LogLevel .INFO , msg , null );
63+ // provide this constructor to enable unit tests
64+ final int level = LogLevel .value (properties .getProperty (
65+ LogService .LOG_LEVEL_PROPERTY ));
66+ if (level >= 0 ) currentLevel = level ;
67+ classAndPackageLevels = setupMapFromProperties (properties ,
68+ LogService .LOG_LEVEL_PROPERTY + ":" );
15269 }
15370
154- @ Override
155- public void info (final Throwable t ) {
156- log (LogLevel .INFO , null , t );
157- }
158-
159- @ Override
160- public void info (final Object msg , final Throwable t ) {
161- log (LogLevel .INFO , msg , t );
162- }
163-
164- @ Override
165- public void trace (final Object msg ) {
166- log (LogLevel .TRACE , msg , null );
167- }
168-
169- @ Override
170- public void trace (final Throwable t ) {
171- log (LogLevel .TRACE , null , t );
172- }
173-
174- @ Override
175- public void trace (final Object msg , final Throwable t ) {
176- log (LogLevel .TRACE , msg , t );
177- }
178-
179- @ Override
180- public void warn (final Object msg ) {
181- log (LogLevel .WARN , msg , null );
182- }
183-
184- @ Override
185- public void warn (final Throwable t ) {
186- log (LogLevel .WARN , null , t );
187- }
188-
189- @ Override
190- public void warn (final Object msg , final Throwable t ) {
191- log (LogLevel .WARN , msg , t );
192- }
193-
194- @ Override
195- public boolean isDebug () {
196- return getLevel () >= LogLevel .DEBUG ;
197- }
198-
199- @ Override
200- public boolean isError () {
201- return getLevel () >= LogLevel .ERROR ;
202- }
203-
204- @ Override
205- public boolean isInfo () {
206- return getLevel () >= LogLevel .INFO ;
207- }
208-
209- @ Override
210- public boolean isTrace () {
211- return getLevel () >= LogLevel .TRACE ;
212- }
213-
214- @ Override
215- public boolean isWarn () {
216- return getLevel () >= LogLevel .WARN ;
217- }
71+ // -- Logger methods --
21872
21973 @ Override
22074 public int getLevel () {
221- if (!classAndPackageLevels .isEmpty ()) {
222- // check for a custom log level for calling class or its parent packages
223- String classOrPackageName = callingClass ();
224- while (classOrPackageName != null ) {
225- final Integer level = classAndPackageLevels .get (classOrPackageName );
226- if (level != null ) return level ;
227- classOrPackageName = parentPackage (classOrPackageName );
228- }
229- }
230- // no custom log level; return the global log level
231- return currentLevel ;
75+ if (classAndPackageLevels .isEmpty ()) return currentLevel ;
76+ return getLevelForClass (CallingClassUtils .getCallingClass ().getName (),
77+ currentLevel );
23278 }
23379
23480 @ Override
@@ -251,14 +97,14 @@ protected String getPrefix(final int level) {
25197
25298 // -- Helper methods --
25399
254- private String callingClass ( ) {
255- final String thisClass = AbstractLogService . class . getName ();
256- for ( final StackTraceElement element : new Exception (). getStackTrace () ) {
257- final String className = element . getClassName ( );
258- // NB: Skip stack trace elements from other methods of this class.
259- if (! thisClass . equals ( className )) return className ;
100+ private int getLevelForClass ( String classOrPackageName , int defaultLevel ) {
101+ // check for a custom log level for calling class or its parent packages
102+ while ( classOrPackageName != null ) {
103+ final Integer level = classAndPackageLevels . get ( classOrPackageName );
104+ if ( level != null ) return level ;
105+ classOrPackageName = parentPackage ( classOrPackageName ) ;
260106 }
261- return null ;
107+ return defaultLevel ;
262108 }
263109
264110 private String parentPackage (final String classOrPackageName ) {
@@ -272,4 +118,15 @@ private int levelFromEnvironment() {
272118 return System .getenv ("DEBUG" ) == null ? LogLevel .INFO : LogLevel .DEBUG ;
273119 }
274120
121+ private Map <String , Integer > setupMapFromProperties (Properties properties ,
122+ String prefix )
123+ {
124+ final HashMap <String , Integer > map = new HashMap <>();
125+ for (final String propName : properties .stringPropertyNames ())
126+ if (propName .startsWith (prefix )) {
127+ final String key = propName .substring (prefix .length ());
128+ map .put (key , LogLevel .value (properties .getProperty (propName )));
129+ }
130+ return map ;
131+ }
275132}
0 commit comments