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.MarkerIgnoringBase; 37 import org.slf4j.helpers.MessageFormatter; 38 39 /** 40 * A simple (and direct) implementation that logs messages of level 41 * INFO or higher on the console (<code>System.err<code>). 42 * 43 * <p>The output includes the relative time in milliseconds, thread 44 * name, the level, logger name, and the message followed by the line 45 * separator for the host. In log4j terms it amounts to the "%r [%t] 46 * %level %logger - %m%n" pattern. </p> 47 * 48 * <p>Sample output follows.</p> 49 <pre> 50 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order. 51 225 [main] INFO examples.SortAlgo - Entered the sort method. 52 304 [main] INFO examples.SortAlgo - Dump of integer array: 53 317 [main] INFO examples.SortAlgo - Element [0] = 0 54 331 [main] INFO examples.SortAlgo - Element [1] = 1 55 343 [main] INFO examples.Sort - The next log statement should be an error message. 56 346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array. 57 at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58) 58 at org.log4j.examples.Sort.main(Sort.java:64) 59 467 [main] INFO examples.Sort - Exiting main method. 60 </pre> 61 * 62 * @author Ceki Gülcü 63 */ 64 public class SimpleLogger extends MarkerIgnoringBase { 65 66 private static final long serialVersionUID = -6560244151660620173L; 67 68 /** 69 * Mark the time when this class gets loaded into memory. 70 */ 71 private static long startTime = System.currentTimeMillis(); 72 public static final String LINE_SEPARATOR = 73 System.getProperty("line.separator"); 74 private static String INFO_STR = "INFO"; 75 private static String WARN_STR = "WARN"; 76 private static String ERROR_STR = "ERROR"; 77 78 /** 79 * Package access allows only {@link SimpleLoggerFactory} to instantiate 80 * SimpleLogger instances. 81 */ 82 SimpleLogger(String name) { 83 this.name = name; 84 } 85 86 /** 87 * Always returns false. 88 * @return always false 89 */ 90 public boolean isTraceEnabled() { 91 return false; 92 } 93 94 /** 95 * A NOP implementation, as this logger is permanently disabled for 96 * the TRACE level. 97 */ 98 public void trace(String msg) { 99 // NOP 100 } 101 102 /** 103 * A NOP implementation, as this logger is permanently disabled for 104 * the TRACE level. 105 */ 106 public void trace(String format, Object param1) { 107 // NOP 108 } 109 110 111 /** 112 * A NOP implementation, as this logger is permanently disabled for 113 * the TRACE level. 114 */ 115 public void trace(String format, Object param1, Object param2) { 116 // NOP 117 } 118 119 public void trace(String format, Object[] argArray) { 120 // NOP 121 } 122 123 /** 124 * A NOP implementation, as this logger is permanently disabled for 125 * the TRACE level. 126 */ 127 public void trace(String msg, Throwable t) { 128 // NOP 129 } 130 131 132 /** 133 * Always returns false. 134 * @return always false 135 */ 136 public boolean isDebugEnabled() { 137 return false; 138 } 139 140 /** 141 * A NOP implementation, as this logger is permanently disabled for 142 * the DEBUG level. 143 */ 144 public void debug(String msg) { 145 // NOP 146 } 147 148 /** 149 * A NOP implementation, as this logger is permanently disabled for 150 * the DEBUG level. 151 */ 152 public void debug(String format, Object param1) { 153 // NOP 154 } 155 156 157 /** 158 * A NOP implementation, as this logger is permanently disabled for 159 * the DEBUG 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 171 * the DEBUG 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( 221 String level, String format, Object arg1, Object arg2) { 222 String message = MessageFormatter.format(format, arg1, arg2); 223 log(level, message, null); 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 String message = MessageFormatter.arrayFormat(format, argArray); 235 log(level, message, null); 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 /** 279 * Log a message of level INFO, including an exception. 280 */ 281 public void info(String msg, Throwable t) { 282 log(INFO_STR, msg, t); 283 } 284 285 /** 286 * Always returns true. 287 */ 288 public boolean isWarnEnabled() { 289 return true; 290 } 291 292 /** 293 * A simple implementation which always logs messages of level WARN according 294 * to the format outlined above. 295 */ 296 public void warn(String msg) { 297 log(WARN_STR, msg, null); 298 } 299 300 /** 301 * Perform single parameter substitution before logging the message of level 302 * WARN according to the format outlined above. 303 */ 304 public void warn(String format, Object arg) { 305 formatAndLog(WARN_STR, format, arg, null); 306 } 307 308 /** 309 * Perform double parameter substitution before logging the message of level 310 * WARN according to the format outlined above. 311 */ 312 public void warn(String format, Object arg1, Object arg2) { 313 formatAndLog(WARN_STR, format, arg1, arg2); 314 } 315 316 /** 317 * Perform double parameter substitution before logging the message of level 318 * WARN according to the format outlined above. 319 */ 320 public void warn(String format, Object[] argArray) { 321 formatAndLog(WARN_STR, format, argArray); 322 } 323 324 /** 325 * Log a message of level WARN, including an exception. 326 */ 327 public void warn(String msg, Throwable t) { 328 log(WARN_STR, msg, t); 329 } 330 331 /** 332 * Always returns true. 333 */ 334 public boolean isErrorEnabled() { 335 return true; 336 } 337 338 /** 339 * A simple implementation which always logs messages of level ERROR according 340 * to the format outlined above. 341 */ 342 public void error(String msg) { 343 log(ERROR_STR, msg, null); 344 } 345 346 /** 347 * Perform single parameter substitution before logging the message of level 348 * ERROR according to the format outlined above. 349 */ 350 public void error(String format, Object arg) { 351 formatAndLog(ERROR_STR, format, arg, null); 352 } 353 354 /** 355 * Perform double parameter substitution before logging the message of level 356 * ERROR according to the format outlined above. 357 */ 358 public void error(String format, Object arg1, Object arg2) { 359 formatAndLog(ERROR_STR, format, arg1, arg2); 360 } 361 362 /** 363 * Perform double parameter substitution before logging the message of level 364 * ERROR according to the format outlined above. 365 */ 366 public void error(String format, Object[] argArray) { 367 formatAndLog(ERROR_STR, format, argArray); 368 } 369 370 371 /** 372 * Log a message of level ERROR, including an exception. 373 */ 374 public void error(String msg, Throwable t) { 375 log(ERROR_STR, msg, t); 376 } 377 }