1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.util.log;
15
16 import java.io.PrintStream;
17 import java.security.AccessControlException;
18 import java.util.Properties;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap;
21
22 import org.eclipse.jetty.util.DateCache;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public class StdErrLog implements Logger
39 {
40 private static DateCache _dateCache;
41
42 private final static boolean __source = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.SOURCE",
43 System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
44 private final static boolean __long = Boolean.parseBoolean(System.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
45
46 private final static ConcurrentMap<String, StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
47
48 static
49 {
50 String deprecatedProperites[] =
51 { "DEBUG", "org.eclipse.jetty.util.log.DEBUG", "org.eclipse.jetty.util.log.stderr.DEBUG" };
52
53
54 for (String deprecatedProp : deprecatedProperites)
55 {
56 if (System.getProperty(deprecatedProp) != null)
57 {
58 System.err.printf("System Property [%s] has been deprecated! (Use org.eclipse.jetty.LEVEL=DEBUG instead)%n",deprecatedProp);
59 }
60 }
61
62 try
63 {
64 _dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
65 }
66 catch (Exception x)
67 {
68 x.printStackTrace(System.err);
69 }
70 }
71
72 public static final int LEVEL_ALL = 0;
73 public static final int LEVEL_DEBUG = 1;
74 public static final int LEVEL_INFO = 2;
75 public static final int LEVEL_WARN = 3;
76
77 private int _level = LEVEL_INFO;
78 private PrintStream _stderr = System.err;
79 private boolean _source = __source;
80
81 private boolean _printLongNames = __long;
82
83 private final String _name;
84
85 private final String _abbrevname;
86 private boolean _hideStacks = false;
87
88 public StdErrLog()
89 {
90 this(null);
91 }
92
93 public StdErrLog(String name)
94 {
95 this._name = name == null?"":name;
96 this._abbrevname = condensePackageString(this._name);
97 this._level = getLoggingLevel(System.getProperties(),this._name);
98
99 try
100 {
101 _source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE",Boolean.toString(_source)));
102 }
103 catch (AccessControlException ace)
104 {
105 _source = __source;
106 }
107 }
108
109
110
111
112
113
114
115
116
117
118
119 public static int getLoggingLevel(Properties props, final String name)
120 {
121
122
123 String nameSegment = name;
124
125 while ((nameSegment != null) && (nameSegment.length() > 0))
126 {
127 String levelStr = props.getProperty(nameSegment + ".LEVEL");
128
129 if (levelStr == null)
130 {
131
132 int idx = nameSegment.lastIndexOf('.');
133 if (idx >= 0)
134 {
135 nameSegment = nameSegment.substring(0,idx);
136 }
137 else
138 {
139 nameSegment = null;
140 }
141 }
142 else
143 {
144 if ("ALL".equalsIgnoreCase(levelStr.trim()))
145 {
146 return LEVEL_ALL;
147 }
148 else if ("DEBUG".equalsIgnoreCase(levelStr.trim()))
149 {
150 return LEVEL_DEBUG;
151 }
152 else if ("INFO".equalsIgnoreCase(levelStr.trim()))
153 {
154 return LEVEL_INFO;
155 }
156 else if ("WARN".equalsIgnoreCase(levelStr.trim()))
157 {
158 return LEVEL_WARN;
159 }
160 }
161 }
162
163
164 return LEVEL_INFO;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 protected static String condensePackageString(String classname)
183 {
184 String parts[] = classname.split("\\.");
185 StringBuilder dense = new StringBuilder();
186 for (int i = 0; i < (parts.length - 1); i++)
187 {
188 dense.append(parts[i].charAt(0));
189 }
190 if (dense.length() > 0)
191 {
192 dense.append('.');
193 }
194 dense.append(parts[parts.length - 1]);
195 return dense.toString();
196 }
197
198 public String getName()
199 {
200 return _name;
201 }
202
203 public void setPrintLongNames(boolean printLongNames)
204 {
205 this._printLongNames = printLongNames;
206 }
207
208 public boolean isPrintLongNames()
209 {
210 return this._printLongNames;
211 }
212
213 public boolean isHideStacks()
214 {
215 return _hideStacks;
216 }
217
218 public void setHideStacks(boolean hideStacks)
219 {
220 _hideStacks = hideStacks;
221 }
222
223
224
225
226
227
228
229 public boolean isSource()
230 {
231 return _source;
232 }
233
234
235
236
237
238
239
240
241 public void setSource(boolean source)
242 {
243 _source = source;
244 }
245
246 public void warn(String msg, Object... args)
247 {
248 if (_level <= LEVEL_WARN)
249 {
250 StringBuilder buffer = new StringBuilder(64);
251 format(buffer,":WARN:",msg,args);
252 _stderr.println(buffer);
253 }
254 }
255
256 public void warn(Throwable thrown)
257 {
258 warn("",thrown);
259 }
260
261 public void warn(String msg, Throwable thrown)
262 {
263 if (_level <= LEVEL_WARN)
264 {
265 StringBuilder buffer = new StringBuilder(64);
266 format(buffer,":WARN:",msg,thrown);
267 _stderr.println(buffer);
268 }
269 }
270
271 public void info(String msg, Object... args)
272 {
273 if (_level <= LEVEL_INFO)
274 {
275 StringBuilder buffer = new StringBuilder(64);
276 format(buffer,":INFO:",msg,args);
277 _stderr.println(buffer);
278 }
279 }
280
281 public void info(Throwable thrown)
282 {
283 info("",thrown);
284 }
285
286 public void info(String msg, Throwable thrown)
287 {
288 if (_level <= LEVEL_INFO)
289 {
290 StringBuilder buffer = new StringBuilder(64);
291 format(buffer,":INFO:",msg,thrown);
292 _stderr.println(buffer);
293 }
294 }
295
296 public boolean isDebugEnabled()
297 {
298 return (_level >= LEVEL_DEBUG);
299 }
300
301
302
303
304 @Deprecated
305 public void setDebugEnabled(boolean enabled)
306 {
307 if (enabled)
308 {
309 _level = LEVEL_DEBUG;
310 }
311 else
312 {
313 _level = LEVEL_INFO;
314 }
315 }
316
317 public int getLevel()
318 {
319 return _level;
320 }
321
322
323
324
325
326
327
328
329
330
331 public void setLevel(int level)
332 {
333 this._level = level;
334 }
335
336 public void setStdErrStream(PrintStream stream)
337 {
338 this._stderr = stream;
339 }
340
341 public void debug(String msg, Object... args)
342 {
343 if (_level <= LEVEL_DEBUG)
344 {
345 StringBuilder buffer = new StringBuilder(64);
346 format(buffer,":DBUG:",msg,args);
347 _stderr.println(buffer);
348 }
349 }
350
351 public void debug(Throwable thrown)
352 {
353 debug("",thrown);
354 }
355
356 public void debug(String msg, Throwable thrown)
357 {
358 if (_level <= LEVEL_DEBUG)
359 {
360 StringBuilder buffer = new StringBuilder(64);
361 format(buffer,":DBUG:",msg,thrown);
362 _stderr.println(buffer);
363 }
364 }
365
366 private void format(StringBuilder buffer, String level, String msg, Object... args)
367 {
368 String d = _dateCache.now();
369 int ms = _dateCache.lastMs();
370 tag(buffer,d,ms,level);
371 format(buffer,msg,args);
372 }
373
374 private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
375 {
376 format(buffer,level,msg);
377 if (isHideStacks())
378 {
379 format(buffer,String.valueOf(thrown));
380 }
381 else
382 {
383 format(buffer,thrown);
384 }
385 }
386
387 private void tag(StringBuilder buffer, String d, int ms, String tag)
388 {
389 buffer.setLength(0);
390 buffer.append(d);
391 if (ms > 99)
392 {
393 buffer.append('.');
394 }
395 else if (ms > 9)
396 {
397 buffer.append(".0");
398 }
399 else
400 {
401 buffer.append(".00");
402 }
403 buffer.append(ms).append(tag);
404 if (_printLongNames)
405 {
406 buffer.append(_name);
407 }
408 else
409 {
410 buffer.append(_abbrevname);
411 }
412 buffer.append(':');
413 if (_source)
414 {
415 Throwable source = new Throwable();
416 StackTraceElement[] frames = source.getStackTrace();
417 for (int i = 0; i < frames.length; i++)
418 {
419 final StackTraceElement frame = frames[i];
420 String clazz = frame.getClassName();
421 if (clazz.equals(StdErrLog.class.getName()) || clazz.equals(Log.class.getName()))
422 {
423 continue;
424 }
425 if (!_printLongNames && clazz.startsWith("org.eclipse.jetty."))
426 {
427 buffer.append(condensePackageString(clazz));
428 }
429 else
430 {
431 buffer.append(clazz);
432 }
433 buffer.append('#').append(frame.getMethodName());
434 if (frame.getFileName() != null)
435 {
436 buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
437 }
438 buffer.append(':');
439 break;
440 }
441 }
442 }
443
444 private void format(StringBuilder builder, String msg, Object... args)
445 {
446 if (msg == null)
447 {
448 msg = "";
449 for (int i = 0; i < args.length; i++)
450 {
451 msg += "{} ";
452 }
453 }
454 String braces = "{}";
455 int start = 0;
456 for (Object arg : args)
457 {
458 int bracesIndex = msg.indexOf(braces,start);
459 if (bracesIndex < 0)
460 {
461 escape(builder,msg.substring(start));
462 builder.append(" ");
463 builder.append(arg);
464 start = msg.length();
465 }
466 else
467 {
468 escape(builder,msg.substring(start,bracesIndex));
469 builder.append(String.valueOf(arg));
470 start = bracesIndex + braces.length();
471 }
472 }
473 escape(builder,msg.substring(start));
474 }
475
476 private void escape(StringBuilder builder, String string)
477 {
478 for (int i = 0; i < string.length(); ++i)
479 {
480 char c = string.charAt(i);
481 if (Character.isISOControl(c))
482 {
483 if (c == '\n')
484 {
485 builder.append('|');
486 }
487 else if (c == '\r')
488 {
489 builder.append('<');
490 }
491 else
492 {
493 builder.append('?');
494 }
495 }
496 else
497 {
498 builder.append(c);
499 }
500 }
501 }
502
503 private void format(StringBuilder buffer, Throwable thrown)
504 {
505 if (thrown == null)
506 {
507 buffer.append("null");
508 }
509 else
510 {
511 buffer.append('\n');
512 format(buffer,thrown.toString());
513 StackTraceElement[] elements = thrown.getStackTrace();
514 for (int i = 0; elements != null && i < elements.length; i++)
515 {
516 buffer.append("\n\tat ");
517 format(buffer,elements[i].toString());
518 }
519
520 Throwable cause = thrown.getCause();
521 if (cause != null && cause != thrown)
522 {
523 buffer.append("\nCaused by: ");
524 format(buffer,cause);
525 }
526 }
527 }
528
529 public Logger getLogger(String name)
530 {
531 String fullname = _name == null || _name.length() == 0?name:_name + "." + name;
532
533 if ((name == null && this._name == null) || fullname.equals(_name))
534 {
535 return this;
536 }
537
538 StdErrLog logger = __loggers.get(name);
539 if (logger == null)
540 {
541 StdErrLog sel = new StdErrLog(fullname);
542
543 sel.setPrintLongNames(_printLongNames);
544 sel.setLevel(_level);
545 sel.setSource(_source);
546 logger = __loggers.putIfAbsent(fullname,sel);
547 if (logger == null)
548 {
549 logger = sel;
550 }
551 }
552
553 return logger;
554 }
555
556 @Override
557 public String toString()
558 {
559 StringBuilder s = new StringBuilder();
560 s.append("StdErrLog:");
561 s.append(_name);
562 s.append(":LEVEL=");
563 switch (_level)
564 {
565 case LEVEL_ALL:
566 s.append("ALL");
567 break;
568 case LEVEL_DEBUG:
569 s.append("DEBUG");
570 break;
571 case LEVEL_INFO:
572 s.append("INFO");
573 break;
574 case LEVEL_WARN:
575 s.append("WARN");
576 break;
577 default:
578 s.append("?");
579 break;
580 }
581 return s.toString();
582 }
583
584 public void ignore(Throwable ignored)
585 {
586 if (_level <= LEVEL_ALL)
587 {
588 StringBuilder buffer = new StringBuilder(64);
589 format(buffer,":IGNORED:","",ignored);
590 _stderr.println(buffer);
591 }
592 }
593 }