001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002// The Molly framework is freely distributable under the terms of an 003// MIT-style license. For details, see the molly pages web site at: 004// http://www.mollypages.org/. Use, modify, have fun ! 005 006package fc.io; 007 008import java.text.*; 009import java.util.*; 010import java.lang.reflect.*; 011 012import fc.util.*; 013 014/** 015A system wide logging facility. Clearer and more elegant 016semantics/nomenclature than <code>java.util.logging</code>. 017<p> 018Logs messages to some user specified destination(s). Each log has a 019<b>name</b> and a <b>log level</b>. 020<p> 021The names are arbitrary (hopefully descriptive) names, per your liking. Many 022different logs can be created and then later retrieved by their 023name as needed. 024<p> 025The levels provided by this class have the order: 026 <blockquote> 027 <code> 028 OFF <b><</b> ERROR <b>< </b>WARN <b><</b> INFO <b><</b> DEBUG 029 </code> 030 </blockquote> 031The above levels are self-explanatory. 032<p> 033Convenience methods with names equal to a <b>level</b> name are provided. 034So for example, instead of saying: 035 <blockquote> 036 <code>log(<b>LogLevel.warn</b>, "the message");</code> 037 </blockquote> 038one can say: 039 <blockquote> 040 <code>log.<b>warn</b>("the message");</code> 041 </blockquote> 042<div style="border: 1px solid #ccc; padding: 1em;"> 043A little historical quirk. For the debug level <code>LogLevel.debug</code>, 044one can say: 045 <blockquote> 046 <pre> 047 <code>log.<b>debug</b>("the message");</code> 048 --<b>or</b>-- 049 <code>log.<b>bug</b>("the message");</code> 050 </pre> 051 </blockquote> 052</div> 053<p> 054A default logger of type {@link fc.io.SystemLog} is provided for 055convenience in this class and can be retrieved by calling the {@link 056#getDefault()} method. 057<p> 058The {@link #closeLog(String)} method is called on all logs 059at JVM shutdown. 060<p> 061<b>Note:</b>To log a full stack traces, pass the string obtained by the 062{@link IOUtil#throwableToString} method. (by default, an exception simply 063prints its message but not the full stack trace) 064<p> 065<b>Implementation Note</b>: subclasses should implement static 066<code>getLog(..)</code> type methods. These that create, as needed, and 067return a new log object of that subclass type. These getter methods 068should be static for convenience. Also, the implementation of the 069<code>subclass.getLog(...)</code> methods in subclasses is expected by 070convention. 071<p> 072Thread Safety: This class <code>is</code> Threadsafe and all its methods can 073be used concurrently. 074 075@author hursh jain 076**/ 077public abstract class Log 078{ 079//--static variables-- 080public static final LogLevel OFF = new LogLevel("OFF", 0); 081public static final LogLevel ERROR = new LogLevel("ERROR", 1); 082public static final LogLevel WARN = new LogLevel("WARN", 2); 083public static final LogLevel INFO = new LogLevel("INFO", 3); 084public static final LogLevel DEBUG = new LogLevel("DEBUG", 4); 085 086/** 087The default level used for new logs. Subclasses should (by default) 088create logs using this level. 089*/ 090public static LogLevel DEFAULT_LEVEL = INFO; 091 092protected static final byte[] linesepbytes = 093 System.getProperty("line.separator").getBytes(); 094 095 //synchronized map needed 096protected static SystemLog defaultlog; 097protected static final Map logs = new Hashtable(); 098 099//--instance variables apply to a particular logger 100protected String name; 101protected LogLevel currentLevel; 102protected long startTime; 103protected String startTimeString; //for toString() 104protected boolean printLevelName = true; 105protected boolean printTimestamp = false; 106protected boolean timestampIsRelative = false; 107protected LogLevel printMethodInfoAtLevel = DEBUG; 108 109//default timestamp data 110protected final SimpleDateFormat df 111 = new SimpleDateFormat("MMM dd H:m:s z"); 112protected final NumberFormat nf 113 = NumberFormat.getNumberInstance(); 114 115protected Date date = new Date(); 116protected long last_time = date.getTime(); 117protected String timestr = df.format(date); 118 119//Add shutdown hook to close all open logs 120static 121 { 122 Runtime.getRuntime().addShutdownHook(new Thread("fc.io.Log.Shutdown") { 123 public void run() 124 { 125 System.out.println("JVM shutdown: fc.io.Log - closing all logs..."); 126 Iterator i = logs.values().iterator(); 127 while (i.hasNext()) 128 ((Log)i.next()).close(); 129 System.out.println(); 130 } 131 }); 132 } 133 134 135/** 136Constructs a new Log. Can only be called from subclasses. 137 138@param name the name for the log -- any arbitrary 139 string denoting a conceptual category, 140 destination, whatever 141@param level the initial logging level for this log 142*/ 143protected Log(String name, LogLevel level) 144 { 145 assert name != null : "name was null"; 146 assert level != null : "level was null" ; 147 this.name = name; 148 this.currentLevel = level; 149 this.startTime = System.currentTimeMillis(); 150 this.startTimeString = new Date(startTime).toString(); 151 } 152 153 154/** 155Returns a {@link SystemLog} with the specified name. If the log does not already 156exist, creates and returns a new SystemLog with that name. 157<p> 158The system log created will have a default destination of <code>System.err</code> 159and a default level of {@link Log#INFO}. 160<p> 161To obtain logs with a different destination, create a SystemLog directly. 162*/ 163public static Log get(String name) 164 { 165 Log log = (Log) logs.get(name); 166 if (log != null) 167 return log; 168 169 synchronized(logs) { 170 log = new SystemLog(name); 171 logs.put(name, log); 172 } 173 174 return log; 175 } 176 177 178/** 179An alias for method {@link #get(String)}. 180<p> 181Returns a {@link SystemLog} with the specified name. If the log does not already 182exist, creates and returns a new SystemLog with that name. 183<p> 184The system log created will have a default destination of <code>System.err</code> 185and a default level of {@link Log#INFO}. 186<p> 187To obtain logs with a different destination, create a SystemLog directly. 188*/ 189public static Log getLog(String name) 190 { 191 return get(name); 192 } 193 194 195/** 196Convenience method that returns the log named after the <b>package</b> that 197the specified class belong to. If 2 classes <pre>a.b.Class1</pre> and 198<pre>a.b.Class2</pre> call this method, they will get the same logger 199(named <code>a.b</code>). 200<p> 201If the log does not already exist, creates and returns a new {@link SystemLog} 202with that name. 203 204@param c a non-null class 205*/ 206public final static Log get(Class c) 207 { 208 Argcheck.notnull(c, "class parameter was null"); 209 final Package p = c.getPackage(); 210 final String name = (p == null) ? "default_pkg" : p.toString(); 211 return get(name); 212 } 213 214/** 215Convenience method that returns a log named after the <b>package</b> that 216the specified object's class belong to. If 2 objects of class 217<pre>a.b.Class1</pre> and <pre>a.b.Class2</pre> call this method, they 218will get the same logger (named <code>a.b</code>). 219<p> 220If the log does not already exist, creates and returns a new {@link SystemLog} 221with that name. 222 223@param obj a non-null object 224*/ 225public final static Log get(Object obj) 226 { 227 Argcheck.notnull(obj, "class parameter was null"); 228 return get(obj.getClass().getPackage().toString()); 229 } 230 231/** 232Returns the default system log. This system log writes to 233<code>System.err</code> and has it's level set to {@link SystemLog#INFO}. This 234level can be changed to some other level if desired by invoking {@link 235#setLevel(LogLevel)} on the returned object. 236*/ 237public static SystemLog getDefault() 238 { 239 synchronized (Log.class) 240 { 241 if (defaultlog == null) { 242 defaultlog = new SystemLog( 243 "_defaultlog", System.out, SystemLog.INFO); 244 } 245 } 246 return defaultlog; 247 } 248 249 250/** 251Returns an iteration containing level names for this log. The names can be in 252any order. 253*/ 254public Iterator getLevelNames() 255 { 256 Class myclass = getClass(); 257 Field[] fields = myclass.getDeclaredFields(); 258 Field levelfield = null; 259 List l = new ArrayList(); 260 for (int n = 0; n < fields.length; n++) 261 { 262 Field f = fields[n]; 263 if (! f.getType().isAssignableFrom(LogLevel.class)) 264 continue; 265 l.add(f.getName()); 266 } 267 return l.iterator(); 268 } 269 270/* 271Manually adds the specified log to the list of all logs. If a log with 272that name already exists, an <tt>IllegalArgumentException</tt> is thrown. 273<p> This method is useful when creating a new logging object manaually. 274So for example: 275 <blockquote> 276 <pre> 277 MyLogClass mylog = new MyLogClass("foo.bar"); 278 Log.addLog(mylog) 279 </pre> 280 </blockquote> 281Contrast that with the more usual: 282 <blockquote> 283 <pre> 284 Log.getLog("foo.bar"); 285 </pre> 286 </blockquote> 287<p> 288<u>Custom log implementations should always call this method in their 289constructor to add themselves to the list of all logs.</u> 290*/ 291protected static void addLog(Log log) 292 { 293 synchronized(logs) 294 { 295 if (! logs.containsKey(log.name)) { 296 logs.put(log.name, log); 297 } 298 else throw new IllegalArgumentException("Log already exists: " + log); 299 } 300 } 301 302/** 303Closes and removes the log with the specified name if it exists 304*/ 305public static void closeLog(String name) 306 { 307 if (logs.containsKey(name)) { 308 Log l = (Log) logs.get(name); 309 l.close(); 310 logs.remove(name); 311 } 312 } 313 314/** 315Returns the method name, file number and line number 316of the calling method. Useful for logging/code tracing. 317 318@param level the level for which this logging call was invoked. 319@param framenum the method to examine. This method itself 320 has frame number 0, the calling method 321 has frame number 1, it's parent 2 and so on. 322**/ 323public final String getDebugContext(LogLevel level, int framenum) 324 { 325 if (level.intval < printMethodInfoAtLevel.intval) { 326 return ""; 327 } 328 329 StackTraceElement ste[] = new Exception().getStackTrace(); 330 if (framenum >= ste.length) 331 throw new IllegalArgumentException( 332 "framenum [" + framenum 333 + "] too large. Max number of record in stack = " 334 + (ste.length - 1)); 335 336 //get method that called us, we are ste[0] 337 StackTraceElement st = ste[framenum]; 338 String file = st.getFileName(); 339 int line = st.getLineNumber(); 340 String method = st.getMethodName(); 341 String threadname = Thread.currentThread().getName(); 342 //String classn = st.getClassName(); 343 return method + "() [" + file + ":" + line + "/thread:" + threadname + "]"; 344 } 345 346 347/** 348If set to true, will print the level name before the logging 349message. For example, if the level is <code>INFO</code>, the 350message is <code>foo</code>, then 351 <blockquote> 352 INFO foo 353 </blockquote> 354will be printed. 355<p> 356This is set to <code>true</code> by default. 357*/ 358public void printLevelName(boolean printName) 359 { 360 printLevelName = printName; 361 } 362 363/** 364Prints a time stamp with every message. By default this 365is <code>false</code> 366 367@param val specify true to print time stamps, false 368 to not 369*/ 370public void printTimestamp(boolean val) { 371 printTimestamp = val; 372 } 373 374/** 375Prints a relative time stamp with every message. By 376default, printing any timestamp is <code>false</code>. 377<b> 378Timestamps must first be enabled via the {@link printTimestamp} 379method before this method can have any effect. 380</b> 381 382@param val if true, prints a <b>relative</b> time 383 stamp. An initial timestamp is printed and 384 all succeeding timestamps are second 385 increments from the initial timestamp 386*/ 387public void printRelativeTimestamp(boolean val) { 388 timestampIsRelative = val; 389 last_time = new Date().getTime(); 390 } 391 392/** 393By default, method, line and thread information is printed wich each 394logging statement at the DEBUG level. Other levels print only the log 395message but skip the method/stack information. 396<p> 397This method allows method information to be printed at all levels greater 398than or equal to the specified level. 399*/ 400public void printMethodInfoAtLevel(LogLevel level) { 401 this.printMethodInfoAtLevel = level; 402 } 403 404/** 405A default implementation that returns an appropriate timestamp based on the 406timestamp setttings. <b> Multiple threads must synchronize access to this 407method </b>. Subclasses should call this method in their logging method 408implementations in the following way. 409<blockquote> 410Suppose the subclass uses an out object as a printwriter. Then 411<br> 412<code> 413<b>...in a synchronized block, typically around the output stream....</b> 414if (printTimestamp) { 415 out.print(getTS()); 416 out.print(" "); 417 } 418..... 419</code> 420</blockquote> 421Of course subclasses are free to not call this method or 422print timestamps in some other fashion. 423*/ 424protected final String getTS() 425 { 426 date = new Date(); 427 long now = date.getTime(); 428 429 if (timestampIsRelative) 430 { 431 return nf.format( ((now - last_time) / 1000) ) ; 432 } 433 else //non relative ts 434 { 435 if (now - last_time >= 1000) { 436 last_time = now; 437 timestr = df.format(date); 438 } 439 } 440 441 return timestr; 442 } 443 444/** 445Sets the current logging level for this logger. Each log has a logging 446level. A message is printed only if the message level is equal to or lower 447than the current maximum level for that log. 448<p> 449Typically, classes that implement a log will define a bunch of static 450variables of type {@link LogLevel} that list the available levels for that 451implementation. Clients of a particular log class should use levels 452defined within only that class. 453*/ 454public void setLevel(LogLevel level) { 455 assert level != null : "specified level was null"; 456 currentLevel = level; 457 } 458 459/** 460Sets the level of this log based on a level description. This is 461convenient for when levels are specified in a configuration file. If the 462specified name cannot be converted into a level, then no change is made. 463 464@param levelname the level name. For example, 465 <code>"info"</code> would set the level of 466 this log to <code>INFO</code>. The name 467 is case-<b>in</b>sensitive. 468*/ 469public void setLevel(String levelname) 470 { 471 if (levelname == null) { 472 warn("specified levelname was null, log level will not be changed"); 473 return; 474 } 475 476 try { 477 Field levelfield = stringToLevel(levelname); 478 if (levelfield == null) { 479 warn("Specified level", levelname, "is not valid/could not be resolved"); 480 return; 481 } 482 483 Method method = Log.class.getMethod("setLevel", new Class[] { LogLevel.class }); 484 //System.out.println("got method="+method); 485 method.invoke(this, new Object[] { levelfield.get(this) }); 486 info("New log level for log=[", name ,"] set to: ", currentLevel); 487 } 488 catch (Exception e) { 489 warn(e); 490 } 491 } 492 493/* 494Returns a level field corresponding to the specified case-insensitive 495string. 496 497this is kinda overkill but hey: It takes about 5ms so speed 498isn't an issue and if we ever add more levels, we won't have to 499update this method. 500*/ 501protected static Field stringToLevel(String levelname) 502 { 503 Field[] fields = Log.class.getDeclaredFields(); 504 Field levelfield = null; 505 for (int n = 0; n < fields.length; n++) 506 { 507 Field f = fields[n]; 508 if (! f.getType().isAssignableFrom(LogLevel.class)) 509 continue; 510 if (f.getName().equalsIgnoreCase(levelname)) 511 levelfield = f; 512 } 513 return levelfield; 514 } 515 516/** 517Sets the level for all logs whose name <b>contain</b> the specified name. 518This is convenient when changing log levels for package heirarchies. A 519empty string (non-null) "" sets the level for all logs. 520 521@param name the level name. For example, 522 <code>"info"</code> would set the level of 523 this log to <code>INFO</code>. The name 524 is case-<b>in</b>sensitive. 525*/ 526public static void setLevelForAll(String name, LogLevel level) 527 { 528 Iterator i = logs.keySet().iterator(); 529 while (i.hasNext()) { 530 String logname = (String) i.next(); 531 if (logname.contains(logname)) { 532 ((Log)logs.get(logname)).setLevel(level); 533 } 534 } 535 } 536 537/** 538Sets the new default logging level for all new instances of loggers 539(that are created after this method is invoked). 540*/ 541public static void setDefaultLevel(LogLevel level) 542 { 543 DEFAULT_LEVEL = level; 544 } 545 546/** 547Sets the new default logging level for all new instances of loggers 548(created after this method is invoked). 549*/ 550public static void setDefaultLevel(String level) 551 { 552 if (level == null) { 553 new Exception("the specified level was null, log level will not be changed").printStackTrace(); 554 return; 555 } 556 557 try { 558 Field levelfield = stringToLevel(level); 559 if (levelfield == null) 560 return; 561 562 Method method = Log.class.getMethod("setDefaultLevel", new Class[] { LogLevel.class }); 563 //System.out.println("got method="+method); 564 method.invoke(null, new Object[] { levelfield.get(null) }); 565 } 566 catch (Exception e) { 567 e.printStackTrace(); 568 } 569 } 570 571/** 572Returns <code>true</code> if the log's current level will allow logging 573messages at the specified logging level. 574<p> 575Implementation Note: If the currentLevel is lesser or equal to the 576specified level returns true, else false. Subclasses can override this 577method if needed. 578 579@param level the specified logging level 580*/ 581public boolean canLog(LogLevel level) 582 { 583 assert level != null : "specified level was null"; 584 if (level.intval > currentLevel.intval) 585 return false; 586 return true; 587 } 588 589/** 590Returns the name of this log. 591*/ 592public String getName() { 593 return name; 594 } 595 596/** 597Returns the current level set for this log. Useful when 598printing out debugging info. 599*/ 600public LogLevel getLevel() { 601 return currentLevel; 602 } 603 604public void logSystemInfo() 605 { 606 StringBuffer buf = new StringBuffer(1024); 607 Properties p = System.getProperties(); 608 Enumeration e = p.propertyNames(); 609 while (e.hasMoreElements()) { 610 buf.append(IOUtil.LINE_SEP); 611 String name = (String) e.nextElement(); 612 613 buf.append(name).append("="); 614 615 if (name.equals("line.separator")) { 616 buf.append(StringUtil.viewableAscii(p.getProperty(name))); 617 } 618 else{ 619 buf.append(p.getProperty(name)); 620 } 621 } 622 buf.append(IOUtil.LINE_SEP); 623 info(buf.toString()); 624 } 625 626public String toString() 627 { 628 return name + " [" + getClass().getName() + 629 "/currentlevel:" + currentLevel.desc + 630 "/started:" + startTimeString + "]"; 631 } 632 633//--methods for various levels 634public final void error(final Object str1) { 635 doLog(ERROR, str1); 636 } 637 638public final void error(final Object str1, final Object str2) { 639 doLog(ERROR, str1, str2); 640 } 641 642public final void error(final Object str1, final Object str2, final Object str3) { 643 doLog(ERROR, str1, str2, str3); 644 } 645 646public final void error(final Object str1, final Object str2, final Object str3, final Object str4) { 647 doLog(ERROR, str1, str2, str3, str4); 648 } 649 650public final void error(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5) { 651 doLog(ERROR, str1, str2, str3, str4, str5); 652 } 653 654public final void error(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6) { 655 doLog(ERROR, str1, str2, str3, str4, str5, str6); 656 } 657 658public final void error(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7) { 659 doLog(ERROR, str1, str2, str3, str4, str5, str6, str7); 660 } 661 662public final void error(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object... args) { 663 doLog(ERROR, str1, str2, str3, str4, str5, str6, str7, args); 664 } 665 666public final void warn(final Object str1) { 667 doLog(WARN, str1); 668 } 669 670public final void warn(final Object str1, final Object str2) { 671 doLog(WARN, str1, str2); 672 } 673 674public final void warn(final Object str1, final Object str2, final Object str3) { 675 doLog(WARN, str1, str2, str3); 676 } 677 678public final void warn(final Object str1, final Object str2, final Object str3, final Object str4) { 679 doLog(WARN, str1, str2, str3, str4); 680 } 681 682public final void warn(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5) { 683 doLog(WARN, str1, str2, str3, str4, str5); 684 } 685 686public final void warn(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6) { 687 doLog(WARN, str1, str2, str3, str4, str5, str6); 688 } 689 690public final void warn(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7) { 691 doLog(WARN, str1, str2, str3, str4, str5, str6, str7); 692 } 693 694public final void warn(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object... args) { 695 doLog(WARN, str1, str2, str3, str4, str5, str6, str7, args); 696 } 697 698public final void info(final Object str1) { 699 doLog(INFO, str1); 700 } 701 702public final void info(final Object str1, final Object str2) { 703 doLog(INFO, str1, str2); 704 } 705 706public final void info(final Object str1, final Object str2, final Object str3) { 707 doLog(INFO, str1, str2, str3); 708 } 709 710public final void info(final Object str1, final Object str2, final Object str3, final Object str4) { 711 doLog(INFO, str1, str2, str3, str4); 712 } 713 714public final void info(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5) { 715 doLog(INFO, str1, str2, str3, str4, str5); 716 } 717 718public final void info(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6) { 719 doLog(INFO, str1, str2, str3, str4, str5, str6); 720 } 721 722public final void info(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7) { 723 doLog(INFO, str1, str2, str3, str4, str5, str6, str7); 724 } 725 726public final void info(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object... args) { 727 doLog(INFO, str1, str2, str3, str4, str5, str6, str7, args); 728 } 729 730public final void debug(final Object str1) { 731 doLog(DEBUG, str1); 732 } 733 734public final void debug(final Object str1, final Object str2) { 735 doLog(DEBUG, str1, str2); 736 } 737 738public final void debug(final Object str1, final Object str2, final Object str3) { 739 doLog(DEBUG, str1, str2, str3); 740 } 741 742public final void debug(final Object str1, final Object str2, final Object str3, final Object str4) { 743 doLog(DEBUG, str1, str2, str3, str4); 744 } 745 746public final void debug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5) { 747 doLog(DEBUG, str1, str2, str3, str4, str5); 748 } 749 750public final void debug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6) { 751 doLog(DEBUG, str1, str2, str3, str4, str5, str6); 752 } 753 754public final void debug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7) { 755 doLog(DEBUG, str1, str2, str3, str4, str5, str6, str7); 756 } 757 758public final void debug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object... args) { 759 doLog(DEBUG, str1, str2, str3, str4, str5, str6, str7, args); 760 } 761 762public final void bug(final Object str1) { 763 doLog(DEBUG, str1); 764 } 765 766public final void bug(final Object str1, final Object str2) { 767 doLog(DEBUG, str1, str2); 768 } 769 770public final void bug(final Object str1, final Object str2, final Object str3) { 771 doLog(DEBUG, str1, str2, str3); 772 } 773 774public final void bug(final Object str1, final Object str2, final Object str3, final Object str4) { 775 doLog(DEBUG, str1, str2, str3, str4); 776 } 777 778public final void bug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5) { 779 doLog(DEBUG, str1, str2, str3, str4, str5); 780 } 781 782public final void bug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6) { 783 doLog(DEBUG, str1, str2, str3, str4, str5, str6); 784 } 785 786public final void bug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7) { 787 doLog(DEBUG, str1, str2, str3, str4, str5, str6, str7); 788 } 789 790public final void bug(final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object... args) { 791 doLog(DEBUG, str1, str2, str3, str4, str5, str6, str7, args); 792 } 793 794final void doLog(final LogLevel level, final Object str1) 795 { 796 if (level.intval > currentLevel.intval) 797 return; 798 799 log(level, getDebugContext(level, 3), str1); 800 } 801 802final void doLog(final LogLevel level, final Object str1, final Object str2) 803 { 804 if (level.intval > currentLevel.intval) 805 return; 806 807 log(level, getDebugContext(level, 3), str1, str2); 808 } 809 810final void doLog(final LogLevel level, final Object str1, 811 final Object str2, final Object str3) 812 { 813 if (level.intval > currentLevel.intval) 814 return; 815 816 log(level, getDebugContext(level, 3), str1, str2, str3); 817 } 818 819final void doLog(final LogLevel level, final Object str1, final Object str2, 820 final Object str3, final Object str4) 821 { 822 if (level.intval > currentLevel.intval) 823 return; 824 825 log(level, getDebugContext(level, 3), str1, str2, str3, str4); 826 } 827 828final void doLog(final LogLevel level, final Object str1, final Object str2, 829 final Object str3, final Object str4, final Object str5) 830 { 831 if (level.intval > currentLevel.intval) 832 return; 833 834 log(level, getDebugContext(level, 3), str1, str2, str3, str4, str5); 835 } 836 837final void doLog(final LogLevel level, final Object str1, final Object str2, 838 final Object str3, final Object str4, final Object str5, 839 final Object str6) 840 { 841 if (level.intval > currentLevel.intval) 842 return; 843 844 log(level, getDebugContext(level, 3), str1, str2, str3, str4, str5, str6); 845 } 846 847final void doLog(final LogLevel level, final Object str1, final Object str2, 848 final Object str3, final Object str4, final Object str5, 849 final Object str6, final Object str7) 850 { 851 if (level.intval > currentLevel.intval) 852 return; 853 854 log(level, getDebugContext(level, 3), str1, str2, str3, str4, str5, str6, str7); 855 } 856 857final void doLog(final LogLevel level, final Object str1, final Object str2, 858 final Object str3, final Object str4, final Object str5, 859 final Object str6, final Object str7, Object... args) 860 { 861 if (level.intval > currentLevel.intval) 862 return; 863 864 log(level, getDebugContext(level, 3), str1, str2, str3, str4, str5, str6, str7, args); 865 } 866 867 868//--abstract methods-- 869 870public abstract void close(); 871 872 873/** 874@param level the current log level. This can be logged 875 as well. 876@param str1 unless overridden in a subclass, this is the 877 value returned by {@link getDebugContext} and 878 is generated automatically by the warn(), 879 info(), debug() etc., methods 880*/ 881public abstract void log(LogLevel level, Object str1); 882 883/** 884@param level the current log level. This can be logged 885 as well. 886@param str1 unless overridden in a subclass, this is the 887 value returned by {@link getDebugContext} and 888 is generated automatically by the warn(), 889 info(), debug() etc., methods 890@param str2 891 some arbitrary object 892*/ 893public abstract void log(LogLevel level, final Object str1, final Object str2); 894 895/** 896@param level the current log level. This can be logged 897 as well. 898@param str1 unless overridden in a subclass, this is the 899 value returned by {@link getDebugContext} and 900 is generated automatically by the warn(), 901 info(), debug() etc., methods 902@param str2 903 some arbitrary object 904*/ 905public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3); 906 907/** 908@param level the current log level. This can be logged 909 as well. 910@param str1 unless overridden in a subclass, this is the 911 value returned by {@link getDebugContext} and 912 is generated automatically by the warn(), 913 info(), debug() etc., methods 914@param str2 915 some arbitrary object 916*/ 917public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3, final Object str4); 918 919/** 920@param level the current log level. This can be logged 921 as well. 922@param str1 unless overridden in a subclass, this is the 923 value returned by {@link getDebugContext} and 924 is generated automatically by the warn(), 925 info(), debug() etc., methods 926@param str2 927 some arbitrary object 928*/ 929public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3, final Object str4, final Object str5); 930 931/** 932@param level the current log level. This can be logged 933 as well. 934@param str1 unless overridden in a subclass, this is the 935 value returned by {@link getDebugContext} and 936 is generated automatically by the warn(), 937 info(), debug() etc., methods 938@param str2 939 some arbitrary object 940*/ 941public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6); 942 943/** 944@param level the current log level. This can be logged 945 as well. 946@param str1 unless overridden in a subclass, this is the 947 value returned by {@link getDebugContext} and 948 is generated automatically by the warn(), 949 info(), debug() etc., methods 950@param str2 951 some arbitrary object 952*/ 953public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7); 954 955/** 956@param level the current log level. This can be logged 957 as well. 958@param str1 unless overridden in a subclass, this is the 959 value returned by {@link getDebugContext} and 960 is generated automatically by the warn(), 961 info(), debug() etc., methods 962@param str2 963 some arbitrary object 964*/ 965public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object str8); 966 967/** 968@param level the current log level. This can be logged 969 as well. 970@param str1 unless overridden in a subclass, this is the 971 value returned by {@link getDebugContext} and 972 is generated automatically by the warn(), 973 info(), debug() etc., methods 974@param str2 975 some arbitrary object 976*/ 977public abstract void log(LogLevel level, final Object str1, final Object str2, final Object str3, final Object str4, final Object str5, final Object str6, final Object str7, Object str8, Object... args); 978} //~class Log 979 980