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
243
244 String nameSegment = name;
245
246 while ((nameSegment != null) && (nameSegment.length() > 0))
247 {
248 String levelStr = props.getProperty(nameSegment + ".LEVEL");
249
250 int level = getLevelId(nameSegment + ".LEVEL",levelStr);
251 if (level != (-1))
252 {
253 return level;
254 }
255
256
257 int idx = nameSegment.lastIndexOf('.');
258 if (idx >= 0)
259 {
260 nameSegment = nameSegment.substring(0,idx);
261 }
262 else
263 {
264 nameSegment = null;
265 }
266 }
267
268
269 return getLevelId("log.LEVEL",props.getProperty("log.LEVEL","INFO"));
270 }
271
272 public static String getLoggingProperty(Properties props, String name, String property)
273 {
274
275
276 String nameSegment = name;
277
278 while ((nameSegment != null) && (nameSegment.length() > 0))
279 {
280 String s = props.getProperty(nameSegment+"."+property);
281 if (s!=null)
282 return s;
283
284
285 int idx = nameSegment.lastIndexOf('.');
286 nameSegment = (idx >= 0)?nameSegment.substring(0,idx):null;
287 }
288
289 return null;
290 }
291
292 protected static int getLevelId(String levelSegment, String levelName)
293 {
294 if (levelName == null)
295 {
296 return -1;
297 }
298 String levelStr = levelName.trim();
299 if ("ALL".equalsIgnoreCase(levelStr))
300 {
301 return LEVEL_ALL;
302 }
303 else if ("DEBUG".equalsIgnoreCase(levelStr))
304 {
305 return LEVEL_DEBUG;
306 }
307 else if ("INFO".equalsIgnoreCase(levelStr))
308 {
309 return LEVEL_INFO;
310 }
311 else if ("WARN".equalsIgnoreCase(levelStr))
312 {
313 return LEVEL_WARN;
314 }
315 else if ("OFF".equalsIgnoreCase(levelStr))
316 {
317 return LEVEL_OFF;
318 }
319
320 System.err.println("Unknown StdErrLog level [" + levelSegment + "]=[" + levelStr + "], expecting only [ALL, DEBUG, INFO, WARN, OFF] as values.");
321 return -1;
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339 protected static String condensePackageString(String classname)
340 {
341 String parts[] = classname.split("\\.");
342 StringBuilder dense = new StringBuilder();
343 for (int i = 0; i < (parts.length - 1); i++)
344 {
345 dense.append(parts[i].charAt(0));
346 }
347 if (dense.length() > 0)
348 {
349 dense.append('.');
350 }
351 dense.append(parts[parts.length - 1]);
352 return dense.toString();
353 }
354
355 public String getName()
356 {
357 return _name;
358 }
359
360 public void setPrintLongNames(boolean printLongNames)
361 {
362 this._printLongNames = printLongNames;
363 }
364
365 public boolean isPrintLongNames()
366 {
367 return this._printLongNames;
368 }
369
370 public boolean isHideStacks()
371 {
372 return _hideStacks;
373 }
374
375 public void setHideStacks(boolean hideStacks)
376 {
377 _hideStacks = hideStacks;
378 }
379
380
381
382
383
384
385
386 public boolean isSource()
387 {
388 return _source;
389 }
390
391
392
393
394
395
396
397
398 public void setSource(boolean source)
399 {
400 _source = source;
401 }
402
403 public void warn(String msg, Object... args)
404 {
405 if (_level <= LEVEL_WARN)
406 {
407 StringBuilder buffer = new StringBuilder(64);
408 format(buffer,":WARN:",msg,args);
409 (_stderr==null?System.err:_stderr).println(buffer);
410 }
411 }
412
413 public void warn(Throwable thrown)
414 {
415 warn("",thrown);
416 }
417
418 public void warn(String msg, Throwable thrown)
419 {
420 if (_level <= LEVEL_WARN)
421 {
422 StringBuilder buffer = new StringBuilder(64);
423 format(buffer,":WARN:",msg,thrown);
424 (_stderr==null?System.err:_stderr).println(buffer);
425 }
426 }
427
428 public void info(String msg, Object... args)
429 {
430 if (_level <= LEVEL_INFO)
431 {
432 StringBuilder buffer = new StringBuilder(64);
433 format(buffer,":INFO:",msg,args);
434 (_stderr==null?System.err:_stderr).println(buffer);
435 }
436 }
437
438 public void info(Throwable thrown)
439 {
440 info("",thrown);
441 }
442
443 public void info(String msg, Throwable thrown)
444 {
445 if (_level <= LEVEL_INFO)
446 {
447 StringBuilder buffer = new StringBuilder(64);
448 format(buffer,":INFO:",msg,thrown);
449 (_stderr==null?System.err:_stderr).println(buffer);
450 }
451 }
452
453 @ManagedAttribute("is debug enabled for root logger Log.LOG")
454 public boolean isDebugEnabled()
455 {
456 return (_level <= LEVEL_DEBUG);
457 }
458
459
460
461
462
463 @Override
464 public void setDebugEnabled(boolean enabled)
465 {
466 if (enabled)
467 {
468 this._level = LEVEL_DEBUG;
469
470 for (Logger log : Log.getLoggers().values())
471 {
472 if (log.getName().startsWith(getName()) && log instanceof StdErrLog)
473 ((StdErrLog)log).setLevel(LEVEL_DEBUG);
474 }
475 }
476 else
477 {
478 this._level = this._configuredLevel;
479
480 for (Logger log : Log.getLoggers().values())
481 {
482 if (log.getName().startsWith(getName()) && log instanceof StdErrLog)
483 ((StdErrLog)log).setLevel(((StdErrLog)log)._configuredLevel);
484 }
485 }
486 }
487
488 public int getLevel()
489 {
490 return _level;
491 }
492
493
494
495
496
497
498
499
500
501
502 public void setLevel(int level)
503 {
504 this._level = level;
505 }
506
507 public void setStdErrStream(PrintStream stream)
508 {
509 this._stderr = stream==System.err?null:stream;
510 }
511
512 public void debug(String msg, Object... args)
513 {
514 if (_level <= LEVEL_DEBUG)
515 {
516 StringBuilder buffer = new StringBuilder(64);
517 format(buffer,":DBUG:",msg,args);
518 (_stderr==null?System.err:_stderr).println(buffer);
519 }
520 }
521
522 public void debug(String msg, long arg)
523 {
524 if (isDebugEnabled())
525 {
526 StringBuilder buffer = new StringBuilder(64);
527 format(buffer,":DBUG:",msg,arg);
528 (_stderr==null?System.err:_stderr).println(buffer);
529 }
530 }
531
532 public void debug(Throwable thrown)
533 {
534 debug("",thrown);
535 }
536
537 public void debug(String msg, Throwable thrown)
538 {
539 if (_level <= LEVEL_DEBUG)
540 {
541 StringBuilder buffer = new StringBuilder(64);
542 format(buffer,":DBUG:",msg,thrown);
543 (_stderr==null?System.err:_stderr).println(buffer);
544 }
545 }
546
547 private void format(StringBuilder buffer, String level, String msg, Object... args)
548 {
549 long now = System.currentTimeMillis();
550 int ms=(int)(now%1000);
551 String d = _dateCache.formatNow(now);
552 tag(buffer,d,ms,level);
553 format(buffer,msg,args);
554 }
555
556 private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
557 {
558 format(buffer,level,msg);
559 if (isHideStacks())
560 {
561 format(buffer,": "+String.valueOf(thrown));
562 }
563 else
564 {
565 format(buffer,thrown);
566 }
567 }
568
569 private void tag(StringBuilder buffer, String d, int ms, String tag)
570 {
571 buffer.setLength(0);
572 buffer.append(d);
573 if (ms > 99)
574 {
575 buffer.append('.');
576 }
577 else if (ms > 9)
578 {
579 buffer.append(".0");
580 }
581 else
582 {
583 buffer.append(".00");
584 }
585 buffer.append(ms).append(tag);
586 if (_printLongNames)
587 {
588 buffer.append(_name);
589 }
590 else
591 {
592 buffer.append(_abbrevname);
593 }
594 buffer.append(':');
595 buffer.append(Thread.currentThread().getName()).append(": ");
596 if (_source)
597 {
598 Throwable source = new Throwable();
599 StackTraceElement[] frames = source.getStackTrace();
600 for (int i = 0; i < frames.length; i++)
601 {
602 final StackTraceElement frame = frames[i];
603 String clazz = frame.getClassName();
604 if (clazz.equals(StdErrLog.class.getName()) || clazz.equals(Log.class.getName()))
605 {
606 continue;
607 }
608 if (!_printLongNames && clazz.startsWith("org.eclipse.jetty."))
609 {
610 buffer.append(condensePackageString(clazz));
611 }
612 else
613 {
614 buffer.append(clazz);
615 }
616 buffer.append('#').append(frame.getMethodName());
617 if (frame.getFileName() != null)
618 {
619 buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
620 }
621 buffer.append(':');
622 break;
623 }
624 }
625 }
626
627 private void format(StringBuilder builder, String msg, Object... args)
628 {
629 if (msg == null)
630 {
631 msg = "";
632 for (int i = 0; i < args.length; i++)
633 {
634 msg += "{} ";
635 }
636 }
637 String braces = "{}";
638 int start = 0;
639 for (Object arg : args)
640 {
641 int bracesIndex = msg.indexOf(braces,start);
642 if (bracesIndex < 0)
643 {
644 escape(builder,msg.substring(start));
645 builder.append(" ");
646 builder.append(arg);
647 start = msg.length();
648 }
649 else
650 {
651 escape(builder,msg.substring(start,bracesIndex));
652 builder.append(String.valueOf(arg));
653 start = bracesIndex + braces.length();
654 }
655 }
656 escape(builder,msg.substring(start));
657 }
658
659 private void escape(StringBuilder builder, String string)
660 {
661 if (__escape)
662 {
663 for (int i = 0; i < string.length(); ++i)
664 {
665 char c = string.charAt(i);
666 if (Character.isISOControl(c))
667 {
668 if (c == '\n')
669 {
670 builder.append('|');
671 }
672 else if (c == '\r')
673 {
674 builder.append('<');
675 }
676 else
677 {
678 builder.append('?');
679 }
680 }
681 else
682 {
683 builder.append(c);
684 }
685 }
686 }
687 else
688 builder.append(string);
689 }
690
691 private void format(StringBuilder buffer, Throwable thrown)
692 {
693 if (thrown == null)
694 {
695 buffer.append("null");
696 }
697 else
698 {
699 buffer.append(EOL);
700 format(buffer,thrown.toString());
701 StackTraceElement[] elements = thrown.getStackTrace();
702 for (int i = 0; elements != null && i < elements.length; i++)
703 {
704 buffer.append(EOL).append("\tat ");
705 format(buffer,elements[i].toString());
706 }
707
708 Throwable cause = thrown.getCause();
709 if (cause != null && cause != thrown)
710 {
711 buffer.append(EOL).append("Caused by: ");
712 format(buffer,cause);
713 }
714 }
715 }
716
717
718
719
720
721 @Override
722 protected Logger newLogger(String fullname)
723 {
724 StdErrLog logger = new StdErrLog(fullname);
725
726 logger.setPrintLongNames(_printLongNames);
727 logger._stderr = this._stderr;
728
729
730 if (_level!=_configuredLevel)
731 logger._level=_level;
732
733 return logger;
734 }
735
736 @Override
737 public String toString()
738 {
739 StringBuilder s = new StringBuilder();
740 s.append("StdErrLog:");
741 s.append(_name);
742 s.append(":LEVEL=");
743 switch (_level)
744 {
745 case LEVEL_ALL:
746 s.append("ALL");
747 break;
748 case LEVEL_DEBUG:
749 s.append("DEBUG");
750 break;
751 case LEVEL_INFO:
752 s.append("INFO");
753 break;
754 case LEVEL_WARN:
755 s.append("WARN");
756 break;
757 default:
758 s.append("?");
759 break;
760 }
761 return s.toString();
762 }
763
764 public static void setProperties(Properties props)
765 {
766 __props.clear();
767 __props.putAll(props);
768 }
769
770 public void ignore(Throwable ignored)
771 {
772 if (_level <= LEVEL_ALL)
773 {
774 StringBuilder buffer = new StringBuilder(64);
775 format(buffer,":IGNORED:","",ignored);
776 (_stderr==null?System.err:_stderr).println(buffer);
777 }
778 }
779 }