1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.util.log;
20
21 import java.io.PrintStream;
22 import java.security.AccessControlException;
23 import java.util.Properties;
24
25 import org.eclipse.jetty.util.DateCache;
26 import org.eclipse.jetty.util.annotation.ManagedAttribute;
27 import org.eclipse.jetty.util.annotation.ManagedObject;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 @ManagedObject("Jetty StdErr Logging Implementation")
93 public class StdErrLog extends AbstractLogger
94 {
95 private static final String EOL = System.getProperty("line.separator");
96 private static DateCache _dateCache;
97 private static final Properties __props = new Properties();
98
99 private final static boolean __source = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.SOURCE",
100 Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
101 private final static boolean __long = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
102 private final static boolean __escape = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.ESCAPE","true"));
103
104 static
105 {
106 __props.putAll(Log.__props);
107
108 String deprecatedProperties[] =
109 { "DEBUG", "org.eclipse.jetty.util.log.DEBUG", "org.eclipse.jetty.util.log.stderr.DEBUG" };
110
111
112 for (String deprecatedProp : deprecatedProperties)
113 {
114 if (System.getProperty(deprecatedProp) != null)
115 {
116 System.err.printf("System Property [%s] has been deprecated! (Use org.eclipse.jetty.LEVEL=DEBUG instead)%n",deprecatedProp);
117 }
118 }
119
120 try
121 {
122 _dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
123 }
124 catch (Exception x)
125 {
126 x.printStackTrace(System.err);
127 }
128 }
129
130 public static final int LEVEL_ALL = 0;
131 public static final int LEVEL_DEBUG = 1;
132 public static final int LEVEL_INFO = 2;
133 public static final int LEVEL_WARN = 3;
134 public static final int LEVEL_OFF = 10;
135
136 private int _level = LEVEL_INFO;
137
138 private int _configuredLevel;
139 private PrintStream _stderr = null;
140 private boolean _source = __source;
141
142 private boolean _printLongNames = __long;
143
144 private final String _name;
145
146 private final String _abbrevname;
147 private boolean _hideStacks = false;
148
149
150
151
152
153
154
155
156
157
158
159
160 public static StdErrLog getLogger(Class<?> clazz)
161 {
162 Logger log = Log.getLogger(clazz);
163 if (log instanceof StdErrLog)
164 {
165 return (StdErrLog)log;
166 }
167 throw new RuntimeException("Logger for " + clazz + " is not of type StdErrLog");
168 }
169
170
171
172
173
174
175 public StdErrLog()
176 {
177 this(null);
178 }
179
180
181
182
183
184
185
186 public StdErrLog(String name)
187 {
188 this(name,__props);
189 }
190
191
192
193
194
195
196
197
198
199 public StdErrLog(String name, Properties props)
200 {
201 if (props!=null && props!=__props)
202 __props.putAll(props);
203 this._name = name == null?"":name;
204 this._abbrevname = condensePackageString(this._name);
205 this._level = getLoggingLevel(props,this._name);
206 this._configuredLevel = this._level;
207
208 try
209 {
210 String source = getLoggingProperty(props,_name,"SOURCE");
211 _source = source==null?__source:Boolean.parseBoolean(source);
212 }
213 catch (AccessControlException ace)
214 {
215 _source = __source;
216 }
217
218 try
219 {
220
221 String stacks = getLoggingProperty(props,_name,"STACKS");
222 _hideStacks = stacks==null?false:!Boolean.parseBoolean(stacks);
223 }
224 catch (AccessControlException ignore)
225 {
226
227 }
228 }
229
230
231
232
233
234
235
236
237
238
239
240 public static int getLoggingLevel(Properties props, final String name)
241 {
242 if ((props == null) || (props.isEmpty()))
243 {
244
245 return getLevelId("log.LEVEL","INFO");
246 }
247
248
249
250 String nameSegment = name;
251
252 while ((nameSegment != null) && (nameSegment.length() > 0))
253 {
254 String levelStr = props.getProperty(nameSegment + ".LEVEL");
255
256 int level = getLevelId(nameSegment + ".LEVEL",levelStr);
257 if (level != (-1))
258 {
259 return level;
260 }
261
262
263 int idx = nameSegment.lastIndexOf('.');
264 if (idx >= 0)
265 {
266 nameSegment = nameSegment.substring(0,idx);
267 }
268 else
269 {
270 nameSegment = null;
271 }
272 }
273
274
275 return getLevelId("log.LEVEL",props.getProperty("log.LEVEL","INFO"));
276 }
277
278 public static String getLoggingProperty(Properties props, String name, String property)
279 {
280
281
282 String nameSegment = name;
283
284 while ((nameSegment != null) && (nameSegment.length() > 0))
285 {
286 String s = props.getProperty(nameSegment+"."+property);
287 if (s!=null)
288 return s;
289
290
291 int idx = nameSegment.lastIndexOf('.');
292 nameSegment = (idx >= 0)?nameSegment.substring(0,idx):null;
293 }
294
295 return null;
296 }
297
298 protected static int getLevelId(String levelSegment, String levelName)
299 {
300 if (levelName == null)
301 {
302 return -1;
303 }
304 String levelStr = levelName.trim();
305 if ("ALL".equalsIgnoreCase(levelStr))
306 {
307 return LEVEL_ALL;
308 }
309 else if ("DEBUG".equalsIgnoreCase(levelStr))
310 {
311 return LEVEL_DEBUG;
312 }
313 else if ("INFO".equalsIgnoreCase(levelStr))
314 {
315 return LEVEL_INFO;
316 }
317 else if ("WARN".equalsIgnoreCase(levelStr))
318 {
319 return LEVEL_WARN;
320 }
321 else if ("OFF".equalsIgnoreCase(levelStr))
322 {
323 return LEVEL_OFF;
324 }
325
326 System.err.println("Unknown StdErrLog level [" + levelSegment + "]=[" + levelStr + "], expecting only [ALL, DEBUG, INFO, WARN, OFF] as values.");
327 return -1;
328 }
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 protected static String condensePackageString(String classname)
346 {
347 String parts[] = classname.split("\\.");
348 StringBuilder dense = new StringBuilder();
349 for (int i = 0; i < (parts.length - 1); i++)
350 {
351 dense.append(parts[i].charAt(0));
352 }
353 if (dense.length() > 0)
354 {
355 dense.append('.');
356 }
357 dense.append(parts[parts.length - 1]);
358 return dense.toString();
359 }
360
361 public String getName()
362 {
363 return _name;
364 }
365
366 public void setPrintLongNames(boolean printLongNames)
367 {
368 this._printLongNames = printLongNames;
369 }
370
371 public boolean isPrintLongNames()
372 {
373 return this._printLongNames;
374 }
375
376 public boolean isHideStacks()
377 {
378 return _hideStacks;
379 }
380
381 public void setHideStacks(boolean hideStacks)
382 {
383 _hideStacks = hideStacks;
384 }
385
386
387
388
389
390
391
392 public boolean isSource()
393 {
394 return _source;
395 }
396
397
398
399
400
401
402
403
404 public void setSource(boolean source)
405 {
406 _source = source;
407 }
408
409 public void warn(String msg, Object... args)
410 {
411 if (_level <= LEVEL_WARN)
412 {
413 StringBuilder buffer = new StringBuilder(64);
414 format(buffer,":WARN:",msg,args);
415 (_stderr==null?System.err:_stderr).println(buffer);
416 }
417 }
418
419 public void warn(Throwable thrown)
420 {
421 warn("",thrown);
422 }
423
424 public void warn(String msg, Throwable thrown)
425 {
426 if (_level <= LEVEL_WARN)
427 {
428 StringBuilder buffer = new StringBuilder(64);
429 format(buffer,":WARN:",msg,thrown);
430 (_stderr==null?System.err:_stderr).println(buffer);
431 }
432 }
433
434 public void info(String msg, Object... args)
435 {
436 if (_level <= LEVEL_INFO)
437 {
438 StringBuilder buffer = new StringBuilder(64);
439 format(buffer,":INFO:",msg,args);
440 (_stderr==null?System.err:_stderr).println(buffer);
441 }
442 }
443
444 public void info(Throwable thrown)
445 {
446 info("",thrown);
447 }
448
449 public void info(String msg, Throwable thrown)
450 {
451 if (_level <= LEVEL_INFO)
452 {
453 StringBuilder buffer = new StringBuilder(64);
454 format(buffer,":INFO:",msg,thrown);
455 (_stderr==null?System.err:_stderr).println(buffer);
456 }
457 }
458
459 @ManagedAttribute("is debug enabled for root logger Log.LOG")
460 public boolean isDebugEnabled()
461 {
462 return (_level <= LEVEL_DEBUG);
463 }
464
465
466
467
468
469 @Override
470 public void setDebugEnabled(boolean enabled)
471 {
472 if (enabled)
473 {
474 this._level = LEVEL_DEBUG;
475
476 for (Logger log : Log.getLoggers().values())
477 {
478 if (log.getName().startsWith(getName()) && log instanceof StdErrLog)
479 ((StdErrLog)log).setLevel(LEVEL_DEBUG);
480 }
481 }
482 else
483 {
484 this._level = this._configuredLevel;
485
486 for (Logger log : Log.getLoggers().values())
487 {
488 if (log.getName().startsWith(getName()) && log instanceof StdErrLog)
489 ((StdErrLog)log).setLevel(((StdErrLog)log)._configuredLevel);
490 }
491 }
492 }
493
494 public int getLevel()
495 {
496 return _level;
497 }
498
499
500
501
502
503
504
505
506
507
508 public void setLevel(int level)
509 {
510 this._level = level;
511 }
512
513 public void setStdErrStream(PrintStream stream)
514 {
515 this._stderr = stream==System.err?null:stream;
516 }
517
518 public void debug(String msg, Object... args)
519 {
520 if (_level <= LEVEL_DEBUG)
521 {
522 StringBuilder buffer = new StringBuilder(64);
523 format(buffer,":DBUG:",msg,args);
524 (_stderr==null?System.err:_stderr).println(buffer);
525 }
526 }
527
528 public void debug(String msg, long arg)
529 {
530 if (isDebugEnabled())
531 {
532 StringBuilder buffer = new StringBuilder(64);
533 format(buffer,":DBUG:",msg,arg);
534 (_stderr==null?System.err:_stderr).println(buffer);
535 }
536 }
537
538 public void debug(Throwable thrown)
539 {
540 debug("",thrown);
541 }
542
543 public void debug(String msg, Throwable thrown)
544 {
545 if (_level <= LEVEL_DEBUG)
546 {
547 StringBuilder buffer = new StringBuilder(64);
548 format(buffer,":DBUG:",msg,thrown);
549 (_stderr==null?System.err:_stderr).println(buffer);
550 }
551 }
552
553 private void format(StringBuilder buffer, String level, String msg, Object... args)
554 {
555 long now = System.currentTimeMillis();
556 int ms=(int)(now%1000);
557 String d = _dateCache.formatNow(now);
558 tag(buffer,d,ms,level);
559 format(buffer,msg,args);
560 }
561
562 private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
563 {
564 format(buffer,level,msg);
565 if (isHideStacks())
566 {
567 format(buffer,": "+String.valueOf(thrown));
568 }
569 else
570 {
571 format(buffer,thrown);
572 }
573 }
574
575 private void tag(StringBuilder buffer, String d, int ms, String tag)
576 {
577 buffer.setLength(0);
578 buffer.append(d);
579 if (ms > 99)
580 {
581 buffer.append('.');
582 }
583 else if (ms > 9)
584 {
585 buffer.append(".0");
586 }
587 else
588 {
589 buffer.append(".00");
590 }
591 buffer.append(ms).append(tag);
592 if (_printLongNames)
593 {
594 buffer.append(_name);
595 }
596 else
597 {
598 buffer.append(_abbrevname);
599 }
600 buffer.append(':');
601 buffer.append(Thread.currentThread().getName()).append(": ");
602 if (_source)
603 {
604 Throwable source = new Throwable();
605 StackTraceElement[] frames = source.getStackTrace();
606 for (int i = 0; i < frames.length; i++)
607 {
608 final StackTraceElement frame = frames[i];
609 String clazz = frame.getClassName();
610 if (clazz.equals(StdErrLog.class.getName()) || clazz.equals(Log.class.getName()))
611 {
612 continue;
613 }
614 if (!_printLongNames && clazz.startsWith("org.eclipse.jetty."))
615 {
616 buffer.append(condensePackageString(clazz));
617 }
618 else
619 {
620 buffer.append(clazz);
621 }
622 buffer.append('#').append(frame.getMethodName());
623 if (frame.getFileName() != null)
624 {
625 buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
626 }
627 buffer.append(':');
628 break;
629 }
630 }
631 }
632
633 private void format(StringBuilder builder, String msg, Object... args)
634 {
635 if (msg == null)
636 {
637 msg = "";
638 for (int i = 0; i < args.length; i++)
639 {
640 msg += "{} ";
641 }
642 }
643 String braces = "{}";
644 int start = 0;
645 for (Object arg : args)
646 {
647 int bracesIndex = msg.indexOf(braces,start);
648 if (bracesIndex < 0)
649 {
650 escape(builder,msg.substring(start));
651 builder.append(" ");
652 builder.append(arg);
653 start = msg.length();
654 }
655 else
656 {
657 escape(builder,msg.substring(start,bracesIndex));
658 builder.append(String.valueOf(arg));
659 start = bracesIndex + braces.length();
660 }
661 }
662 escape(builder,msg.substring(start));
663 }
664
665 private void escape(StringBuilder builder, String string)
666 {
667 if (__escape)
668 {
669 for (int i = 0; i < string.length(); ++i)
670 {
671 char c = string.charAt(i);
672 if (Character.isISOControl(c))
673 {
674 if (c == '\n')
675 {
676 builder.append('|');
677 }
678 else if (c == '\r')
679 {
680 builder.append('<');
681 }
682 else
683 {
684 builder.append('?');
685 }
686 }
687 else
688 {
689 builder.append(c);
690 }
691 }
692 }
693 else
694 builder.append(string);
695 }
696
697 private void format(StringBuilder buffer, Throwable thrown)
698 {
699 if (thrown == null)
700 {
701 buffer.append("null");
702 }
703 else
704 {
705 buffer.append(EOL);
706 format(buffer,thrown.toString());
707 StackTraceElement[] elements = thrown.getStackTrace();
708 for (int i = 0; elements != null && i < elements.length; i++)
709 {
710 buffer.append(EOL).append("\tat ");
711 format(buffer,elements[i].toString());
712 }
713
714 Throwable cause = thrown.getCause();
715 if (cause != null && cause != thrown)
716 {
717 buffer.append(EOL).append("Caused by: ");
718 format(buffer,cause);
719 }
720 }
721 }
722
723
724
725
726
727 @Override
728 protected Logger newLogger(String fullname)
729 {
730 StdErrLog logger = new StdErrLog(fullname);
731
732 logger.setPrintLongNames(_printLongNames);
733 logger._stderr = this._stderr;
734
735
736 if (_level!=_configuredLevel)
737 logger._level=_level;
738
739 return logger;
740 }
741
742 @Override
743 public String toString()
744 {
745 StringBuilder s = new StringBuilder();
746 s.append("StdErrLog:");
747 s.append(_name);
748 s.append(":LEVEL=");
749 switch (_level)
750 {
751 case LEVEL_ALL:
752 s.append("ALL");
753 break;
754 case LEVEL_DEBUG:
755 s.append("DEBUG");
756 break;
757 case LEVEL_INFO:
758 s.append("INFO");
759 break;
760 case LEVEL_WARN:
761 s.append("WARN");
762 break;
763 default:
764 s.append("?");
765 break;
766 }
767 return s.toString();
768 }
769
770 public static void setProperties(Properties props)
771 {
772 __props.clear();
773 __props.putAll(props);
774 }
775
776 public void ignore(Throwable ignored)
777 {
778 if (_level <= LEVEL_ALL)
779 {
780 StringBuilder buffer = new StringBuilder(64);
781 format(buffer,":IGNORED:","",ignored);
782 (_stderr==null?System.err:_stderr).println(buffer);
783 }
784 }
785 }