1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 /**
17 * Copyright (c) 2004-2011 QOS.ch
18 * All rights reserved.
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining
21 * a copy of this software and associated documentation files (the
22 * "Software"), to deal in the Software without restriction, including
23 * without limitation the rights to use, copy, modify, merge, publish,
24 * distribute, sublicense, and/or sell copies of the Software, and to
25 * permit persons to whom the Software is furnished to do so, subject to
26 * the following conditions:
27 *
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 *
39 */
40 package com.foxinmy.weixin4j.logging;
41
42 import java.util.logging.Level;
43 import java.util.logging.LogRecord;
44 import java.util.logging.Logger;
45
46 /**
47 * <a href="http://java.sun.com/javase/6/docs/technotes/guides/logging/index.html">java.util.logging</a>
48 * logger.
49 */
50 class JdkLogger extends AbstractInternalLogger {
51
52 private static final long serialVersionUID = -1767272577989225979L;
53
54 final transient Logger logger;
55
56 JdkLogger(Logger logger) {
57 super(logger.getName());
58 this.logger = logger;
59 }
60
61 /**
62 * Is this logger instance enabled for the FINEST level?
63 *
64 * @return True if this Logger is enabled for level FINEST, false otherwise.
65 */
66 @Override
67 public boolean isTraceEnabled() {
68 return logger.isLoggable(Level.FINEST);
69 }
70
71 /**
72 * Log a message object at level FINEST.
73 *
74 * @param msg
75 * - the message object to be logged
76 */
77 @Override
78 public void trace(String msg) {
79 if (logger.isLoggable(Level.FINEST)) {
80 log(SELF, Level.FINEST, msg, null);
81 }
82 }
83
84 /**
85 * Log a message at level FINEST according to the specified format and
86 * argument.
87 *
88 * <p>
89 * This form avoids superfluous object creation when the logger is disabled
90 * for level FINEST.
91 * </p>
92 *
93 * @param format
94 * the format string
95 * @param arg
96 * the argument
97 */
98 @Override
99 public void trace(String format, Object arg) {
100 if (logger.isLoggable(Level.FINEST)) {
101 FormattingTuple ft = MessageFormatter.format(format, arg);
102 log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
103 }
104 }
105
106 /**
107 * Log a message at level FINEST according to the specified format and
108 * arguments.
109 *
110 * <p>
111 * This form avoids superfluous object creation when the logger is disabled
112 * for the FINEST level.
113 * </p>
114 *
115 * @param format
116 * the format string
117 * @param argA
118 * the first argument
119 * @param argB
120 * the second argument
121 */
122 @Override
123 public void trace(String format, Object argA, Object argB) {
124 if (logger.isLoggable(Level.FINEST)) {
125 FormattingTuple ft = MessageFormatter.format(format, argA, argB);
126 log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
127 }
128 }
129
130 /**
131 * Log a message at level FINEST 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 FINEST level.
137 * </p>
138 *
139 * @param format
140 * the format string
141 * @param argArray
142 * an array of arguments
143 */
144 @Override
145 public void trace(String format, Object... argArray) {
146 if (logger.isLoggable(Level.FINEST)) {
147 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
148 log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
149 }
150 }
151
152 /**
153 * Log an exception (throwable) at level FINEST with an accompanying message.
154 *
155 * @param msg
156 * the message accompanying the exception
157 * @param t
158 * the exception (throwable) to log
159 */
160 @Override
161 public void trace(String msg, Throwable t) {
162 if (logger.isLoggable(Level.FINEST)) {
163 log(SELF, Level.FINEST, msg, t);
164 }
165 }
166
167 /**
168 * Is this logger instance enabled for the FINE level?
169 *
170 * @return True if this Logger is enabled for level FINE, false otherwise.
171 */
172 @Override
173 public boolean isDebugEnabled() {
174 return logger.isLoggable(Level.FINE);
175 }
176
177 /**
178 * Log a message object at level FINE.
179 *
180 * @param msg
181 * - the message object to be logged
182 */
183 @Override
184 public void debug(String msg) {
185 if (logger.isLoggable(Level.FINE)) {
186 log(SELF, Level.FINE, msg, null);
187 }
188 }
189
190 /**
191 * Log a message at level FINE according to the specified format and argument.
192 *
193 * <p>
194 * This form avoids superfluous object creation when the logger is disabled
195 * for level FINE.
196 * </p>
197 *
198 * @param format
199 * the format string
200 * @param arg
201 * the argument
202 */
203 @Override
204 public void debug(String format, Object arg) {
205 if (logger.isLoggable(Level.FINE)) {
206 FormattingTuple ft = MessageFormatter.format(format, arg);
207 log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
208 }
209 }
210
211 /**
212 * Log a message at level FINE according to the specified format and
213 * arguments.
214 *
215 * <p>
216 * This form avoids superfluous object creation when the logger is disabled
217 * for the FINE level.
218 * </p>
219 *
220 * @param format
221 * the format string
222 * @param argA
223 * the first argument
224 * @param argB
225 * the second argument
226 */
227 @Override
228 public void debug(String format, Object argA, Object argB) {
229 if (logger.isLoggable(Level.FINE)) {
230 FormattingTuple ft = MessageFormatter.format(format, argA, argB);
231 log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
232 }
233 }
234
235 /**
236 * Log a message at level FINE 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 FINE level.
242 * </p>
243 *
244 * @param format
245 * the format string
246 * @param argArray
247 * an array of arguments
248 */
249 @Override
250 public void debug(String format, Object... argArray) {
251 if (logger.isLoggable(Level.FINE)) {
252 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
253 log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
254 }
255 }
256
257 /**
258 * Log an exception (throwable) at level FINE with an accompanying message.
259 *
260 * @param msg
261 * the message accompanying the exception
262 * @param t
263 * the exception (throwable) to log
264 */
265 @Override
266 public void debug(String msg, Throwable t) {
267 if (logger.isLoggable(Level.FINE)) {
268 log(SELF, Level.FINE, msg, t);
269 }
270 }
271
272 /**
273 * Is this logger instance enabled for the INFO level?
274 *
275 * @return True if this Logger is enabled for the INFO level, false otherwise.
276 */
277 @Override
278 public boolean isInfoEnabled() {
279 return logger.isLoggable(Level.INFO);
280 }
281
282 /**
283 * Log a message object at the INFO level.
284 *
285 * @param msg
286 * - the message object to be logged
287 */
288 @Override
289 public void info(String msg) {
290 if (logger.isLoggable(Level.INFO)) {
291 log(SELF, Level.INFO, msg, null);
292 }
293 }
294
295 /**
296 * Log a message at level INFO according to the specified format and argument.
297 *
298 * <p>
299 * This form avoids superfluous object creation when the logger is disabled
300 * for the INFO level.
301 * </p>
302 *
303 * @param format
304 * the format string
305 * @param arg
306 * the argument
307 */
308 @Override
309 public void info(String format, Object arg) {
310 if (logger.isLoggable(Level.INFO)) {
311 FormattingTuple ft = MessageFormatter.format(format, arg);
312 log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
313 }
314 }
315
316 /**
317 * Log a message at the INFO level according to the specified format and
318 * arguments.
319 *
320 * <p>
321 * This form avoids superfluous object creation when the logger is disabled
322 * for the INFO level.
323 * </p>
324 *
325 * @param format
326 * the format string
327 * @param argA
328 * the first argument
329 * @param argB
330 * the second argument
331 */
332 @Override
333 public void info(String format, Object argA, Object argB) {
334 if (logger.isLoggable(Level.INFO)) {
335 FormattingTuple ft = MessageFormatter.format(format, argA, argB);
336 log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
337 }
338 }
339
340 /**
341 * Log a message at level INFO according to the specified format and
342 * arguments.
343 *
344 * <p>
345 * This form avoids superfluous object creation when the logger is disabled
346 * for the INFO level.
347 * </p>
348 *
349 * @param format
350 * the format string
351 * @param argArray
352 * an array of arguments
353 */
354 @Override
355 public void info(String format, Object... argArray) {
356 if (logger.isLoggable(Level.INFO)) {
357 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
358 log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
359 }
360 }
361
362 /**
363 * Log an exception (throwable) at the INFO level with an accompanying
364 * message.
365 *
366 * @param msg
367 * the message accompanying the exception
368 * @param t
369 * the exception (throwable) to log
370 */
371 @Override
372 public void info(String msg, Throwable t) {
373 if (logger.isLoggable(Level.INFO)) {
374 log(SELF, Level.INFO, msg, t);
375 }
376 }
377
378 /**
379 * Is this logger instance enabled for the WARNING level?
380 *
381 * @return True if this Logger is enabled for the WARNING level, false
382 * otherwise.
383 */
384 @Override
385 public boolean isWarnEnabled() {
386 return logger.isLoggable(Level.WARNING);
387 }
388
389 /**
390 * Log a message object at the WARNING level.
391 *
392 * @param msg
393 * - the message object to be logged
394 */
395 @Override
396 public void warn(String msg) {
397 if (logger.isLoggable(Level.WARNING)) {
398 log(SELF, Level.WARNING, msg, null);
399 }
400 }
401
402 /**
403 * Log a message at the WARNING level according to the specified format and
404 * argument.
405 *
406 * <p>
407 * This form avoids superfluous object creation when the logger is disabled
408 * for the WARNING level.
409 * </p>
410 *
411 * @param format
412 * the format string
413 * @param arg
414 * the argument
415 */
416 @Override
417 public void warn(String format, Object arg) {
418 if (logger.isLoggable(Level.WARNING)) {
419 FormattingTuple ft = MessageFormatter.format(format, arg);
420 log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
421 }
422 }
423
424 /**
425 * Log a message at the WARNING level according to the specified format and
426 * arguments.
427 *
428 * <p>
429 * This form avoids superfluous object creation when the logger is disabled
430 * for the WARNING level.
431 * </p>
432 *
433 * @param format
434 * the format string
435 * @param argA
436 * the first argument
437 * @param argB
438 * the second argument
439 */
440 @Override
441 public void warn(String format, Object argA, Object argB) {
442 if (logger.isLoggable(Level.WARNING)) {
443 FormattingTuple ft = MessageFormatter.format(format, argA, argB);
444 log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
445 }
446 }
447
448 /**
449 * Log a message at level WARNING according to the specified format and
450 * arguments.
451 *
452 * <p>
453 * This form avoids superfluous object creation when the logger is disabled
454 * for the WARNING level.
455 * </p>
456 *
457 * @param format
458 * the format string
459 * @param argArray
460 * an array of arguments
461 */
462 @Override
463 public void warn(String format, Object... argArray) {
464 if (logger.isLoggable(Level.WARNING)) {
465 FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
466 log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
467 }
468 }
469
470 /**
471 * Log an exception (throwable) at the WARNING level with an accompanying
472 * message.
473 *
474 * @param msg
475 * the message accompanying the exception
476 * @param t
477 * the exception (throwable) to log
478 */
479 @Override
480 public void warn(String msg, Throwable t) {
481 if (logger.isLoggable(Level.WARNING)) {
482 log(SELF, Level.WARNING, msg, t);
483 }
484 }
485
486 /**
487 * Is this logger instance enabled for level SEVERE?
488 *
489 * @return True if this Logger is enabled for level SEVERE, false otherwise.
490 */
491 @Override
492 public boolean isErrorEnabled() {
493 return logger.isLoggable(Level.SEVERE);
494 }
495
496 /**
497 * Log a message object at the SEVERE level.
498 *
499 * @param msg
500 * - the message object to be logged
501 */
502 @Override
503 public void error(String msg) {
504 if (logger.isLoggable(Level.SEVERE)) {
505 log(SELF, Level.SEVERE, msg, null);
506 }
507 }
508
509 /**
510 * Log a message at the SEVERE level according to the specified format and
511 * argument.
512 *
513 * <p>
514 * This form avoids superfluous object creation when the logger is disabled
515 * for the SEVERE level.
516 * </p>
517 *
518 * @param format
519 * the format string
520 * @param arg
521 * the argument
522 */
523 @Override
524 public void error(String format, Object arg) {
525 if (logger.isLoggable(Level.SEVERE)) {
526 FormattingTuple ft = MessageFormatter.format(format, arg);
527 log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
528 }
529 }
530
531 /**
532 * Log a message at the SEVERE level according to the specified format and
533 * arguments.
534 *
535 * <p>
536 * This form avoids superfluous object creation when the logger is disabled
537 * for the SEVERE level.
538 * </p>
539 *
540 * @param format
541 * the format string
542 * @param argA
543 * the first argument
544 * @param argB
545 * the second argument
546 */
547 @Override
548 public void error(String format, Object argA, Object argB) {
549 if (logger.isLoggable(Level.SEVERE)) {
550 FormattingTuple ft = MessageFormatter.format(format, argA, argB);
551 log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
552 }
553 }
554
555 /**
556 * Log a message at level SEVERE according to the specified format and
557 * arguments.
558 *
559 * <p>
560 * This form avoids superfluous object creation when the logger is disabled
561 * for the SEVERE level.
562 * </p>
563 *
564 * @param format
565 * the format string
566 * @param arguments
567 * an array of arguments
568 */
569 @Override
570 public void error(String format, Object... arguments) {
571 if (logger.isLoggable(Level.SEVERE)) {
572 FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
573 log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
574 }
575 }
576
577 /**
578 * Log an exception (throwable) at the SEVERE level with an accompanying
579 * message.
580 *
581 * @param msg
582 * the message accompanying the exception
583 * @param t
584 * the exception (throwable) to log
585 */
586 @Override
587 public void error(String msg, Throwable t) {
588 if (logger.isLoggable(Level.SEVERE)) {
589 log(SELF, Level.SEVERE, msg, t);
590 }
591 }
592
593 /**
594 * Log the message at the specified level with the specified throwable if any.
595 * This method creates a LogRecord and fills in caller date before calling
596 * this instance's JDK14 logger.
597 *
598 * See bug report #13 for more details.
599 */
600 private void log(String callerFQCN, Level level, String msg, Throwable t) {
601 // millis and thread are filled by the constructor
602 LogRecord record = new LogRecord(level, msg);
603 record.setLoggerName(name());
604 record.setThrown(t);
605 fillCallerData(callerFQCN, record);
606 logger.log(record);
607 }
608
609 static final String SELF = JdkLogger.class.getName();
610 static final String SUPER = AbstractInternalLogger.class.getName();
611
612 /**
613 * Fill in caller data if possible.
614 *
615 * @param record
616 * The record to update
617 */
618 private static void fillCallerData(String callerFQCN, LogRecord record) {
619 StackTraceElement[] steArray = new Throwable().getStackTrace();
620
621 int selfIndex = -1;
622 for (int i = 0; i < steArray.length; i++) {
623 final String className = steArray[i].getClassName();
624 if (className.equals(callerFQCN) || className.equals(SUPER)) {
625 selfIndex = i;
626 break;
627 }
628 }
629
630 int found = -1;
631 for (int i = selfIndex + 1; i < steArray.length; i++) {
632 final String className = steArray[i].getClassName();
633 if (!(className.equals(callerFQCN) || className.equals(SUPER))) {
634 found = i;
635 break;
636 }
637 }
638
639 if (found != -1) {
640 StackTraceElement ste = steArray[found];
641 // setting the class name has the side effect of setting
642 // the needToInferCaller variable to false.
643 record.setSourceClassName(ste.getClassName());
644 record.setSourceMethodName(ste.getMethodName());
645 }
646 }
647 }