001/* 002 * This is free and unencumbered software released into the public domain. 003 * 004 * Please see https://github.com/binkley/binkley/blob/master/LICENSE.md. 005 */ 006 007package hm.binkley.util.logging; 008 009import ch.qos.logback.classic.Level; 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012import org.slf4j.Marker; 013import org.slf4j.ext.LoggerWrapper; 014 015import javax.annotation.Nonnull; 016 017import static ch.qos.logback.classic.Level.DEBUG; 018import static ch.qos.logback.classic.Level.ERROR; 019import static ch.qos.logback.classic.Level.INFO; 020import static ch.qos.logback.classic.Level.TRACE; 021import static ch.qos.logback.classic.Level.WARN; 022import static java.lang.String.format; 023import static java.lang.System.out; 024 025/** 026 * {@code MinimalLogger} complains about trivial logging. When a logger supports only a given level 027 * or greater, attempts to log at a lesser level throw {@code IllegalStateException}. 028 * 029 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a> 030 */ 031public class MinimumLogger 032 extends LoggerWrapper { 033 private final Level minimum; 034 035 /** 036 * Gets the underlying wrapped logger for extensions. 037 * 038 * @return the underlying logger, never missing 039 */ 040 @Nonnull 041 public final Logger getUnderlying() { 042 return logger; 043 } 044 045 /** 046 * Constructs a new {@code MinimalLogger} for the given parameters. 047 * 048 * @param logger the logger to delegate to, never missing 049 * @param minimum the minimum, non-trivial level of logging, never missing 050 */ 051 public MinimumLogger(@Nonnull final Logger logger, @Nonnull final Level minimum) { 052 this(logger, MinimumLogger.class.getName(), minimum); 053 } 054 055 /** 056 * Constructs a new {@code MinimalLogger} for the given parameters suitable as a base class. 057 * 058 * @param logger the logger to delegate to, never missing 059 * @param fqcn the fully-qualified class name of the extending logger, never missing 060 * @param minimum the minimum, non-trivial level of logging, never missing 061 */ 062 public MinimumLogger(@Nonnull final Logger logger, @Nonnull final String fqcn, 063 @Nonnull final Level minimum) { 064 super(logger, fqcn); 065 this.minimum = minimum; 066 } 067 068 @Override 069 public boolean isTraceEnabled() { 070 return TRACE.isGreaterOrEqual(minimum) && logger.isTraceEnabled(); 071 } 072 073 @Override 074 public boolean isTraceEnabled(final Marker marker) { 075 return TRACE.isGreaterOrEqual(minimum) && logger.isTraceEnabled(marker); 076 } 077 078 @Override 079 public void trace(final String msg) { 080 require(TRACE); 081 super.trace(msg); 082 } 083 084 @Override 085 public void trace(final String format, final Object arg) { 086 require(TRACE); 087 super.trace(format, arg); 088 } 089 090 @Override 091 public void trace(final String format, final Object arg1, final Object arg2) { 092 require(TRACE); 093 super.trace(format, arg1, arg2); 094 } 095 096 @Override 097 public void trace(final String format, final Object... args) { 098 require(TRACE); 099 super.trace(format, args); 100 } 101 102 @Override 103 public void trace(final String msg, final Throwable t) { 104 require(TRACE); 105 super.trace(msg, t); 106 } 107 108 @Override 109 public void trace(final Marker marker, final String msg) { 110 require(TRACE); 111 super.trace(marker, msg); 112 } 113 114 @Override 115 public void trace(final Marker marker, final String format, final Object arg) { 116 require(TRACE); 117 super.trace(marker, format, arg); 118 } 119 120 @Override 121 public void trace(final Marker marker, final String format, final Object arg1, 122 final Object arg2) { 123 require(TRACE); 124 super.trace(marker, format, arg1, arg2); 125 } 126 127 @Override 128 public void trace(final Marker marker, final String format, final Object... args) { 129 require(TRACE); 130 super.trace(marker, format, args); 131 } 132 133 @Override 134 public void trace(final Marker marker, final String msg, final Throwable t) { 135 require(TRACE); 136 super.trace(marker, msg, t); 137 } 138 139 @Override 140 public boolean isDebugEnabled() { 141 return DEBUG.isGreaterOrEqual(minimum) && logger.isDebugEnabled(); 142 } 143 144 @Override 145 public boolean isDebugEnabled(final Marker marker) { 146 return DEBUG.isGreaterOrEqual(minimum) && logger.isDebugEnabled(marker); 147 } 148 149 @Override 150 public void debug(final String msg) { 151 require(DEBUG); 152 super.debug(msg); 153 } 154 155 @Override 156 public void debug(final String format, final Object arg) { 157 require(DEBUG); 158 super.debug(format, arg); 159 } 160 161 @Override 162 public void debug(final String format, final Object arg1, final Object arg2) { 163 require(DEBUG); 164 super.debug(format, arg1, arg2); 165 } 166 167 @Override 168 public void debug(final String format, final Object... argArray) { 169 require(DEBUG); 170 super.debug(format, argArray); 171 } 172 173 @Override 174 public void debug(final String msg, final Throwable t) { 175 require(DEBUG); 176 super.debug(msg, t); 177 } 178 179 @Override 180 public void debug(final Marker marker, final String msg) { 181 require(DEBUG); 182 super.debug(marker, msg); 183 } 184 185 @Override 186 public void debug(final Marker marker, final String format, final Object arg) { 187 require(DEBUG); 188 super.debug(marker, format, arg); 189 } 190 191 @Override 192 public void debug(final Marker marker, final String format, final Object arg1, 193 final Object arg2) { 194 require(DEBUG); 195 super.debug(marker, format, arg1, arg2); 196 } 197 198 @Override 199 public void debug(final Marker marker, final String format, final Object... argArray) { 200 require(DEBUG); 201 super.debug(marker, format, argArray); 202 } 203 204 @Override 205 public void debug(final Marker marker, final String msg, final Throwable t) { 206 require(DEBUG); 207 super.debug(marker, msg, t); 208 } 209 210 @Override 211 public boolean isInfoEnabled() { 212 return INFO.isGreaterOrEqual(minimum) && logger.isInfoEnabled(); 213 } 214 215 @Override 216 public boolean isInfoEnabled(final Marker marker) { 217 return INFO.isGreaterOrEqual(minimum) && logger.isInfoEnabled(marker); 218 } 219 220 @Override 221 public void info(final String msg) { 222 require(INFO); 223 super.info(msg); 224 } 225 226 @Override 227 public void info(final String format, final Object arg) { 228 require(INFO); 229 super.info(format, arg); 230 } 231 232 @Override 233 public void info(final String format, final Object arg1, final Object arg2) { 234 require(INFO); 235 super.info(format, arg1, arg2); 236 } 237 238 @Override 239 public void info(final String format, final Object... args) { 240 require(INFO); 241 super.info(format, args); 242 } 243 244 @Override 245 public void info(final String msg, final Throwable t) { 246 require(INFO); 247 super.info(msg, t); 248 } 249 250 @Override 251 public void info(final Marker marker, final String msg) { 252 require(INFO); 253 super.info(marker, msg); 254 } 255 256 @Override 257 public void info(final Marker marker, final String format, final Object arg) { 258 require(INFO); 259 super.info(marker, format, arg); 260 } 261 262 @Override 263 public void info(final Marker marker, final String format, final Object arg1, 264 final Object arg2) { 265 require(INFO); 266 super.info(marker, format, arg1, arg2); 267 } 268 269 @Override 270 public void info(final Marker marker, final String format, final Object... args) { 271 require(INFO); 272 super.info(marker, format, args); 273 } 274 275 @Override 276 public void info(final Marker marker, final String msg, final Throwable t) { 277 require(INFO); 278 super.info(marker, msg, t); 279 } 280 281 @Override 282 public boolean isWarnEnabled() { 283 return WARN.isGreaterOrEqual(minimum) && logger.isWarnEnabled(); 284 } 285 286 @Override 287 public boolean isWarnEnabled(final Marker marker) { 288 return WARN.isGreaterOrEqual(minimum) && logger.isWarnEnabled(marker); 289 } 290 291 @Override 292 public void warn(final String msg) { 293 require(WARN); 294 super.warn(msg); 295 } 296 297 @Override 298 public void warn(final String format, final Object arg) { 299 require(WARN); 300 super.warn(format, arg); 301 } 302 303 @Override 304 public void warn(final String format, final Object arg1, final Object arg2) { 305 require(WARN); 306 super.warn(format, arg1, arg2); 307 } 308 309 @Override 310 public void warn(final String format, final Object... args) { 311 require(WARN); 312 super.warn(format, args); 313 } 314 315 @Override 316 public void warn(final String msg, final Throwable t) { 317 require(WARN); 318 super.warn(msg, t); 319 } 320 321 @Override 322 public void warn(final Marker marker, final String msg) { 323 require(WARN); 324 super.warn(marker, msg); 325 } 326 327 @Override 328 public void warn(final Marker marker, final String format, final Object arg) { 329 require(WARN); 330 super.warn(marker, format, arg); 331 } 332 333 @Override 334 public void warn(final Marker marker, final String format, final Object arg1, 335 final Object arg2) { 336 require(WARN); 337 super.warn(marker, format, arg1, arg2); 338 } 339 340 @Override 341 public void warn(final Marker marker, final String format, final Object... args) { 342 require(WARN); 343 super.warn(marker, format, args); 344 } 345 346 @Override 347 public void warn(final Marker marker, final String msg, final Throwable t) { 348 require(WARN); 349 super.warn(marker, msg, t); 350 } 351 352 @Override 353 public boolean isErrorEnabled() { 354 return WARN.isGreaterOrEqual(minimum) && logger.isWarnEnabled(); 355 } 356 357 @Override 358 public boolean isErrorEnabled(final Marker marker) { 359 return WARN.isGreaterOrEqual(minimum) && logger.isWarnEnabled(marker); 360 } 361 362 @Override 363 public void error(final String msg) { 364 require(ERROR); 365 super.error(msg); 366 } 367 368 @Override 369 public void error(final String format, final Object arg) { 370 require(ERROR); 371 super.error(format, arg); 372 } 373 374 @Override 375 public void error(final String format, final Object arg1, final Object arg2) { 376 require(ERROR); 377 super.error(format, arg1, arg2); 378 } 379 380 @Override 381 public void error(final String format, final Object... args) { 382 require(ERROR); 383 super.error(format, args); 384 } 385 386 @Override 387 public void error(final String msg, final Throwable t) { 388 require(ERROR); 389 super.error(msg, t); 390 } 391 392 @Override 393 public void error(final Marker marker, final String msg) { 394 require(ERROR); 395 super.error(marker, msg); 396 } 397 398 @Override 399 public void error(final Marker marker, final String format, final Object arg) { 400 require(ERROR); 401 super.error(marker, format, arg); 402 } 403 404 @Override 405 public void error(final Marker marker, final String format, final Object arg1, 406 final Object arg2) { 407 require(ERROR); 408 super.error(marker, format, arg1, arg2); 409 } 410 411 @Override 412 public void error(final Marker marker, final String format, final Object... args) { 413 require(ERROR); 414 super.error(marker, format, args); 415 } 416 417 @Override 418 public void error(final Marker marker, final String msg, final Throwable t) { 419 require(ERROR); 420 super.error(marker, msg, t); 421 } 422 423 private void require(final Level current) { 424 if (!current.isGreaterOrEqual(minimum)) 425 throw new IllegalStateException( 426 format("%s logging disabled for logger \"%s\" [%s]", current, getName(), 427 getClass().getName())); 428 } 429 430 public static void main(final String... args) { 431 try { 432 final MinimumLogger main = new MinimumLogger(LoggerFactory.getLogger("main"), INFO); 433 main.info("Just fine"); 434 main.trace("Too trivial!"); 435 } catch (final IllegalStateException e) { 436 e.printStackTrace(out); 437 } 438 } 439}