1 package org.djutils.logger; 2 3 import java.util.Arrays; 4 import java.util.LinkedHashMap; 5 import java.util.LinkedHashSet; 6 import java.util.Map; 7 import java.util.Set; 8 import java.util.function.BooleanSupplier; 9 10 import org.djutils.exceptions.Throw; 11 import org.djutils.immutablecollections.Immutable; 12 import org.djutils.immutablecollections.ImmutableLinkedHashSet; 13 import org.djutils.immutablecollections.ImmutableSet; 14 import org.pmw.tinylog.Configurator; 15 import org.pmw.tinylog.Level; 16 import org.pmw.tinylog.LogEntryForwarder; 17 import org.pmw.tinylog.Logger; 18 import org.pmw.tinylog.writers.ConsoleWriter; 19 import org.pmw.tinylog.writers.Writer; 20 21 /** 22 * The CategoryLogger can log for specific Categories. The way to call the logger for messages that always need to be logged, 23 * such as an error with an exception is: 24 * 25 * <pre> 26 * CategoryLogger.always().error(exception, "Parameter {} did not initialize correctly", param1.toString()); 27 * </pre> 28 * 29 * It is also possible to indicate the category / categories for the message, which will only be logged if at least one of the 30 * indicated categories is turned on with addLogCategory() or setLogCategories(), or if one of the added or set LogCategories is 31 * LogCategory.ALL: 32 * 33 * <pre> 34 * CategoryLogger.filter(Cat.BASE).debug("Parameter {} initialized correctly", param1.toString()); 35 * </pre> 36 * <p> 37 * Copyright (c) 2018-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See 38 * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is 39 * distributed under a three-clause BSD-style license, which can be found at 40 * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>. 41 * </p> 42 * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank"> Alexander Verbraeck</a> 43 */ 44 @SuppressWarnings("checkstyle:needbraces") 45 public final class CategoryLogger 46 { 47 /** The default message format. */ 48 public static final String DEFAULT_MESSAGE_FORMAT = "{class_name}.{method}:{line} {message|indent=4}"; 49 50 /** The current message format. */ 51 private static String defaultMessageFormat = DEFAULT_MESSAGE_FORMAT; 52 53 /** The current logging level. */ 54 private static Level defaultLevel = Level.INFO; 55 56 /** The writers registered with this CategoryLogger. */ 57 private static final Set<Writer> WRITERS = new LinkedHashSet<>(); 58 59 /** The log level per Writer. */ 60 private static final Map<Writer, Level> WRITER_LEVELS = new LinkedHashMap<>(); 61 62 /** The message format per Writer. */ 63 private static final Map<Writer, String> WRITER_FORMATS = new LinkedHashMap<>(); 64 65 /** The categories to log. */ 66 private static final Set<LogCategory> LOG_CATEGORIES = new LinkedHashSet<>(256); 67 68 /** A cached immutable copy of the log categories to return to `extending` classes. */ 69 private static ImmutableSet<LogCategory> immutableLogCategories; 70 71 /** The delegate logger instance that does the actual logging work, after a positive filter outcome. */ 72 public static final DelegateLogger DELEGATE_LOGGER = new DelegateLogger(true); 73 74 /** The delegate logger that returns immediately after a negative filter outcome. */ 75 public static final DelegateLogger NO_LOGGER = new DelegateLogger(false); 76 77 /** */ 78 private CategoryLogger() 79 { 80 // Utility class. 81 } 82 83 static 84 { 85 create(); 86 } 87 88 /** 89 * Create a new logger for the system console. Note that this REPLACES current writers. Note that the initial LogCategory is 90 * LogCategory.ALL, so all categories will be logged. This category has to be explicitly removed (or new categories have to 91 * be set) to log a limited set of categories. 92 */ 93 protected static void create() 94 { 95 Logger.getConfiguration().removeAllWriters().activate(); 96 addWriter(new ConsoleWriter()); 97 LOG_CATEGORIES.add(LogCategory.ALL); 98 immutableLogCategories = new ImmutableLinkedHashSet<>(LOG_CATEGORIES, Immutable.COPY); 99 } 100 101 /** 102 * Set a new logging format for the message lines of all writers. The default message format is:<br> 103 * {class_name}.{method}:{line} {message|indent=4}<br> 104 * <br> 105 * A few popular placeholders that can be used:<br> 106 * - {class} Fully-qualified class name where the logging request is issued<br> 107 * - {class_name} Class name (without package) where the logging request is issued<br> 108 * - {date} Date and time of the logging request, e.g. {date:yyyy-MM-dd HH:mm:ss} [SimpleDateFormat]<br> 109 * - {level} Logging level of the created log entry<br> 110 * - {line} Line number from where the logging request is issued<br> 111 * - {message} Associated message of the created log entry<br> 112 * - {method} Method name from where the logging request is issued<br> 113 * - {package} Package where the logging request is issued<br> 114 * Because all individual writers get a log level at which they log, the overall log level in the Configurator is 115 * Level.TRACE, which means that all messages are passed through on a generic level and it is up to the individual Writers 116 * to decide when to log. 117 * @see <a href="https://tinylog.org/configuration#format">https://tinylog.org/configuration</a> 118 * @param newMessageFormat String; the new formatting pattern to use for all registered writers 119 */ 120 public static void setAllLogMessageFormat(final String newMessageFormat) 121 { 122 Configurator configurator = Logger.getConfiguration(); 123 defaultMessageFormat = newMessageFormat; 124 configurator.formatPattern(defaultMessageFormat).level(Level.TRACE); 125 for (Writer writer : WRITERS) 126 { 127 configurator.removeWriter(writer).activate(); 128 WRITER_FORMATS.put(writer, newMessageFormat); 129 configurator.addWriter(writer, WRITER_LEVELS.get(writer), defaultMessageFormat); 130 } 131 configurator.activate(); 132 } 133 134 /** 135 * Set a new logging level for all registered writers. Because all individual writers get a log level at which they log, the 136 * overall log level in the Configurator is Level.TRACE, which means that all messages are passed through on a generic level 137 * and it is up to the individual Writers to decide when to log. 138 * @param newLevel Level; the new log level for all registered writers 139 */ 140 public static void setAllLogLevel(final Level newLevel) 141 { 142 Configurator configurator = Logger.getConfiguration(); 143 defaultLevel = newLevel; 144 configurator.formatPattern(defaultMessageFormat).level(Level.TRACE); 145 for (Writer writer : WRITERS) 146 { 147 configurator.removeWriter(writer).activate(); 148 WRITER_LEVELS.put(writer, newLevel); 149 configurator.addWriter(writer, newLevel, WRITER_FORMATS.get(writer)); 150 } 151 configurator.activate(); 152 } 153 154 /** 155 * Set a new logging format for the message lines of a writer. The default message format is:<br> 156 * {class_name}.{method}:{line} {message|indent=4}<br> 157 * <br> 158 * A few popular placeholders that can be used:<br> 159 * - {class} Fully-qualified class name where the logging request is issued<br> 160 * - {class_name} Class name (without package) where the logging request is issued<br> 161 * - {date} Date and time of the logging request, e.g. {date:yyyy-MM-dd HH:mm:ss} [SimpleDateFormat]<br> 162 * - {level} Logging level of the created log entry<br> 163 * - {line} Line number from where the logging request is issued<br> 164 * - {message} Associated message of the created log entry<br> 165 * - {method} Method name from where the logging request is issued<br> 166 * - {package} Package where the logging request is issued<br> 167 * @see <a href="https://tinylog.org/configuration#format">https://tinylog.org/configuration</a> 168 * @param writer Writer; the writer to change the message format for 169 * @param newMessageFormat String; the new formatting pattern to use for all registered writers 170 */ 171 public static void setLogMessageFormat(final Writer writer, final String newMessageFormat) 172 { 173 Configurator configurator = Logger.getConfiguration(); 174 configurator.removeWriter(writer); 175 WRITER_FORMATS.put(writer, newMessageFormat); 176 configurator.addWriter(writer, WRITER_LEVELS.get(writer), newMessageFormat); 177 configurator.activate(); 178 } 179 180 /** 181 * Set a new logging level for one of the registered writers. 182 * @param writer Writer; the writer to change the log level for 183 * @param newLevel Level; the new log level for the writer 184 */ 185 public static void setLogLevel(final Writer writer, final Level newLevel) 186 { 187 Configurator configurator = Logger.getConfiguration(); 188 configurator.removeWriter(writer); 189 WRITER_LEVELS.put(writer, newLevel); 190 configurator.addWriter(writer, newLevel, WRITER_FORMATS.get(writer)); 191 configurator.activate(); 192 } 193 194 /** 195 * Add a writer to the CategoryLogger, using the current default for the log level and for the message format. 196 * @param writer Writer; the writer to add 197 * @return boolean; true when the writer was added; false when the writer was already registered 198 */ 199 public static boolean addWriter(final Writer writer) 200 { 201 Throw.whenNull(writer, "writer may not be null"); 202 Configurator configurator = Logger.getConfiguration(); 203 boolean result = WRITERS.add(writer); 204 WRITER_LEVELS.put(writer, defaultLevel); 205 WRITER_FORMATS.put(writer, defaultMessageFormat); 206 configurator.addWriter(writer, defaultLevel, defaultMessageFormat); 207 configurator.activate(); 208 return result; 209 } 210 211 /** 212 * Remove a writer from the CategoryLogger. 213 * @param writer Writer; the writer to remove 214 * @return boolean; true if the writer was removed; false if the writer was not registered (and thus could not be removed) 215 */ 216 public static boolean removeWriter(final Writer writer) 217 { 218 Throw.whenNull(writer, "writer may not be null"); 219 Configurator configurator = Logger.getConfiguration(); 220 boolean result = WRITERS.remove(writer); 221 WRITER_LEVELS.remove(writer); 222 WRITER_FORMATS.remove(writer); 223 configurator.removeWriter(writer); 224 configurator.activate(); 225 return result; 226 } 227 228 /** 229 * Return the set of all registered writers. 230 * @return ImmutableSet<Writer>; the set of all registered writers 231 */ 232 public static ImmutableSet<Writer> getWriters() 233 { 234 return new ImmutableLinkedHashSet<>(WRITERS, Immutable.WRAP); 235 } 236 237 /** 238 * Add a category to be logged to the Writers. 239 * @param logCategory LogCategory; the LogCategory to add 240 */ 241 public static void addLogCategory(final LogCategory logCategory) 242 { 243 LOG_CATEGORIES.add(logCategory); 244 immutableLogCategories = new ImmutableLinkedHashSet<>(LOG_CATEGORIES, Immutable.COPY); 245 } 246 247 /** 248 * Remove a category to be logged to the Writers. 249 * @param logCategory LogCategory; the LogCategory to remove 250 */ 251 public static void removeLogCategory(final LogCategory logCategory) 252 { 253 LOG_CATEGORIES.remove(logCategory); 254 immutableLogCategories = new ImmutableLinkedHashSet<>(LOG_CATEGORIES, Immutable.COPY); 255 } 256 257 /** 258 * Set the categories to be logged to the Writers. 259 * @param newLogCategories LogCategory...; the LogCategories to set, replacing the previous ones 260 */ 261 public static void setLogCategories(final LogCategory... newLogCategories) 262 { 263 LOG_CATEGORIES.clear(); 264 LOG_CATEGORIES.addAll(Arrays.asList(newLogCategories)); 265 immutableLogCategories = new ImmutableLinkedHashSet<>(LOG_CATEGORIES, Immutable.COPY); 266 } 267 268 /** 269 * Return the set of all log categories (cached immutable copy). 270 * @return ImmutableSet<Writer>; the set of all registered writers 271 */ 272 public static ImmutableSet<LogCategory> getLogCategories() 273 { 274 return immutableLogCategories; 275 } 276 277 /* ****************************************** FILTER ******************************************/ 278 279 /** 280 * The "pass" filter that will result in always trying to log. 281 * @return the logger that tries to execute logging (delegateLogger) 282 */ 283 public static DelegateLogger always() 284 { 285 return DELEGATE_LOGGER; 286 } 287 288 /** 289 * Check whether the provided category needs to be logged. Note that when LogCategory.ALL is contained in the categories, 290 * filter will return true. 291 * @param logCategory LogCategory; the category to check for. 292 * @return the logger that either tries to log (delegateLogger), or returns without logging (noLogger) 293 */ 294 public static DelegateLogger filter(final LogCategory logCategory) 295 { 296 if (LOG_CATEGORIES.contains(LogCategory.ALL)) 297 return DELEGATE_LOGGER; 298 if (LOG_CATEGORIES.contains(logCategory)) 299 return DELEGATE_LOGGER; 300 return NO_LOGGER; 301 } 302 303 /** 304 * Check whether the provided categories contain one or more categories that need to be logged. Note that when 305 * LogCategory.ALL is contained in the categories, filter will return true. 306 * @param logCategories LogCategory...; elements or array with the categories to check for 307 * @return the logger that either tries to log (delegateLogger), or returns without logging (noLogger) 308 */ 309 public static DelegateLogger filter(final LogCategory... logCategories) 310 { 311 if (LOG_CATEGORIES.contains(LogCategory.ALL)) 312 return DELEGATE_LOGGER; 313 for (LogCategory logCategory : logCategories) 314 { 315 if (LOG_CATEGORIES.contains(logCategory)) 316 return DELEGATE_LOGGER; 317 } 318 return NO_LOGGER; 319 } 320 321 /** 322 * Check whether the provided categories contain one or more categories that need to be logged. Note that when 323 * LogCategory.ALL is contained in the categories, filter will return true. 324 * @param logCategories Set<LogCategory>; the categories to check for 325 * @return the logger that either tries to log (delegateLogger), or returns without logging (noLogger) 326 */ 327 public static DelegateLogger filter(final Set<LogCategory> logCategories) 328 { 329 if (LOG_CATEGORIES.contains(LogCategory.ALL)) 330 return DELEGATE_LOGGER; 331 for (LogCategory logCategory : logCategories) 332 { 333 if (LOG_CATEGORIES.contains(logCategory)) 334 return DELEGATE_LOGGER; 335 } 336 return NO_LOGGER; 337 } 338 339 /** 340 * The conditional filter that will result in the usage of a DelegateLogger. 341 * @param condition boolean; the condition that should be evaluated 342 * @return the logger that further processes logging (DelegateLogger) 343 */ 344 public static DelegateLogger when(final boolean condition) 345 { 346 if (condition) 347 return DELEGATE_LOGGER; 348 return NO_LOGGER; 349 } 350 351 /** 352 * The conditional filter that will result in the usage of a DelegateLogger. 353 * @param supplier BooleanSupplier; the function evaluating the condition 354 * @return the logger that further processes logging (DelegateLogger) 355 */ 356 public static DelegateLogger when(final BooleanSupplier supplier) 357 { 358 if (supplier.getAsBoolean()) 359 return DELEGATE_LOGGER; 360 return NO_LOGGER; 361 } 362 363 /* ************************************ DELEGATE LOGGER ***************************************/ 364 365 /** 366 * DelegateLogger class that takes care of actually logging the message and/or exception. <br> 367 * <p> 368 * Copyright (c) 2003-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights 369 * reserved.<br> 370 * BSD-style license. See <a href="https://djutils.org/docs/current/djutils/licenses.html">DJUTILS License</a>. 371 * </p> 372 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a> 373 */ 374 public static class DelegateLogger 375 { 376 /** Should we try to log or not? */ 377 private final boolean log; 378 379 /** 380 * @param log boolean; indicate whether we should log or not. 381 */ 382 public DelegateLogger(final boolean log) 383 { 384 this.log = log; 385 } 386 387 /** 388 * The conditional filter that will result in the usage of a DelegateLogger. 389 * @param condition boolean; the condition that should be evaluated 390 * @return the logger that further processes logging (DelegateLogger) 391 */ 392 public DelegateLogger when(final boolean condition) 393 { 394 if (this.log && condition) 395 return this; 396 return CategoryLogger.NO_LOGGER; 397 } 398 399 /** 400 * The conditional filter that will result in the usage of a DelegateLogger. 401 * @param supplier BooleanSupplier; the function evaluating the condition 402 * @return the logger that further processes logging (DelegateLogger) 403 */ 404 public DelegateLogger when(final BooleanSupplier supplier) 405 { 406 if (this.log && supplier.getAsBoolean()) 407 return this; 408 return CategoryLogger.NO_LOGGER; 409 } 410 411 /* ****************************************** TRACE ******************************************/ 412 413 /** 414 * Create a trace log entry that will always be output, independent of LogCategory settings. 415 * @param object Object; the result of the <code>toString()</code> method of <code>object</code> will be logged 416 */ 417 public void trace(final Object object) 418 { 419 if (this.log) 420 LogEntryForwarder.forward(1, Level.TRACE, object); 421 } 422 423 /** 424 * Create a trace log entry that will always be output, independent of LogCategory settings. 425 * @param message String; the message to log 426 */ 427 public void trace(final String message) 428 { 429 if (this.log) 430 LogEntryForwarder.forward(1, Level.TRACE, message); 431 } 432 433 /** 434 * Create a trace log entry that will always be output, independent of LogCategory settings. 435 * @param message String; the message to be logged, where {} entries will be replaced by arguments 436 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 437 */ 438 public void trace(final String message, final Object... arguments) 439 { 440 if (this.log) 441 LogEntryForwarder.forward(1, Level.TRACE, message, arguments); 442 } 443 444 /** 445 * Create a trace log entry that will always be output, independent of LogCategory settings. 446 * @param exception Throwable; the exception to log 447 */ 448 public void trace(final Throwable exception) 449 { 450 if (this.log) 451 LogEntryForwarder.forward(1, Level.TRACE, exception); 452 } 453 454 /** 455 * Create a trace log entry that will always be output, independent of LogCategory settings. 456 * @param exception Throwable; the exception to log 457 * @param message String; the message to log 458 */ 459 public void trace(final Throwable exception, final String message) 460 { 461 if (this.log) 462 LogEntryForwarder.forward(1, Level.TRACE, exception, message); 463 } 464 465 /** 466 * Create a trace log entry that will always be output, independent of LogCategory settings. 467 * @param exception Throwable; the exception to log 468 * @param message String; the message to log, where {} entries will be replaced by arguments 469 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 470 */ 471 public void trace(final Throwable exception, final String message, final Object... arguments) 472 { 473 if (this.log) 474 LogEntryForwarder.forward(1, Level.TRACE, exception, message, arguments); 475 } 476 477 /* ****************************************** DEBUG ******************************************/ 478 479 /** 480 * Create a debug log entry that will always be output, independent of LogCategory settings. 481 * @param object Object; the result of the <code>toString()</code> method of <code>object</code> will be logged 482 */ 483 public void debug(final Object object) 484 { 485 if (this.log) 486 LogEntryForwarder.forward(1, Level.DEBUG, object); 487 } 488 489 /** 490 * Create a debug log entry that will always be output, independent of LogCategory settings. 491 * @param message String; the message to log 492 */ 493 public void debug(final String message) 494 { 495 if (this.log) 496 LogEntryForwarder.forward(1, Level.DEBUG, message); 497 } 498 499 /** 500 * Create a debug log entry that will always be output, independent of LogCategory settings. 501 * @param message String; the message to be logged, where {} entries will be replaced by arguments 502 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 503 */ 504 public void debug(final String message, final Object... arguments) 505 { 506 if (this.log) 507 LogEntryForwarder.forward(1, Level.DEBUG, message, arguments); 508 } 509 510 /** 511 * Create a debug log entry that will always be output, independent of LogCategory settings. 512 * @param exception Throwable; the exception to log 513 */ 514 public void debug(final Throwable exception) 515 { 516 if (this.log) 517 LogEntryForwarder.forward(1, Level.DEBUG, exception); 518 } 519 520 /** 521 * Create a debug log entry that will always be output, independent of LogCategory settings. 522 * @param exception Throwable; the exception to log 523 * @param message String; the message to log 524 */ 525 public void debug(final Throwable exception, final String message) 526 { 527 if (this.log) 528 LogEntryForwarder.forward(1, Level.DEBUG, exception, message); 529 } 530 531 /** 532 * Create a debug log entry that will always be output, independent of LogCategory settings. 533 * @param exception Throwable; the exception to log 534 * @param message String; the message to log, where {} entries will be replaced by arguments 535 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 536 */ 537 public void debug(final Throwable exception, final String message, final Object... arguments) 538 { 539 if (this.log) 540 LogEntryForwarder.forward(1, Level.DEBUG, exception, message, arguments); 541 } 542 543 /* ****************************************** INFO ******************************************/ 544 545 /** 546 * Create a info log entry that will always be output, independent of LogCategory settings. 547 * @param object Object; the result of the <code>toString()</code> method of <code>object</code> will be logged 548 */ 549 public void info(final Object object) 550 { 551 if (this.log) 552 LogEntryForwarder.forward(1, Level.INFO, object); 553 } 554 555 /** 556 * Create a info log entry that will always be output, independent of LogCategory settings. 557 * @param message String; the message to log 558 */ 559 public void info(final String message) 560 { 561 if (this.log) 562 LogEntryForwarder.forward(1, Level.INFO, message); 563 } 564 565 /** 566 * Create a info log entry that will always be output, independent of LogCategory settings. 567 * @param message String; the message to be logged, where {} entries will be replaced by arguments 568 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 569 */ 570 public void info(final String message, final Object... arguments) 571 { 572 if (this.log) 573 LogEntryForwarder.forward(1, Level.INFO, message, arguments); 574 } 575 576 /** 577 * Create a info log entry that will always be output, independent of LogCategory settings. 578 * @param exception Throwable; the exception to log 579 */ 580 public void info(final Throwable exception) 581 { 582 if (this.log) 583 LogEntryForwarder.forward(1, Level.INFO, exception); 584 } 585 586 /** 587 * Create a info log entry that will always be output, independent of LogCategory settings. 588 * @param exception Throwable; the exception to log 589 * @param message String; the message to log 590 */ 591 public void info(final Throwable exception, final String message) 592 { 593 if (this.log) 594 LogEntryForwarder.forward(1, Level.INFO, exception, message); 595 } 596 597 /** 598 * Create a info log entry that will always be output, independent of LogCategory settings. 599 * @param exception Throwable; the exception to log 600 * @param message String; the message to log, where {} entries will be replaced by arguments 601 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 602 */ 603 public void info(final Throwable exception, final String message, final Object... arguments) 604 { 605 if (this.log) 606 LogEntryForwarder.forward(1, Level.INFO, exception, message, arguments); 607 } 608 609 /* ****************************************** WARN ******************************************/ 610 611 /** 612 * Create a warn log entry that will always be output, // TODO: explain better independent of LogCategory settings. 613 * @param object Object; the result of the <code>toString()</code> method of <code>object</code> will be logged 614 */ 615 public void warn(final Object object) 616 { 617 if (this.log) 618 LogEntryForwarder.forward(1, Level.WARNING, object); 619 } 620 621 /** 622 * Create a warn log entry that will always be output, independent of LogCategory settings. 623 * @param message String; the message to log 624 */ 625 public void warn(final String message) 626 { 627 if (this.log) 628 LogEntryForwarder.forward(1, Level.WARNING, message); 629 } 630 631 /** 632 * Create a warn log entry that will always be output, independent of LogCategory settings. 633 * @param message String; the message to be logged, where {} entries will be replaced by arguments 634 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 635 */ 636 public void warn(final String message, final Object... arguments) 637 { 638 if (this.log) 639 LogEntryForwarder.forward(1, Level.WARNING, message, arguments); 640 } 641 642 /** 643 * Create a warn log entry that will always be output, independent of LogCategory settings. 644 * @param exception Throwable; the exception to log 645 */ 646 public void warn(final Throwable exception) 647 { 648 if (this.log) 649 LogEntryForwarder.forward(1, Level.WARNING, exception); 650 } 651 652 /** 653 * Create a warn log entry that will always be output, independent of LogCategory settings. 654 * @param exception Throwable; the exception to log 655 * @param message String; the message to log 656 */ 657 public void warn(final Throwable exception, final String message) 658 { 659 if (this.log) 660 LogEntryForwarder.forward(1, Level.WARNING, exception, message); 661 } 662 663 /** 664 * Create a warn log entry that will always be output, independent of LogCategory settings. 665 * @param exception Throwable; the exception to log 666 * @param message String; the message to log, where {} entries will be replaced by arguments 667 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 668 */ 669 public void warn(final Throwable exception, final String message, final Object... arguments) 670 { 671 if (this.log) 672 LogEntryForwarder.forward(1, Level.WARNING, exception, message, arguments); 673 } 674 675 /* ****************************************** ERROR ******************************************/ 676 677 /** 678 * Create a error log entry that will always be output, independent of LogCategory settings. 679 * @param object Object; the result of the <code>toString()</code> method of <code>object</code> will be logged 680 */ 681 public void error(final Object object) 682 { 683 if (this.log) 684 LogEntryForwarder.forward(1, Level.ERROR, object); 685 } 686 687 /** 688 * Create a error log entry that will always be output, independent of LogCategory settings. 689 * @param message String; the message to log 690 */ 691 public void error(final String message) 692 { 693 if (this.log) 694 LogEntryForwarder.forward(1, Level.ERROR, message); 695 } 696 697 /** 698 * Create a error log entry that will always be output, independent of LogCategory settings. 699 * @param message String; the message to be logged, where {} entries will be replaced by arguments 700 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 701 */ 702 public void error(final String message, final Object... arguments) 703 { 704 if (this.log) 705 LogEntryForwarder.forward(1, Level.ERROR, message, arguments); 706 } 707 708 /** 709 * Create a error log entry that will always be output, independent of LogCategory settings. 710 * @param exception Throwable; the exception to log 711 */ 712 public void error(final Throwable exception) 713 { 714 if (this.log) 715 LogEntryForwarder.forward(1, Level.ERROR, exception); 716 } 717 718 /** 719 * Create a error log entry that will always be output, independent of LogCategory settings. 720 * @param exception Throwable; the exception to log 721 * @param message String; the message to log 722 */ 723 public void error(final Throwable exception, final String message) 724 { 725 if (this.log) 726 LogEntryForwarder.forward(1, Level.ERROR, exception, message); 727 } 728 729 /** 730 * Create a error log entry that will always be output, independent of LogCategory settings. 731 * @param exception Throwable; the exception to log 732 * @param message String; the message to log, where {} entries will be replaced by arguments 733 * @param arguments Object...; the arguments to substitute for the {} entries in the message string 734 */ 735 public void error(final Throwable exception, final String message, final Object... arguments) 736 { 737 if (this.log) 738 LogEntryForwarder.forward(1, Level.ERROR, exception, message, arguments); 739 } 740 } 741 }