1 /* 2 * Copyright (c) 2004-2005 SLF4J.ORG 3 * Copyright (c) 2004-2005 QOS.ch 4 * 5 * All rights reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining 8 * a copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, and/or sell copies of the Software, and to permit persons 12 * to whom the Software is furnished to do so, provided that the above 13 * copyright notice(s) and this permission notice appear in all copies of 14 * the Software and that both the above copyright notice(s) and this 15 * permission notice appear in supporting documentation. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 20 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY 22 * SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER 23 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 24 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 25 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 26 * 27 * Except as contained in this notice, the name of a copyright holder 28 * shall not be used in advertising or otherwise to promote the sale, use 29 * or other dealings in this Software without prior written authorization 30 * of the copyright holder. 31 * 32 */ 33 34 package org.slf4j.impl; 35 36 import org.slf4j.helpers.FormattingTuple; 37 import org.slf4j.helpers.MarkerIgnoringBase; 38 import org.slf4j.helpers.MessageFormatter; 39 40 /** 41 * A simple (and direct) implementation that logs messages of level INFO or 42 * higher on the console (<code>System.err<code>). 43 * 44 * <p>The output includes the relative time in milliseconds, thread 45 * name, the level, logger name, and the message followed by the line 46 * separator for the host. In log4j terms it amounts to the "%r [%t] 47 * %level %logger - %m%n" pattern. </p> 48 * 49 * <p>Sample output follows.</p> 50 <pre> 51 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order. 52 225 [main] INFO examples.SortAlgo - Entered the sort method. 53 304 [main] INFO examples.SortAlgo - Dump of integer array: 54 317 [main] INFO examples.SortAlgo - Element [0] = 0 55 331 [main] INFO examples.SortAlgo - Element [1] = 1 56 343 [main] INFO examples.Sort - The next log statement should be an error message. 57 346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array. 58 at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58) 59 at org.log4j.examples.Sort.main(Sort.java:64) 60 467 [main] INFO examples.Sort - Exiting main method. 61 </pre> 62 * 63 * @author Ceki Gülcü 64 */ 65 public class SimpleLogger extends MarkerIgnoringBase { 66 67 private static final long serialVersionUID = -6560244151660620173L; 68 69 /** 70 * Mark the time when this class gets loaded into memory. 71 */ 72 private static long startTime = System.currentTimeMillis(); 73 public static final String LINE_SEPARATOR = System 74 .getProperty("line.separator"); 75 private static String INFO_STR = "INFO"; 76 private static String WARN_STR = "WARN"; 77 private static String ERROR_STR = "ERROR"; 78 79 /** 80 * Package access allows only {@link SimpleLoggerFactory} to instantiate 81 * SimpleLogger instances. 82 */ 83 SimpleLogger(String name) { 84 this.name = name; 85 } 86 87 /** 88 * Always returns false. 89 * 90 * @return always false 91 */ 92 public boolean isTraceEnabled() { 93 return false; 94 } 95 96 /** 97 * A NOP implementation, as this logger is permanently disabled for the TRACE 98 * level. 99 */ 100 public void trace(String msg) { 101 // NOP 102 } 103 104 /** 105 * A NOP implementation, as this logger is permanently disabled for the TRACE 106 * level. 107 */ 108 public void trace(String format, Object param1) { 109 // NOP 110 } 111 112 /** 113 * A NOP implementation, as this logger is permanently disabled for the TRACE 114 * level. 115 */ 116 public void trace(String format, Object param1, Object param2) { 117 // NOP 118 } 119 120 public void trace(String format, Object[] argArray) { 121 // NOP 122 } 123 124 /** 125 * A NOP implementation, as this logger is permanently disabled for the TRACE 126 * level. 127 */ 128 public void trace(String msg, Throwable t) { 129 // NOP 130 } 131 132 /** 133 * Always returns false. 134 * 135 * @return always false 136 */ 137 public boolean isDebugEnabled() { 138 return false; 139 } 140 141 /** 142 * A NOP implementation, as this logger is permanently disabled for the DEBUG 143 * level. 144 */ 145 public void debug(String msg) { 146 // NOP 147 } 148 149 /** 150 * A NOP implementation, as this logger is permanently disabled for the DEBUG 151 * level. 152 */ 153 public void debug(String format, Object param1) { 154 // NOP 155 } 156 157 /** 158 * A NOP implementation, as this logger is permanently disabled for the DEBUG 159 * level. 160 */ 161 public void debug(String format, Object param1, Object param2) { 162 // NOP 163 } 164 165 public void debug(String format, Object[] argArray) { 166 // NOP 167 } 168 169 /** 170 * A NOP implementation, as this logger is permanently disabled for the DEBUG 171 * level. 172 */ 173 public void debug(String msg, Throwable t) { 174 // NOP 175 } 176 177 /** 178 * This is our internal implementation for logging regular (non-parameterized) 179 * log messages. 180 * 181 * @param level 182 * @param message 183 * @param t 184 */ 185 private void log(String level, String message, Throwable t) { 186 StringBuffer buf = new StringBuffer(); 187 188 long millis = System.currentTimeMillis(); 189 buf.append(millis - startTime); 190 191 buf.append(" ["); 192 buf.append(Thread.currentThread().getName()); 193 buf.append("] "); 194 195 buf.append(level); 196 buf.append(" "); 197 198 buf.append(name); 199 buf.append(" - "); 200 201 buf.append(message); 202 203 buf.append(LINE_SEPARATOR); 204 205 System.err.print(buf.toString()); 206 if (t != null) { 207 t.printStackTrace(System.err); 208 } 209 System.err.flush(); 210 } 211 212 /** 213 * For formatted messages, first substitute arguments and then log. 214 * 215 * @param level 216 * @param format 217 * @param param1 218 * @param param2 219 */ 220 private void formatAndLog(String level, String format, Object arg1, 221 Object arg2) { 222 FormattingTuple tp = MessageFormatter.format(format, arg1, arg2); 223 log(level, tp.getMessage(), tp.getThrowable()); 224 } 225 226 /** 227 * For formatted messages, first substitute arguments and then log. 228 * 229 * @param level 230 * @param format 231 * @param argArray 232 */ 233 private void formatAndLog(String level, String format, Object[] argArray) { 234 FormattingTuple tp = MessageFormatter.arrayFormat(format, argArray); 235 log(level, tp.getMessage(), tp.getThrowable()); 236 } 237 238 /** 239 * Always returns true. 240 */ 241 public boolean isInfoEnabled() { 242 return true; 243 } 244 245 /** 246 * A simple implementation which always logs messages of level INFO according 247 * to the format outlined above. 248 */ 249 public void info(String msg) { 250 log(INFO_STR, msg, null); 251 } 252 253 /** 254 * Perform single parameter substitution before logging the message of level 255 * INFO according to the format outlined above. 256 */ 257 public void info(String format, Object arg) { 258 formatAndLog(INFO_STR, format, arg, null); 259 } 260 261 /** 262 * Perform double parameter substitution before logging the message of level 263 * INFO according to the format outlined above. 264 */ 265 public void info(String format, Object arg1, Object arg2) { 266 formatAndLog(INFO_STR, format, arg1, arg2); 267 } 268 269 /** 270 * Perform double parameter substitution before logging the message of level 271 * INFO according to the format outlined above. 272 */ 273 public void info(String format, Object[] argArray) { 274 formatAndLog(INFO_STR, format, argArray); 275 } 276 277 /** 278 * Log a message of level INFO, including an exception. 279 */ 280 public void info(String msg, Throwable t) { 281 log(INFO_STR, msg, t); 282 } 283 284 /** 285 * Always returns true. 286 */ 287 public boolean isWarnEnabled() { 288 return true; 289 } 290 291 /** 292 * A simple implementation which always logs messages of level WARN according 293 * to the format outlined above. 294 */ 295 public void warn(String msg) { 296 log(WARN_STR, msg, null); 297 } 298 299 /** 300 * Perform single parameter substitution before logging the message of level 301 * WARN according to the format outlined above. 302 */ 303 public void warn(String format, Object arg) { 304 formatAndLog(WARN_STR, format, arg, null); 305 } 306 307 /** 308 * Perform double parameter substitution before logging the message of level 309 * WARN according to the format outlined above. 310 */ 311 public void warn(String format, Object arg1, Object arg2) { 312 formatAndLog(WARN_STR, format, arg1, arg2); 313 } 314 315 /** 316 * Perform double parameter substitution before logging the message of level 317 * WARN according to the format outlined above. 318 */ 319 public void warn(String format, Object[] argArray) { 320 formatAndLog(WARN_STR, format, argArray); 321 } 322 323 /** 324 * Log a message of level WARN, including an exception. 325 */ 326 public void warn(String msg, Throwable t) { 327 log(WARN_STR, msg, t); 328 } 329 330 /** 331 * Always returns true. 332 */ 333 public boolean isErrorEnabled() { 334 return true; 335 } 336 337 /** 338 * A simple implementation which always logs messages of level ERROR according 339 * to the format outlined above. 340 */ 341 public void error(String msg) { 342 log(ERROR_STR, msg, null); 343 } 344 345 /** 346 * Perform single parameter substitution before logging the message of level 347 * ERROR according to the format outlined above. 348 */ 349 public void error(String format, Object arg) { 350 formatAndLog(ERROR_STR, format, arg, null); 351 } 352 353 /** 354 * Perform double parameter substitution before logging the message of level 355 * ERROR according to the format outlined above. 356 */ 357 public void error(String format, Object arg1, Object arg2) { 358 formatAndLog(ERROR_STR, format, arg1, arg2); 359 } 360 361 /** 362 * Perform double parameter substitution before logging the message of level 363 * ERROR according to the format outlined above. 364 */ 365 public void error(String format, Object[] argArray) { 366 formatAndLog(ERROR_STR, format, argArray); 367 } 368 369 /** 370 * Log a message of level ERROR, including an exception. 371 */ 372 public void error(String msg, Throwable t) { 373 log(ERROR_STR, msg, t); 374 } 375 }