1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.nuiton.util;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import java.io.PrintWriter;
29 import java.io.StringWriter;
30 import java.text.SimpleDateFormat;
31 import java.util.ArrayList;
32 import java.util.Date;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.logging.Formatter;
36 import java.util.logging.LogManager;
37 import java.util.logging.LogRecord;
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 public class LoggingPatternFormatter extends Formatter {
84
85 private static final Log log = LogFactory.getLog(LoggingPatternFormatter.class);
86
87 private static final String DEFAULT_PATTERN = "%d{yyyy-MM-dd HH:mm:ss} [free:%o{-7}|total:%O{-7}][%t][%p{7}] %c{org.nuiton.*|25} %M{15:105}: %m%n%e";
88
89 protected HashMap<String, Class<?>> arguments = null;
90
91 protected ArrayList<Argument> compile = null;
92
93 protected String pattern = null;
94
95 public LoggingPatternFormatter() {
96 try {
97 arguments = new HashMap<String, Class<?>>();
98 initArguments();
99 LogManager manager = LogManager.getLogManager();
100 String cname = this.getClass().getName();
101 pattern = manager.getProperty(cname + ".pattern");
102 if (pattern == null)
103 pattern = DEFAULT_PATTERN;
104 compilePattern(pattern);
105 } catch (Exception eee) {
106 log.error("Impossible d'utiliser le PatternFormatter", eee);
107 throw new LoggingException(
108 "Exception durant l'initialisation du PatternFormatter",
109 eee);
110 }
111 }
112
113
114
115
116
117
118
119 public String format(LogRecord record) {
120 StringBuffer result = new StringBuffer();
121 for (Iterator i = compile.iterator(); i.hasNext(); ) {
122 ((Argument) i.next()).toString(record, result);
123 }
124 return result.toString();
125 }
126
127
128
129
130
131 protected void initArguments() {
132 arguments.put("d", DateArgument.class);
133 arguments.put("o", FreeMemoryArgument.class);
134 arguments.put("O", TotalMemoryArgument.class);
135 arguments.put("t", ThreadArgument.class);
136 arguments.put("p", PriorityLevelArgument.class);
137 arguments.put("c", ClassNameArgument.class);
138 arguments.put("M", MethodNameArgument.class);
139 arguments.put("m", MessageArgument.class);
140 arguments.put("e", ExceptionArgument.class);
141 }
142
143
144
145
146
147
148 protected void compilePattern(String pattern) {
149 compile = new ArrayList<Argument>();
150 String[] match = findNextPattern(pattern);
151 while (!match[1].equals("")) {
152 compile.add(new StringArgument(match[0]));
153 compile.add(patternToArgument(match[1]));
154 match = findNextPattern(match[2]);
155 }
156 compile.add(new StringArgument(match[0]));
157 }
158
159
160
161
162
163
164
165
166 protected String[] findNextPattern(String s) {
167 String[] result = new String[]{"", "", ""};
168 if (s == null) {
169 return result;
170 }
171
172 int d = s.indexOf("%");
173
174 if (d != -1) {
175 if (d + 2 < s.length() && s.charAt(d + 2) == '{') {
176 int f = s.indexOf("}", d);
177 if (f != -1) {
178 result[0] = s.substring(0, d);
179 result[1] = s.substring(d + 1, f);
180 result[2] = s.substring(f + 1);
181 } else {
182 throw new LoggingException("Error, { at position "
183 + (d + 2) + " not terminated in :" + s);
184 }
185 } else {
186 result[0] = s.substring(0, d);
187 result[1] = s.substring(d + 1, d + 2);
188 result[2] = s.substring(d + 2);
189 }
190 } else {
191 result[0] = s;
192 }
193
194 return result;
195 }
196
197
198
199
200
201
202
203 protected Argument patternToArgument(String s) {
204 if (s.charAt(0) == 'n') {
205 return new StringArgument("\n");
206
207 } else if (s.charAt(0) == '%') {
208 return new StringArgument("%");
209
210 } else if (s.charAt(0) == '{') {
211 return new StringArgument("{");
212
213 } else {
214 String code = s.substring(0, 1);
215 Class argumentClass = (Class) arguments.get(code);
216 if (argumentClass == null)
217 throw new LoggingException("Erreur dans le pattern '" + code
218 + "' inconnu");
219 Argument argument;
220 try {
221 argument = (Argument) argumentClass.newInstance();
222 } catch (InstantiationException eee) {
223 throw new LoggingException(
224 "Erreur lors de l'instanciation de l'objet Argument: "
225 + argumentClass.getName(), eee);
226 } catch (IllegalAccessException eee) {
227 throw new LoggingException(
228 "Erreur lors de l'instanciation de l'objet Argument: "
229 + argumentClass.getName(), eee);
230 }
231 if (s.length() > 1) {
232 argument.setPattern(s.substring(2));
233 }
234
235 return argument;
236 }
237 }
238
239
240
241
242
243 static protected abstract class Argument {
244 protected String pattern;
245
246 public Argument() {
247 }
248
249 public void setPattern(String pattern) {
250 this.pattern = pattern;
251 }
252
253 abstract public StringBuffer toString(LogRecord record,
254 StringBuffer toAppendTo);
255 }
256
257 static protected class StringArgument extends Argument {
258 protected String s = null;
259
260 public StringArgument(String s) {
261 super();
262 this.s = s;
263 }
264
265 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
266 toAppendTo.append(s);
267 return toAppendTo;
268 }
269 }
270
271 static protected class DateArgument extends Argument {
272 protected SimpleDateFormat dateFormat = null;
273
274 public DateArgument() {
275 super();
276 }
277
278 public void setPattern(String pattern) {
279 super.setPattern(pattern);
280 dateFormat = new SimpleDateFormat(pattern);
281 }
282
283 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
284 toAppendTo.append(dateFormat.format(new Date(record.getMillis())));
285 return toAppendTo;
286 }
287 }
288
289 static abstract protected class SizedArgument extends Argument {
290 protected boolean left = true;
291
292 protected int width = 0;
293
294 protected int maxPos = -1;
295
296 public SizedArgument() {
297 super();
298 }
299
300 public void setPattern(String pattern) {
301 super.setPattern(pattern);
302 if (pattern.length() > 0) {
303 String[] subpattern = pattern.split(":");
304 pattern = subpattern[0];
305 char op = pattern.charAt(0);
306 if (pattern.charAt(0) == '+' || pattern.charAt(0) == '-') {
307 pattern = pattern.substring(1);
308 }
309 width = Integer.parseInt(pattern);
310 left = op != '-';
311 if (subpattern.length > 1) {
312 maxPos = Integer.parseInt(subpattern[1]);
313 }
314 }
315 }
316
317 protected StringBuffer justify(String s, StringBuffer toAppendTo) {
318 int blanc = width - s.length();
319 if (left) {
320 toAppendTo.append(s);
321 while (0 < blanc--
322 && (maxPos == -1 || toAppendTo.length() < maxPos)) {
323 toAppendTo.append(" ");
324 }
325 } else {
326 while (0 < blanc--
327 && (maxPos == -1 || toAppendTo.length() < maxPos)) {
328 toAppendTo.append(" ");
329 }
330 toAppendTo.append(s);
331 }
332 return toAppendTo;
333 }
334 }
335
336 static abstract protected class SubStringArgument extends SizedArgument {
337
338
339
340 protected String removeString = null;
341
342
343
344
345 protected boolean atBeginning = true;
346
347 public SubStringArgument() {
348 super();
349 }
350
351 public void setPattern(String pattern) {
352 String[] subpattern = pattern.split("\\|");
353 for (int i = 0; i < subpattern.length; i++) {
354 try {
355 super.setPattern(subpattern[i]);
356 } catch (NumberFormatException eee) {
357
358
359 atBeginning = subpattern[i].charAt(0) != '*';
360 if (subpattern[i].charAt(0) == '*') {
361 removeString = subpattern[i].substring(1);
362 } else if (subpattern[i].endsWith("*")) {
363 removeString = subpattern[i].substring(0, subpattern[i]
364 .length() - 1);
365 }
366 }
367 }
368 }
369
370 protected String substring(String s) {
371 if (atBeginning) {
372 if (s.startsWith(removeString))
373 return s.substring(removeString.length());
374 } else {
375 if (s.endsWith(removeString))
376 return s.substring(0, s.length() - removeString.length());
377 }
378 return s;
379 }
380 }
381
382 static abstract protected class OctetArgument extends SizedArgument {
383 protected static final String[] UNITE = {"o", "Ko", "Mo", "Go", "To",
384 "Po"};
385
386 protected int diviseur = 1024;
387
388 public OctetArgument() {
389 super();
390 }
391
392
393
394
395
396
397
398
399
400
401 protected String toReadableSize(long size, String[] unit, int diviseur) {
402 int unitIndex = 0;
403 while (size > 99999 && unitIndex < unit.length) {
404 size /= diviseur;
405 unitIndex++;
406 }
407 String result = size + unit[unitIndex];
408 return result;
409 }
410 }
411
412 static protected class FreeMemoryArgument extends OctetArgument {
413 public FreeMemoryArgument() {
414 super();
415 }
416
417 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
418 return justify(toReadableSize(Runtime.getRuntime().freeMemory(),
419 UNITE, diviseur), toAppendTo);
420 }
421 }
422
423 static protected class TotalMemoryArgument extends OctetArgument {
424 public TotalMemoryArgument() {
425 super();
426 }
427
428 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
429 return justify(toReadableSize(Runtime.getRuntime().totalMemory(),
430 UNITE, diviseur), toAppendTo);
431 }
432 }
433
434 static protected class ThreadArgument extends SizedArgument {
435 public ThreadArgument() {
436 super();
437 }
438
439 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
440 return justify(Thread.currentThread().getName(), toAppendTo);
441 }
442 }
443
444 static protected class PriorityLevelArgument extends SizedArgument {
445 public PriorityLevelArgument() {
446 super();
447 }
448
449 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
450 return justify(record.getLevel().toString(), toAppendTo);
451 }
452 }
453
454 static protected class ClassNameArgument extends SubStringArgument {
455 public ClassNameArgument() {
456 super();
457 }
458
459 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
460 return justify(substring(record.getSourceClassName()), toAppendTo);
461 }
462 }
463
464 static protected class MethodNameArgument extends SizedArgument {
465 public MethodNameArgument() {
466 super();
467 }
468
469 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
470 return justify(record.getSourceMethodName(), toAppendTo);
471 }
472 }
473
474 static protected class MessageArgument extends SizedArgument {
475 public MessageArgument() {
476 super();
477 }
478
479 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
480 return justify(record.getMessage(), toAppendTo);
481 }
482 }
483
484 static protected class ExceptionArgument extends Argument {
485 public ExceptionArgument() {
486 super();
487 }
488
489 public StringBuffer toString(LogRecord record, StringBuffer toAppendTo) {
490 Throwable e = record.getThrown();
491 if (e != null) {
492 toAppendTo.append(e.getMessage());
493 toAppendTo.append("\n");
494 StringWriter st = new StringWriter();
495 e.printStackTrace(new PrintWriter(st));
496 toAppendTo.append(st.toString());
497 toAppendTo.append("\n");
498 }
499 return toAppendTo;
500 }
501 }
502
503 }