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 }