1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.util.log;
15
16 import java.security.AccessControlException;
17 import java.util.concurrent.ConcurrentHashMap;
18 import java.util.concurrent.ConcurrentMap;
19
20 import org.eclipse.jetty.util.DateCache;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class StdErrLog implements Logger
42 {
43 private static DateCache _dateCache;
44
45 private final static boolean __debug = Boolean.parseBoolean(
46 System.getProperty("org.eclipse.jetty.util.log.DEBUG",
47 System.getProperty("org.eclipse.jetty.util.log.stderr.DEBUG", "false")));
48 private final static boolean __source = Boolean.parseBoolean(
49 System.getProperty("org.eclipse.jetty.util.log.SOURCE",
50 System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE", "false")));
51 private final static boolean __long = Boolean.parseBoolean(
52 System.getProperty("org.eclipse.jetty.util.log.stderr.LONG", "false"));
53
54 private final static ConcurrentMap<String,StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
55
56 static
57 {
58 try
59 {
60 _dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
61 }
62 catch (Exception x)
63 {
64 x.printStackTrace();
65 }
66 }
67
68 private boolean _debug = __debug;
69 private boolean _source = __source;
70
71 private boolean _printLongNames = __long;
72
73 private final String _name;
74
75 private final String _abbrevname;
76 private boolean _hideStacks = false;
77
78 public StdErrLog()
79 {
80 this(null);
81 }
82
83 public StdErrLog(String name)
84 {
85 this._name = name == null ? "" : name;
86 this._abbrevname = condensePackageString(this._name);
87
88 try
89 {
90 _debug = Boolean.parseBoolean(System.getProperty(_name + ".DEBUG", Boolean.toString(_debug)));
91 }
92 catch (AccessControlException ace)
93 {
94 _debug = __debug;
95 }
96
97 try
98 {
99 _source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE", Boolean.toString(_source)));
100 }
101 catch (AccessControlException ace)
102 {
103 _source = __source;
104 }
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 protected static String condensePackageString(String classname)
123 {
124 String parts[] = classname.split("\\.");
125 StringBuilder dense = new StringBuilder();
126 for (int i = 0; i < (parts.length - 1); i++)
127 {
128 dense.append(parts[i].charAt(0));
129 }
130 if (dense.length() > 0)
131 {
132 dense.append('.');
133 }
134 dense.append(parts[parts.length - 1]);
135 return dense.toString();
136 }
137
138 public String getName()
139 {
140 return _name;
141 }
142
143 public void setPrintLongNames(boolean printLongNames)
144 {
145 this._printLongNames = printLongNames;
146 }
147
148 public boolean isPrintLongNames()
149 {
150 return this._printLongNames;
151 }
152
153 public boolean isHideStacks()
154 {
155 return _hideStacks;
156 }
157
158 public void setHideStacks(boolean hideStacks)
159 {
160 _hideStacks = hideStacks;
161 }
162
163
164
165
166
167 public boolean isSource()
168 {
169 return _source;
170 }
171
172
173
174
175
176 public void setSource(boolean source)
177 {
178 _source = source;
179 }
180
181 public void warn(String msg, Object... args)
182 {
183 StringBuilder buffer = new StringBuilder(64);
184 format(buffer, ":WARN:", msg, args);
185 System.err.println(buffer);
186 }
187
188 public void warn(Throwable thrown)
189 {
190 warn("", thrown);
191 }
192
193 public void warn(String msg, Throwable thrown)
194 {
195 StringBuilder buffer = new StringBuilder(64);
196 format(buffer, ":WARN:", msg, thrown);
197 System.err.println(buffer);
198 }
199
200 public void info(String msg, Object... args)
201 {
202 StringBuilder buffer = new StringBuilder(64);
203 format(buffer, ":INFO:", msg, args);
204 System.err.println(buffer);
205 }
206
207 public void info(Throwable thrown)
208 {
209 info("", thrown);
210 }
211
212 public void info(String msg, Throwable thrown)
213 {
214 StringBuilder buffer = new StringBuilder(64);
215 format(buffer, ":INFO:", msg, thrown);
216 System.err.println(buffer);
217 }
218
219 public boolean isDebugEnabled()
220 {
221 return _debug;
222 }
223
224 public void setDebugEnabled(boolean enabled)
225 {
226 _debug = enabled;
227 }
228
229 public void debug(String msg, Object... args)
230 {
231 if (!_debug)
232 return;
233 StringBuilder buffer = new StringBuilder(64);
234 format(buffer, ":DBUG:", msg, args);
235 System.err.println(buffer);
236 }
237
238 public void debug(Throwable thrown)
239 {
240 debug("", thrown);
241 }
242
243 public void debug(String msg, Throwable thrown)
244 {
245 if (!_debug)
246 return;
247 StringBuilder buffer = new StringBuilder(64);
248 format(buffer, ":DBUG:", msg, thrown);
249 System.err.println(buffer);
250 }
251
252 private void format(StringBuilder buffer, String level, String msg, Object... args)
253 {
254 String d = _dateCache.now();
255 int ms = _dateCache.lastMs();
256 tag(buffer, d, ms, level);
257 format(buffer, msg, args);
258 }
259
260 private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
261 {
262 format(buffer, level, msg);
263 if (isHideStacks())
264 format(buffer, String.valueOf(thrown));
265 else
266 format(buffer, thrown);
267 }
268
269 private void tag(StringBuilder buffer, String d, int ms, String tag)
270 {
271 buffer.setLength(0);
272 buffer.append(d);
273 if (ms > 99)
274 buffer.append('.');
275 else if (ms > 9)
276 buffer.append(".0");
277 else
278 buffer.append(".00");
279 buffer.append(ms).append(tag);
280 if(_printLongNames) {
281 buffer.append(_name);
282 } else {
283 buffer.append(_abbrevname);
284 }
285 buffer.append(':');
286 if (_source)
287 {
288 Throwable source = new Throwable();
289 StackTraceElement[] frames = source.getStackTrace();
290 for (int i=0;i<frames.length;i++)
291 {
292 final StackTraceElement frame = frames[i];
293 String clazz = frame.getClassName();
294 if (clazz.equals(StdErrLog.class.getName())|| clazz.equals(Log.class.getName()))
295 continue;
296 if (!_printLongNames && clazz.startsWith("org.eclipse.jetty.")) {
297 buffer.append(condensePackageString(clazz));
298 } else {
299 buffer.append(clazz);
300 }
301 buffer.append('#').append(frame.getMethodName());
302 if (frame.getFileName()!=null)
303 buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
304 buffer.append(':');
305 break;
306 }
307 }
308 }
309
310 private void format(StringBuilder builder, String msg, Object... args)
311 {
312 if (msg==null)
313 {
314 msg="";
315 for (Object o : args)
316 msg+="{} ";
317 }
318 String braces = "{}";
319 int start = 0;
320 for (Object arg : args)
321 {
322 int bracesIndex = msg.indexOf(braces, start);
323 if (bracesIndex < 0)
324 {
325 escape(builder, msg.substring(start));
326 builder.append(" ");
327 builder.append(arg);
328 start = msg.length();
329 }
330 else
331 {
332 escape(builder, msg.substring(start, bracesIndex));
333 builder.append(String.valueOf(arg));
334 start = bracesIndex + braces.length();
335 }
336 }
337 escape(builder, msg.substring(start));
338 }
339
340 private void escape(StringBuilder builder, String string)
341 {
342 for (int i = 0; i < string.length(); ++i)
343 {
344 char c = string.charAt(i);
345 if (Character.isISOControl(c))
346 {
347 if (c == '\n')
348 builder.append('|');
349 else if (c == '\r')
350 builder.append('<');
351 else
352 builder.append('?');
353 }
354 else
355 builder.append(c);
356 }
357 }
358
359 private void format(StringBuilder buffer, Throwable thrown)
360 {
361 if (thrown == null)
362 {
363 buffer.append("null");
364 }
365 else
366 {
367 buffer.append('\n');
368 format(buffer, thrown.toString());
369 StackTraceElement[] elements = thrown.getStackTrace();
370 for (int i = 0; elements != null && i < elements.length; i++)
371 {
372 buffer.append("\n\tat ");
373 format(buffer, elements[i].toString());
374 }
375
376 Throwable cause = thrown.getCause();
377 if (cause!=null && cause!=thrown)
378 {
379 buffer.append("\nCaused by: ");
380 format(buffer,cause);
381 }
382 }
383 }
384
385 public Logger getLogger(String name)
386 {
387 String fullname=_name == null || _name.length() == 0?name:_name + "." + name;
388
389 if ((name == null && this._name == null) || fullname.equals(_name))
390 return this;
391
392 StdErrLog logger = __loggers.get(name);
393 if (logger==null)
394 {
395 StdErrLog sel=new StdErrLog(fullname);
396
397 sel.setPrintLongNames(_printLongNames);
398 sel.setDebugEnabled(_debug);
399 sel.setSource(_source);
400 logger=__loggers.putIfAbsent(fullname,sel);
401 if (logger==null)
402 logger=sel;
403 }
404
405 return logger;
406 }
407
408 @Override
409 public String toString()
410 {
411 return "StdErrLog:" + _name + ":DEBUG=" + _debug;
412 }
413
414 public void ignore(Throwable ignored)
415 {
416 if (Log.isIgnored())
417 {
418 warn(Log.IGNORED, ignored);
419 }
420 else
421 {
422 debug("Ignored {}",ignored.toString());
423 }
424 }
425 }