1 /* 2 * Copyright (c) 2004-2013 QOS.ch 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 package org.slf4j.impl; 26 27 import android.util.Log; 28 import org.slf4j.helpers.FormattingTuple; 29 import org.slf4j.helpers.MarkerIgnoringBase; 30 import org.slf4j.helpers.MessageFormatter; 31 32 /** 33 * <p>A simple implementation that delegates all log requests to the Google Android 34 * logging facilities. Note that this logger does not support {@link org.slf4j.Marker}. 35 * Methods taking marker data as parameter simply invoke the eponymous method 36 * without the Marker argument, discarding any marker data in the process.</p> 37 * 38 * <p>The logging levels specified for SLF4J can be almost directly mapped to 39 * the levels that exist in the Google Android platform. The following table 40 * shows the mapping implemented by this logger.</p> 41 * 42 * <table border="1"> 43 * <tr><th><b>SLF4J<b></th><th><b>Android</b></th></tr> 44 * <tr><td>TRACE</td><td>{@link android.util.Log#VERBOSE}</td></tr> 45 * <tr><td>DEBUG</td><td>{@link android.util.Log#DEBUG}</td></tr> 46 * <tr><td>INFO</td><td>{@link android.util.Log#INFO}</td></tr> 47 * <tr><td>WARN</td><td>{@link android.util.Log#WARN}</td></tr> 48 * <tr><td>ERROR</td><td>{@link android.util.Log#ERROR}</td></tr> 49 * </table> 50 * 51 * <p>Use loggers as usual: 52 * <ul> 53 * <li> 54 * Declare a logger<br/> 55 * <code>private static final Logger logger = LoggerFactory.getLogger(MyClass.class);</code> 56 * </li> 57 * <li> 58 * Invoke logging methods, e.g.,<br/> 59 * <code>logger.debug("Some log message. Details: {}", someObject);</code><br/> 60 * <code>logger.debug("Some log message with varargs. Details: {}, {}, {}", someObject1, someObject2, someObject3);</code> 61 * </li> 62 * </ul> 63 * </p> 64 * 65 * <p>Logger instances created using the LoggerFactory are named either according to the name 66 * or the fully qualified class name of the class given as a parameter. 67 * Each logger name will be used as the log message tag on the Android platform. 68 * However, tag names cannot be longer than 23 characters so if logger name exceeds this limit then 69 * it will be truncated by the LoggerFactory. The following examples illustrate this. 70 * <table border="1"> 71 * <tr><th><b>Original Name<b></th><th><b>Truncated Name</b></th></tr> 72 * <tr><td>org.example.myproject.mypackage.MyClass</td><td>o*.e*.m*.m*.MyClass</td></tr> 73 * <tr><td>o.e.myproject.mypackage.MyClass</td><td>o.e.m*.m*.MyClass</td></tr> 74 * <tr><td>org.example.ThisNameIsWayTooLongAndWillBeTruncated</td><td>*LongAndWillBeTruncated</td></tr> 75 * <tr><td>ThisNameIsWayTooLongAndWillBeTruncated</td><td>*LongAndWillBeTruncated</td></tr> 76 * </table> 77 * </p> 78 * 79 * @author Andrey Korzhevskiy <a.korzhevskiy@gmail.com> 80 */ 81 class AndroidLoggerAdapter extends MarkerIgnoringBase { 82 private static final long serialVersionUID = -1227274521521287937L; 83 84 /** 85 * Package access allows only {@link AndroidLoggerFactory} to instantiate 86 * SimpleLogger instances. 87 */ 88 AndroidLoggerAdapter(String tag) { 89 this.name = tag; 90 } 91 92 /** 93 * Is this logger instance enabled for the VERBOSE level? 94 * 95 * @return True if this Logger is enabled for level VERBOSE, false otherwise. 96 */ 97 public boolean isTraceEnabled() { 98 return isLoggable(Log.VERBOSE); 99 } 100 101 /** 102 * Log a message object at level VERBOSE. 103 * 104 * @param msg 105 * - the message object to be logged 106 */ 107 public void trace(String msg) { 108 log(Log.VERBOSE, msg, null); 109 } 110 111 /** 112 * Log a message at level VERBOSE according to the specified format and 113 * argument. 114 * 115 * <p> 116 * This form avoids superfluous object creation when the logger is disabled 117 * for level VERBOSE. 118 * </p> 119 * 120 * @param format 121 * the format string 122 * @param arg 123 * the argument 124 */ 125 public void trace(String format, Object arg) { 126 formatAndLog(Log.VERBOSE, format, arg); 127 } 128 129 /** 130 * Log a message at level VERBOSE according to the specified format and 131 * arguments. 132 * 133 * <p> 134 * This form avoids superfluous object creation when the logger is disabled 135 * for the VERBOSE level. 136 * </p> 137 * 138 * @param format 139 * the format string 140 * @param arg1 141 * the first argument 142 * @param arg2 143 * the second argument 144 */ 145 public void trace(String format, Object arg1, Object arg2) { 146 formatAndLog(Log.VERBOSE, format, arg1, arg2); 147 } 148 149 /** 150 * Log a message at level VERBOSE according to the specified format and 151 * arguments. 152 * 153 * <p> 154 * This form avoids superfluous object creation when the logger is disabled 155 * for the VERBOSE level. 156 * </p> 157 * 158 * @param format 159 * the format string 160 * @param argArray 161 * an array of arguments 162 */ 163 public void trace(String format, Object... argArray) { 164 formatAndLog(Log.VERBOSE, format, argArray); 165 } 166 167 /** 168 * Log an exception (throwable) at level VERBOSE with an accompanying message. 169 * 170 * @param msg 171 * the message accompanying the exception 172 * @param t 173 * the exception (throwable) to log 174 */ 175 public void trace(String msg, Throwable t) { 176 log(Log.VERBOSE, msg, t); 177 } 178 179 /** 180 * Is this logger instance enabled for the DEBUG level? 181 * 182 * @return True if this Logger is enabled for level DEBUG, false otherwise. 183 */ 184 public boolean isDebugEnabled() { 185 return isLoggable(Log.DEBUG); 186 } 187 188 /** 189 * Log a message object at level DEBUG. 190 * 191 * @param msg 192 * - the message object to be logged 193 */ 194 public void debug(String msg) { 195 log(Log.DEBUG, msg, null); 196 } 197 198 /** 199 * Log a message at level DEBUG according to the specified format and argument. 200 * 201 * <p> 202 * This form avoids superfluous object creation when the logger is disabled 203 * for level DEBUG. 204 * </p> 205 * 206 * @param format 207 * the format string 208 * @param arg 209 * the argument 210 */ 211 public void debug(String format, Object arg) { 212 formatAndLog(Log.DEBUG, format, arg); 213 } 214 215 /** 216 * Log a message at level DEBUG according to the specified format and 217 * arguments. 218 * 219 * <p> 220 * This form avoids superfluous object creation when the logger is disabled 221 * for the DEBUG level. 222 * </p> 223 * 224 * @param format 225 * the format string 226 * @param arg1 227 * the first argument 228 * @param arg2 229 * the second argument 230 */ 231 public void debug(String format, Object arg1, Object arg2) { 232 formatAndLog(Log.DEBUG, format, arg1, arg2); 233 } 234 235 /** 236 * Log a message at level DEBUG according to the specified format and 237 * arguments. 238 * 239 * <p> 240 * This form avoids superfluous object creation when the logger is disabled 241 * for the DEBUG level. 242 * </p> 243 * 244 * @param format 245 * the format string 246 * @param argArray 247 * an array of arguments 248 */ 249 public void debug(String format, Object... argArray) { 250 formatAndLog(Log.DEBUG, format, argArray); 251 } 252 253 /** 254 * Log an exception (throwable) at level DEBUG with an accompanying message. 255 * 256 * @param msg 257 * the message accompanying the exception 258 * @param t 259 * the exception (throwable) to log 260 */ 261 public void debug(String msg, Throwable t) { 262 log(Log.VERBOSE, msg, t); 263 } 264 265 /** 266 * Is this logger instance enabled for the INFO level? 267 * 268 * @return True if this Logger is enabled for the INFO level, false otherwise. 269 */ 270 public boolean isInfoEnabled() { 271 return isLoggable(Log.INFO); 272 } 273 274 /** 275 * Log a message object at the INFO level. 276 * 277 * @param msg 278 * - the message object to be logged 279 */ 280 public void info(String msg) { 281 log(Log.INFO, msg, null); 282 } 283 284 /** 285 * Log a message at level INFO according to the specified format and argument. 286 * 287 * <p> 288 * This form avoids superfluous object creation when the logger is disabled 289 * for the INFO level. 290 * </p> 291 * 292 * @param format 293 * the format string 294 * @param arg 295 * the argument 296 */ 297 public void info(String format, Object arg) { 298 formatAndLog(Log.INFO, format, arg); 299 } 300 301 /** 302 * Log a message at the INFO level according to the specified format and 303 * arguments. 304 * 305 * <p> 306 * This form avoids superfluous object creation when the logger is disabled 307 * for the INFO level. 308 * </p> 309 * 310 * @param format 311 * the format string 312 * @param arg1 313 * the first argument 314 * @param arg2 315 * the second argument 316 */ 317 public void info(String format, Object arg1, Object arg2) { 318 formatAndLog(Log.INFO, format, arg1, arg2); 319 } 320 321 /** 322 * Log a message at level INFO according to the specified format and 323 * arguments. 324 * 325 * <p> 326 * This form avoids superfluous object creation when the logger is disabled 327 * for the INFO level. 328 * </p> 329 * 330 * @param format 331 * the format string 332 * @param argArray 333 * an array of arguments 334 */ 335 public void info(String format, Object... argArray) { 336 formatAndLog(Log.INFO, format, argArray); 337 } 338 339 /** 340 * Log an exception (throwable) at the INFO level with an accompanying 341 * message. 342 * 343 * @param msg 344 * the message accompanying the exception 345 * @param t 346 * the exception (throwable) to log 347 */ 348 public void info(String msg, Throwable t) { 349 log(Log.INFO, msg, t); 350 } 351 352 /** 353 * Is this logger instance enabled for the WARN level? 354 * 355 * @return True if this Logger is enabled for the WARN level, false 356 * otherwise. 357 */ 358 public boolean isWarnEnabled() { 359 return isLoggable(Log.WARN); 360 } 361 362 /** 363 * Log a message object at the WARN level. 364 * 365 * @param msg 366 * - the message object to be logged 367 */ 368 public void warn(String msg) { 369 log(Log.WARN, msg, null); 370 } 371 372 /** 373 * Log a message at the WARN level according to the specified format and 374 * argument. 375 * 376 * <p> 377 * This form avoids superfluous object creation when the logger is disabled 378 * for the WARN level. 379 * </p> 380 * 381 * @param format 382 * the format string 383 * @param arg 384 * the argument 385 */ 386 public void warn(String format, Object arg) { 387 formatAndLog(Log.WARN, format, arg); 388 } 389 390 /** 391 * Log a message at the WARN level according to the specified format and 392 * arguments. 393 * 394 * <p> 395 * This form avoids superfluous object creation when the logger is disabled 396 * for the WARN level. 397 * </p> 398 * 399 * @param format 400 * the format string 401 * @param arg1 402 * the first argument 403 * @param arg2 404 * the second argument 405 */ 406 public void warn(String format, Object arg1, Object arg2) { 407 formatAndLog(Log.WARN, format, arg1, arg2); 408 } 409 410 /** 411 * Log a message at level WARN according to the specified format and 412 * arguments. 413 * 414 * <p> 415 * This form avoids superfluous object creation when the logger is disabled 416 * for the WARN level. 417 * </p> 418 * 419 * @param format 420 * the format string 421 * @param argArray 422 * an array of arguments 423 */ 424 public void warn(String format, Object... argArray) { 425 formatAndLog(Log.WARN, format, argArray); 426 } 427 428 /** 429 * Log an exception (throwable) at the WARN level with an accompanying 430 * message. 431 * 432 * @param msg 433 * the message accompanying the exception 434 * @param t 435 * the exception (throwable) to log 436 */ 437 public void warn(String msg, Throwable t) { 438 log(Log.WARN, msg, t); 439 } 440 441 /** 442 * Is this logger instance enabled for level ERROR? 443 * 444 * @return True if this Logger is enabled for level ERROR, false otherwise. 445 */ 446 public boolean isErrorEnabled() { 447 return isLoggable(Log.ERROR); 448 } 449 450 /** 451 * Log a message object at the ERROR level. 452 * 453 * @param msg 454 * - the message object to be logged 455 */ 456 public void error(String msg) { 457 log(Log.ERROR, msg, null); 458 } 459 460 /** 461 * Log a message at the ERROR level according to the specified format and 462 * argument. 463 * 464 * <p> 465 * This form avoids superfluous object creation when the logger is disabled 466 * for the ERROR level. 467 * </p> 468 * 469 * @param format 470 * the format string 471 * @param arg 472 * the argument 473 */ 474 public void error(String format, Object arg) { 475 formatAndLog(Log.ERROR, format, arg); 476 } 477 478 /** 479 * Log a message at the ERROR level according to the specified format and 480 * arguments. 481 * 482 * <p> 483 * This form avoids superfluous object creation when the logger is disabled 484 * for the ERROR level. 485 * </p> 486 * 487 * @param format 488 * the format string 489 * @param arg1 490 * the first argument 491 * @param arg2 492 * the second argument 493 */ 494 public void error(String format, Object arg1, Object arg2) { 495 formatAndLog(Log.ERROR, format, arg1, arg2); 496 } 497 498 /** 499 * Log a message at level ERROR according to the specified format and 500 * arguments. 501 * 502 * <p> 503 * This form avoids superfluous object creation when the logger is disabled 504 * for the ERROR level. 505 * </p> 506 * 507 * @param format 508 * the format string 509 * @param argArray 510 * an array of arguments 511 */ 512 public void error(String format, Object... argArray) { 513 formatAndLog(Log.ERROR, format, argArray); 514 } 515 516 /** 517 * Log an exception (throwable) at the ERROR level with an accompanying 518 * message. 519 * 520 * @param msg 521 * the message accompanying the exception 522 * @param t 523 * the exception (throwable) to log 524 */ 525 public void error(String msg, Throwable t) { 526 log(Log.ERROR, msg, t); 527 } 528 529 private void formatAndLog(int priority, String format, Object... argArray) { 530 if (isLoggable(priority)) { 531 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 532 logInternal(priority, ft.getMessage(), ft.getThrowable()); 533 } 534 } 535 536 private void log(int priority, String message, Throwable throwable) { 537 if (isLoggable(priority)) { 538 logInternal(priority, message, throwable); 539 } 540 } 541 542 private boolean isLoggable(int priority) { 543 return Log.isLoggable(name, priority); 544 } 545 546 private void logInternal(int priority, String message, Throwable throwable) { 547 if (throwable != null) { 548 message += '\n' + Log.getStackTraceString(throwable); 549 } 550 Log.println(priority, name, message); 551 } 552 }