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 public class StdErrLog implements Logger
38 {
39 private static DateCache _dateCache;
40
41 private final static boolean __debug = Boolean.parseBoolean(
42 System.getProperty("org.eclipse.jetty.util.log.DEBUG",
43 System.getProperty("org.eclipse.jetty.util.log.stderr.DEBUG", "false")));
44 private final static boolean __source = Boolean.parseBoolean(
45 System.getProperty("org.eclipse.jetty.util.log.SOURCE",
46 System.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE", "false")));
47
48 private final static ConcurrentMap<String,StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
49
50 static
51 {
52 try
53 {
54 _dateCache = new DateCache("yyyy-MM-dd HH:mm:ss");
55 }
56 catch (Exception x)
57 {
58 x.printStackTrace();
59 }
60 }
61
62 private boolean _debug = __debug;
63 private boolean _source = __source;
64 private final String _name;
65 private boolean _hideStacks = false;
66
67 public StdErrLog()
68 {
69 this(null);
70 }
71
72 public StdErrLog(String name)
73 {
74 this._name = name == null ? "" : name;
75
76 try
77 {
78 _debug = Boolean.parseBoolean(System.getProperty(_name + ".DEBUG", Boolean.toString(_debug)));
79 }
80 catch (AccessControlException ace)
81 {
82 _debug = __debug;
83 }
84
85 try
86 {
87 _source = Boolean.parseBoolean(System.getProperty(_name + ".SOURCE", Boolean.toString(_source)));
88 }
89 catch (AccessControlException ace)
90 {
91 _source = __source;
92 }
93 }
94
95 public String getName()
96 {
97 return _name;
98 }
99
100 public boolean isHideStacks()
101 {
102 return _hideStacks;
103 }
104
105 public void setHideStacks(boolean hideStacks)
106 {
107 _hideStacks = hideStacks;
108 }
109
110
111
112
113
114 public boolean isSource()
115 {
116 return _source;
117 }
118
119
120
121
122
123 public void setSource(boolean source)
124 {
125 _source = source;
126 }
127
128 public void warn(String msg, Object... args)
129 {
130 StringBuilder buffer = new StringBuilder(64);
131 format(buffer, ":WARN:", msg, args);
132 System.err.println(buffer);
133 }
134
135 public void warn(Throwable thrown)
136 {
137 warn("", thrown);
138 }
139
140 public void warn(String msg, Throwable thrown)
141 {
142 StringBuilder buffer = new StringBuilder(64);
143 format(buffer, ":WARN:", msg, thrown);
144 System.err.println(buffer);
145 }
146
147 public void info(String msg, Object... args)
148 {
149 StringBuilder buffer = new StringBuilder(64);
150 format(buffer, ":INFO:", msg, args);
151 System.err.println(buffer);
152 }
153
154 public void info(Throwable thrown)
155 {
156 info("", thrown);
157 }
158
159 public void info(String msg, Throwable thrown)
160 {
161 StringBuilder buffer = new StringBuilder(64);
162 format(buffer, ":INFO:", msg, thrown);
163 System.err.println(buffer);
164 }
165
166 public boolean isDebugEnabled()
167 {
168 return _debug;
169 }
170
171 public void setDebugEnabled(boolean enabled)
172 {
173 _debug = enabled;
174 }
175
176 public void debug(String msg, Object... args)
177 {
178 if (!_debug)
179 return;
180 StringBuilder buffer = new StringBuilder(64);
181 format(buffer, ":DBUG:", msg, args);
182 System.err.println(buffer);
183 }
184
185 public void debug(Throwable thrown)
186 {
187 debug("", thrown);
188 }
189
190 public void debug(String msg, Throwable thrown)
191 {
192 if (!_debug)
193 return;
194 StringBuilder buffer = new StringBuilder(64);
195 format(buffer, ":DBUG:", msg, thrown);
196 System.err.println(buffer);
197 }
198
199 private void format(StringBuilder buffer, String level, String msg, Object... args)
200 {
201 String d = _dateCache.now();
202 int ms = _dateCache.lastMs();
203 tag(buffer, d, ms, level);
204 format(buffer, msg, args);
205 }
206
207 private void format(StringBuilder buffer, String level, String msg, Throwable thrown)
208 {
209 format(buffer, level, msg);
210 if (isHideStacks())
211 format(buffer, String.valueOf(thrown));
212 else
213 format(buffer, thrown);
214 }
215
216 private void tag(StringBuilder buffer, String d, int ms, String tag)
217 {
218 buffer.setLength(0);
219 buffer.append(d);
220 if (ms > 99)
221 buffer.append('.');
222 else if (ms > 9)
223 buffer.append(".0");
224 else
225 buffer.append(".00");
226 buffer.append(ms).append(tag).append(_name).append(':');
227 if (_source)
228 {
229 Throwable source = new Throwable();
230 StackTraceElement[] frames = source.getStackTrace();
231 for (int i=0;i<frames.length;i++)
232 {
233 final StackTraceElement frame = frames[i];
234 String clazz = frame.getClassName();
235 if (clazz.equals(StdErrLog.class.getName())|| clazz.equals(Log.class.getName()))
236 continue;
237 if (clazz.startsWith("org.eclipse.jetty."))
238 buffer.append("o.e.j.").append(clazz,18,clazz.length());
239 else
240 buffer.append(clazz);
241 buffer.append('#').append(frame.getMethodName());
242 if (frame.getFileName()!=null)
243 buffer.append('(').append(frame.getFileName()).append(':').append(frame.getLineNumber()).append(')');
244 buffer.append(':');
245 break;
246 }
247 }
248 }
249
250 private void format(StringBuilder builder, String msg, Object... args)
251 {
252 msg = String.valueOf(msg);
253 String braces = "{}";
254 int start = 0;
255 for (Object arg : args)
256 {
257 int bracesIndex = msg.indexOf(braces, start);
258 if (bracesIndex < 0)
259 {
260 escape(builder, msg.substring(start));
261 builder.append(" ");
262 builder.append(arg);
263 start = msg.length();
264 }
265 else
266 {
267 escape(builder, msg.substring(start, bracesIndex));
268 builder.append(String.valueOf(arg));
269 start = bracesIndex + braces.length();
270 }
271 }
272 escape(builder, msg.substring(start));
273 }
274
275 private void escape(StringBuilder builder, String string)
276 {
277 for (int i = 0; i < string.length(); ++i)
278 {
279 char c = string.charAt(i);
280 if (Character.isISOControl(c))
281 {
282 if (c == '\n')
283 builder.append('|');
284 else if (c == '\r')
285 builder.append('<');
286 else
287 builder.append('?');
288 }
289 else
290 builder.append(c);
291 }
292 }
293
294 private void format(StringBuilder buffer, Throwable thrown)
295 {
296 if (thrown == null)
297 {
298 buffer.append("null");
299 }
300 else
301 {
302 buffer.append('\n');
303 format(buffer, thrown.toString());
304 StackTraceElement[] elements = thrown.getStackTrace();
305 for (int i = 0; elements != null && i < elements.length; i++)
306 {
307 buffer.append("\n\tat ");
308 format(buffer, elements[i].toString());
309 }
310
311 Throwable cause = thrown.getCause();
312 if (cause!=null && cause!=thrown)
313 {
314 buffer.append("\nCaused by: ");
315 format(buffer,cause);
316 }
317 }
318 }
319
320 public Logger getLogger(String name)
321 {
322 String fullname=_name == null || _name.length() == 0?name:_name + "." + name;
323
324 if ((name == null && this._name == null) || fullname.equals(_name))
325 return this;
326
327 StdErrLog logger = __loggers.get(name);
328 if (logger==null)
329 {
330 StdErrLog sel=new StdErrLog(fullname);
331 logger=__loggers.putIfAbsent(fullname,sel);
332 if (logger==null)
333 logger=sel;
334 }
335
336 return logger;
337 }
338
339 @Override
340 public String toString()
341 {
342 return "StdErrLog:" + _name + ":DEBUG=" + _debug;
343 }
344
345 public void ignore(Throwable ignored)
346 {
347 if (Log.isIgnored())
348 {
349 warn(Log.IGNORED, ignored);
350 }
351 }
352 }