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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
526 public void error(String msg, Throwable t) {
527 log(Log.ERROR, msg, t);
528 }
529
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
537 private void log(int priority, String message, Throwable throwable) {
538 if (isLoggable(priority)) {
539 _log(priority, message, throwable);
540 }
541 }
542
543 private boolean isLoggable(int priority) {
544 return Log.isLoggable(name, priority);
545 }
546
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 }