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 /** 86 * Package access allows only {@link AndroidLoggerFactory} to instantiate 87 * SimpleLogger instances. 88 */ AndroidLoggerAdapter(String tag)89 AndroidLoggerAdapter(String tag) { 90 this.name = tag; 91 } 92 93 /** 94 * Is this logger instance enabled for the VERBOSE level? 95 * 96 * @return True if this Logger is enabled for level VERBOSE, false otherwise. 97 */ isTraceEnabled()98 public boolean isTraceEnabled() { 99 return isLoggable(Log.VERBOSE); 100 } 101 102 /** 103 * Log a message object at level VERBOSE. 104 * 105 * @param msg 106 * - the message object to be logged 107 */ trace(String msg)108 public void trace(String msg) { 109 log(Log.VERBOSE, msg, null); 110 } 111 112 /** 113 * Log a message at level VERBOSE according to the specified format and 114 * argument. 115 * 116 * <p> 117 * This form avoids superfluous object creation when the logger is disabled 118 * for level VERBOSE. 119 * </p> 120 * 121 * @param format 122 * the format string 123 * @param arg 124 * the argument 125 */ trace(String format, Object arg)126 public void trace(String format, Object arg) { 127 formatAndLog(Log.VERBOSE, format, arg); 128 } 129 130 /** 131 * Log a message at level VERBOSE according to the specified format and 132 * arguments. 133 * 134 * <p> 135 * This form avoids superfluous object creation when the logger is disabled 136 * for the VERBOSE level. 137 * </p> 138 * 139 * @param format 140 * the format string 141 * @param arg1 142 * the first argument 143 * @param arg2 144 * the second argument 145 */ trace(String format, Object arg1, Object arg2)146 public void trace(String format, Object arg1, Object arg2) { 147 formatAndLog(Log.VERBOSE, format, arg1, arg2); 148 } 149 150 /** 151 * Log a message at level VERBOSE according to the specified format and 152 * arguments. 153 * 154 * <p> 155 * This form avoids superfluous object creation when the logger is disabled 156 * for the VERBOSE level. 157 * </p> 158 * 159 * @param format 160 * the format string 161 * @param argArray 162 * an array of arguments 163 */ trace(String format, Object... argArray)164 public void trace(String format, Object... argArray) { 165 formatAndLog(Log.VERBOSE, format, argArray); 166 } 167 168 /** 169 * Log an exception (throwable) at level VERBOSE with an accompanying message. 170 * 171 * @param msg 172 * the message accompanying the exception 173 * @param t 174 * the exception (throwable) to log 175 */ trace(String msg, Throwable t)176 public void trace(String msg, Throwable t) { 177 log(Log.VERBOSE, msg, t); 178 } 179 180 /** 181 * Is this logger instance enabled for the DEBUG level? 182 * 183 * @return True if this Logger is enabled for level DEBUG, false otherwise. 184 */ isDebugEnabled()185 public boolean isDebugEnabled() { 186 return isLoggable(Log.DEBUG); 187 } 188 189 /** 190 * Log a message object at level DEBUG. 191 * 192 * @param msg 193 * - the message object to be logged 194 */ debug(String msg)195 public void debug(String msg) { 196 log(Log.DEBUG, msg, null); 197 } 198 199 /** 200 * Log a message at level DEBUG according to the specified format and argument. 201 * 202 * <p> 203 * This form avoids superfluous object creation when the logger is disabled 204 * for level DEBUG. 205 * </p> 206 * 207 * @param format 208 * the format string 209 * @param arg 210 * the argument 211 */ debug(String format, Object arg)212 public void debug(String format, Object arg) { 213 formatAndLog(Log.DEBUG, format, arg); 214 } 215 216 /** 217 * Log a message at level DEBUG according to the specified format and 218 * arguments. 219 * 220 * <p> 221 * This form avoids superfluous object creation when the logger is disabled 222 * for the DEBUG level. 223 * </p> 224 * 225 * @param format 226 * the format string 227 * @param arg1 228 * the first argument 229 * @param arg2 230 * the second argument 231 */ debug(String format, Object arg1, Object arg2)232 public void debug(String format, Object arg1, Object arg2) { 233 formatAndLog(Log.DEBUG, format, arg1, arg2); 234 } 235 236 /** 237 * Log a message at level DEBUG according to the specified format and 238 * arguments. 239 * 240 * <p> 241 * This form avoids superfluous object creation when the logger is disabled 242 * for the DEBUG level. 243 * </p> 244 * 245 * @param format 246 * the format string 247 * @param argArray 248 * an array of arguments 249 */ debug(String format, Object... argArray)250 public void debug(String format, Object... argArray) { 251 formatAndLog(Log.DEBUG, format, argArray); 252 } 253 254 /** 255 * Log an exception (throwable) at level DEBUG with an accompanying message. 256 * 257 * @param msg 258 * the message accompanying the exception 259 * @param t 260 * the exception (throwable) to log 261 */ debug(String msg, Throwable t)262 public void debug(String msg, Throwable t) { 263 log(Log.VERBOSE, msg, t); 264 } 265 266 /** 267 * Is this logger instance enabled for the INFO level? 268 * 269 * @return True if this Logger is enabled for the INFO level, false otherwise. 270 */ isInfoEnabled()271 public boolean isInfoEnabled() { 272 return isLoggable(Log.INFO); 273 } 274 275 /** 276 * Log a message object at the INFO level. 277 * 278 * @param msg 279 * - the message object to be logged 280 */ info(String msg)281 public void info(String msg) { 282 log(Log.INFO, msg, null); 283 } 284 285 /** 286 * Log a message at level INFO according to the specified format and argument. 287 * 288 * <p> 289 * This form avoids superfluous object creation when the logger is disabled 290 * for the INFO level. 291 * </p> 292 * 293 * @param format 294 * the format string 295 * @param arg 296 * the argument 297 */ info(String format, Object arg)298 public void info(String format, Object arg) { 299 formatAndLog(Log.INFO, format, arg); 300 } 301 302 /** 303 * Log a message at the INFO level according to the specified format and 304 * arguments. 305 * 306 * <p> 307 * This form avoids superfluous object creation when the logger is disabled 308 * for the INFO level. 309 * </p> 310 * 311 * @param format 312 * the format string 313 * @param arg1 314 * the first argument 315 * @param arg2 316 * the second argument 317 */ info(String format, Object arg1, Object arg2)318 public void info(String format, Object arg1, Object arg2) { 319 formatAndLog(Log.INFO, format, arg1, arg2); 320 } 321 322 /** 323 * Log a message at level INFO according to the specified format and 324 * arguments. 325 * 326 * <p> 327 * This form avoids superfluous object creation when the logger is disabled 328 * for the INFO level. 329 * </p> 330 * 331 * @param format 332 * the format string 333 * @param argArray 334 * an array of arguments 335 */ info(String format, Object... argArray)336 public void info(String format, Object... argArray) { 337 formatAndLog(Log.INFO, format, argArray); 338 } 339 340 /** 341 * Log an exception (throwable) at the INFO level with an accompanying 342 * message. 343 * 344 * @param msg 345 * the message accompanying the exception 346 * @param t 347 * the exception (throwable) to log 348 */ info(String msg, Throwable t)349 public void info(String msg, Throwable t) { 350 log(Log.INFO, msg, t); 351 } 352 353 /** 354 * Is this logger instance enabled for the WARN level? 355 * 356 * @return True if this Logger is enabled for the WARN level, false 357 * otherwise. 358 */ isWarnEnabled()359 public boolean isWarnEnabled() { 360 return isLoggable(Log.WARN); 361 } 362 363 /** 364 * Log a message object at the WARN level. 365 * 366 * @param msg 367 * - the message object to be logged 368 */ warn(String msg)369 public void warn(String msg) { 370 log(Log.WARN, msg, null); 371 } 372 373 /** 374 * Log a message at the WARN level according to the specified format and 375 * argument. 376 * 377 * <p> 378 * This form avoids superfluous object creation when the logger is disabled 379 * for the WARN level. 380 * </p> 381 * 382 * @param format 383 * the format string 384 * @param arg 385 * the argument 386 */ warn(String format, Object arg)387 public void warn(String format, Object arg) { 388 formatAndLog(Log.WARN, format, arg); 389 } 390 391 /** 392 * Log a message at the WARN level according to the specified format and 393 * arguments. 394 * 395 * <p> 396 * This form avoids superfluous object creation when the logger is disabled 397 * for the WARN level. 398 * </p> 399 * 400 * @param format 401 * the format string 402 * @param arg1 403 * the first argument 404 * @param arg2 405 * the second argument 406 */ warn(String format, Object arg1, Object arg2)407 public void warn(String format, Object arg1, Object arg2) { 408 formatAndLog(Log.WARN, format, arg1, arg2); 409 } 410 411 /** 412 * Log a message at level WARN according to the specified format and 413 * arguments. 414 * 415 * <p> 416 * This form avoids superfluous object creation when the logger is disabled 417 * for the WARN level. 418 * </p> 419 * 420 * @param format 421 * the format string 422 * @param argArray 423 * an array of arguments 424 */ warn(String format, Object... argArray)425 public void warn(String format, Object... argArray) { 426 formatAndLog(Log.WARN, format, argArray); 427 } 428 429 /** 430 * Log an exception (throwable) at the WARN level with an accompanying 431 * message. 432 * 433 * @param msg 434 * the message accompanying the exception 435 * @param t 436 * the exception (throwable) to log 437 */ warn(String msg, Throwable t)438 public void warn(String msg, Throwable t) { 439 log(Log.WARN, msg, t); 440 } 441 442 /** 443 * Is this logger instance enabled for level ERROR? 444 * 445 * @return True if this Logger is enabled for level ERROR, false otherwise. 446 */ isErrorEnabled()447 public boolean isErrorEnabled() { 448 return isLoggable(Log.ERROR); 449 } 450 451 /** 452 * Log a message object at the ERROR level. 453 * 454 * @param msg 455 * - the message object to be logged 456 */ error(String msg)457 public void error(String msg) { 458 log(Log.ERROR, msg, null); 459 } 460 461 /** 462 * Log a message at the ERROR level according to the specified format and 463 * argument. 464 * 465 * <p> 466 * This form avoids superfluous object creation when the logger is disabled 467 * for the ERROR level. 468 * </p> 469 * 470 * @param format 471 * the format string 472 * @param arg 473 * the argument 474 */ error(String format, Object arg)475 public void error(String format, Object arg) { 476 formatAndLog(Log.ERROR, format, arg); 477 } 478 479 /** 480 * Log a message at the ERROR level according to the specified format and 481 * arguments. 482 * 483 * <p> 484 * This form avoids superfluous object creation when the logger is disabled 485 * for the ERROR level. 486 * </p> 487 * 488 * @param format 489 * the format string 490 * @param arg1 491 * the first argument 492 * @param arg2 493 * the second argument 494 */ error(String format, Object arg1, Object arg2)495 public void error(String format, Object arg1, Object arg2) { 496 formatAndLog(Log.ERROR, format, arg1, arg2); 497 } 498 499 /** 500 * Log a message at level ERROR according to the specified format and 501 * arguments. 502 * 503 * <p> 504 * This form avoids superfluous object creation when the logger is disabled 505 * for the ERROR level. 506 * </p> 507 * 508 * @param format 509 * the format string 510 * @param argArray 511 * an array of arguments 512 */ error(String format, Object... argArray)513 public void error(String format, Object... argArray) { 514 formatAndLog(Log.ERROR, format, argArray); 515 } 516 517 /** 518 * Log an exception (throwable) at the ERROR level with an accompanying 519 * message. 520 * 521 * @param msg 522 * the message accompanying the exception 523 * @param t 524 * the exception (throwable) to log 525 */ error(String msg, Throwable t)526 public void error(String msg, Throwable t) { 527 log(Log.ERROR, msg, t); 528 } 529 formatAndLog(int priority, String format, Object... argArray)530 private void formatAndLog(int priority, String format, Object... argArray) { 531 if (isLoggable(priority)) { 532 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray); 533 _log(priority, ft.getMessage(), ft.getThrowable()); 534 } 535 } 536 log(int priority, String message, Throwable throwable)537 private void log(int priority, String message, Throwable throwable) { 538 if (isLoggable(priority)) { 539 _log(priority, message, throwable); 540 } 541 } 542 isLoggable(int priority)543 private boolean isLoggable(int priority) { 544 return Log.isLoggable(name, priority); 545 } 546 _log(int priority, String message, Throwable throwable)547 private void _log(int priority, String message, Throwable throwable) { 548 if (throwable != null) { 549 message += '\n' + Log.getStackTraceString(throwable); 550 } 551 Log.println(priority, name, message); 552 } 553 }