1 18 package org.objectweb.util.monolog.wrapper.javaLog; 19 20 import org.objectweb.util.monolog.file.api.Pattern; 21 import org.objectweb.util.monolog.wrapper.common.AbstractFactory; 22 23 import java.util.logging.Formatter ; 24 import java.util.logging.LogRecord ; 25 import java.util.StringTokenizer ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 import java.util.Calendar ; 29 import java.util.Date ; 30 import java.io.StringWriter ; 31 import java.io.PrintWriter ; 32 33 43 public class MonologFormatter extends Formatter { 44 45 public final static String WRAPPERS_PROPERTY = "monolog.wrappers"; 46 47 50 private static final int STACK_TRACE_ITEMS = 9; 51 52 private static String [] LOGWRAPPER = { 53 "org.objectweb.util.monolog.wrapper", 54 "org.apache.commons.logging" 55 }; 56 57 static { 58 String wrap = System.getProperty(WRAPPERS_PROPERTY); 59 if (wrap != null) { 60 ArrayList ws = new ArrayList (5); 61 StringTokenizer st = new StringTokenizer (wrap,",;: /", false); 62 while (st.hasMoreTokens()) { 63 ws.add(st.nextToken()); 64 } 65 String [] wsa = new String [LOGWRAPPER.length + ws.size()]; 66 System.arraycopy(LOGWRAPPER, 0, wsa, 0, LOGWRAPPER.length); 67 for(int i=0; i<ws.size(); i++) { 68 wsa[LOGWRAPPER.length + i] = (String ) ws.get(i); 69 } 70 LOGWRAPPER = wsa; 71 } 72 } 73 74 private final static int PATTERN_ID_LEVEL = -100; 75 private final static int PATTERN_ID_TOPIC = -200; 76 private final static int PATTERN_ID_DATE = -300; 77 private final static int PATTERN_ID_THREAD = -400; 78 private final static int PATTERN_ID_MESSAGE = -500; 79 private final static int PATTERN_ID_METHOD = -600; 80 private final static int PATTERN_ID_OBJECT = -700; 81 private final static int PATTERN_ID_LINE_NUMBER = -800; 82 private final static int PATTERN_ID_NEW_LINE = -900; 83 private final static int PATTERN_ID_INTERVAL = 100; 84 85 private final static String TOKENS = 86 "{}" 87 + Pattern.LEVEL 88 + Pattern.TOPIC 89 + Pattern.DATE 90 + Pattern.THREAD 91 + Pattern.MESSAGE 92 + Pattern.METHOD 93 + Pattern.OBJECT 94 + Pattern.LINE_NUMBER 95 + Pattern.PREFIX 96 + Pattern.NEW_LINE; 97 98 private final static String patternIdToString(int id) { 99 switch(id) { 100 case PATTERN_ID_LEVEL: return "" + Pattern.LEVEL; 101 case PATTERN_ID_TOPIC: return "" + Pattern.TOPIC; 102 case PATTERN_ID_DATE: return "" + Pattern.DATE; 103 case PATTERN_ID_THREAD: return "" + Pattern.THREAD; 104 case PATTERN_ID_MESSAGE: return "" + Pattern.MESSAGE; 105 case PATTERN_ID_METHOD: return "" + Pattern.METHOD; 106 case PATTERN_ID_OBJECT: return "" + Pattern.OBJECT; 107 case PATTERN_ID_LINE_NUMBER: return "" + Pattern.LINE_NUMBER; 108 case PATTERN_ID_NEW_LINE: return "" + Pattern.NEW_LINE; 109 default: 110 return null; 111 } 112 } 113 114 115 Calendar calendar; 116 117 private static long previousTime; 118 119 private static char[] previousTimeWithoutMillis = new char[20]; 121 122 125 String strPattern; 126 127 130 int[] pattern; 131 132 135 String [] strings; 136 137 public MonologFormatter() { 138 calendar = Calendar.getInstance(); 139 } 140 141 public MonologFormatter(String strPattern) { 142 this(); 143 setPattern(strPattern); 144 } 145 146 147 public String getPattern() { 148 return strPattern; 149 } 150 151 public void setPattern(String p) { 152 if (AbstractFactory.debug) { 153 AbstractFactory.debug("Pattern=" + p); 154 } 155 this.strPattern = p; 156 if (strPattern == null) { 157 pattern = new int[0]; 158 } else { 159 StringTokenizer st = new StringTokenizer (p, TOKENS, true); 160 ArrayList sections = new ArrayList (); 161 boolean isPrefix = false; 162 boolean isObject = false; 163 boolean isInSubObject = false; 164 int subObjectNumber = 1; 165 while (st.hasMoreElements()) { 166 String token = st.nextToken(); 167 if (AbstractFactory.debug) { 168 AbstractFactory.debug("token=<" + token + ">"); 169 } 170 if (isObject && token.equals("{")) { 171 isInSubObject = true; 172 isObject = false; 173 } 174 if (token.length() == 1) { 175 char c = token.charAt(0); 176 switch (c) { 177 case '{': 178 if (!isInSubObject) { 179 addSection(sections, token); 180 } 181 break; 182 case '}': 183 if (isInSubObject) { 184 int old = ((Integer ) sections.get(sections.size() - 1)).intValue(); 185 sections.set(sections.size() - 1, 186 new Integer (old - subObjectNumber)); 187 isInSubObject = false; 188 } else { 189 addSection(sections, token); 190 } 191 break; 192 case Pattern.PREFIX: 193 if (isPrefix) { 194 sections.add(String.valueOf(Pattern.PREFIX)); 195 } 196 isPrefix = !isPrefix; 197 break; 198 case Pattern.LEVEL: 199 isPrefix = treatPattern( 200 sections, token, PATTERN_ID_LEVEL, isPrefix); 201 break; 202 case Pattern.TOPIC: 203 isPrefix = treatPattern( 204 sections, token, PATTERN_ID_TOPIC, isPrefix); 205 break; 206 case Pattern.DATE: 207 isPrefix = treatPattern( 208 sections, token, PATTERN_ID_DATE, isPrefix); 209 break; 210 case Pattern.THREAD: 211 isPrefix = treatPattern( 212 sections, token, PATTERN_ID_THREAD, isPrefix); 213 break; 214 case Pattern.MESSAGE: 215 isPrefix = treatPattern( 216 sections, token, PATTERN_ID_MESSAGE, isPrefix); 217 break; 218 case Pattern.METHOD: 219 isPrefix = treatPattern( 220 sections, token, PATTERN_ID_METHOD, isPrefix); 221 break; 222 case Pattern.OBJECT: 223 isPrefix = treatPattern( 224 sections, token, PATTERN_ID_OBJECT, isPrefix); 225 isObject = true; 226 break; 227 case Pattern.LINE_NUMBER: 228 isPrefix = treatPattern( 229 sections, token, PATTERN_ID_LINE_NUMBER, isPrefix); 230 break; 231 case Pattern.NEW_LINE: 232 isPrefix = treatPattern( 233 sections, token, PATTERN_ID_NEW_LINE, isPrefix); 234 break; 235 default: 236 if (isInSubObject) { 237 subObjectNumber = Integer.parseInt(token); 238 } else { 239 addSection(sections, token); 240 } 241 break; 242 } 243 } else if (isObject) { 244 } else if (isInSubObject) { 246 subObjectNumber = Integer.parseInt(token); 247 } else { 248 addSection(sections, token); 249 } 250 } 251 pattern = new int[sections.size()]; 252 if (AbstractFactory.debug) { 253 AbstractFactory.debug("building pattern array..."); 254 AbstractFactory.debug("nb of pattern:" + pattern.length); 255 } 256 ArrayList stringList = new ArrayList (sections.size()); 257 int cpt = 0; 258 for (int i = 0; i < pattern.length; i++) { 259 Object o = sections.get(i); 260 if (o instanceof String ) { 261 if (AbstractFactory.debug) { 262 AbstractFactory.debug("add current pattern into strings: [" + cpt + ", " + o + "]"); 263 } 264 stringList.add(o); 265 pattern[i] = cpt; 266 cpt++; 267 } else if (o instanceof Integer ) { 268 if (AbstractFactory.debug) { 269 AbstractFactory.debug("add current pattern as negative number:" + o); 270 } 271 pattern[i] = ((Integer ) o).intValue(); 272 } 273 } 274 strings = (String []) stringList.toArray(new String [cpt]); 275 if (AbstractFactory.debug) { 276 AbstractFactory.debug("nb of string:" + strings.length); 277 } 278 } 279 } 280 281 private boolean treatPattern(List sections, 282 String token, 283 int tokenId, 284 boolean isPrefix) { 285 if (AbstractFactory.debug) { 286 AbstractFactory.debug("treatPttern(" + tokenId + "):" 287 + " isPrefix=" + isPrefix 288 + " token=" + token 289 + " sections=" + sections 290 ); 291 } 292 if (isPrefix) { 293 sections.add(new Integer (tokenId)); 294 return false; 295 } else { 296 addSection(sections, token); 297 return isPrefix; 298 } 299 } 300 301 private void addSection(List sections, String s) { 302 int size = sections.size(); 303 if (size == 0) { 304 if (AbstractFactory.debug) { 305 AbstractFactory.debug("addSection(" + s + ", " + sections + "): first elem"); 306 } 307 sections.add(s); 308 } else { 309 Object last = sections.get(size - 1); 310 if (last instanceof String ) { 311 sections.set(size - 1, last + s); 312 if (AbstractFactory.debug) { 313 AbstractFactory.debug("addSection(" + s + ", " + sections + "): concat: " + sections.get(size - 1)); 314 } 315 } else { 316 if (AbstractFactory.debug) { 317 AbstractFactory.debug("addSection(" + s + ", " + sections + "): new elem"); 318 } 319 sections.add(s); 320 } 321 } 322 } 323 324 335 public String format(LogRecord record) { 336 StringBuffer sb = new StringBuffer (); 337 String [] ctx = null; 338 for (int i = 0; i < pattern.length; i++) { 339 int p = pattern[i]; 340 if (AbstractFactory.debug) { 341 AbstractFactory.debug("format: pattern=" + p + "=" + patternIdToString(p)); 342 } 343 switch (p) { 344 case PATTERN_ID_LEVEL: 345 sb.append(record.getLevel().getName()); 346 break; 347 case PATTERN_ID_TOPIC: 348 sb.append(record.getLoggerName()); 349 break; 350 case PATTERN_ID_DATE: 351 format(new Date (record.getMillis()), sb); 352 break; 353 case PATTERN_ID_THREAD: 354 sb.append(Thread.currentThread().getName()); 355 break; 356 case PATTERN_ID_MESSAGE: 357 sb.append(record.getMessage()); 358 break; 359 case PATTERN_ID_METHOD: 360 if (ctx == null) { 361 ctx = getContext(); 362 } 363 sb.append(ctx[1]); 364 break; 365 case PATTERN_ID_OBJECT: 366 if (ctx == null) { 367 ctx = getContext(); 368 } 369 sb.append(ctx[0]); 370 break; 371 case PATTERN_ID_LINE_NUMBER: 372 if (ctx == null) { 373 ctx = getContext(); 374 } 375 sb.append(ctx[2]); 376 break; 377 case PATTERN_ID_NEW_LINE: 378 sb.append("\n"); 379 break; 380 default: 381 if (p < 0) { 382 if (ctx == null) { 383 ctx = getContext(); 384 } 385 if (p > (PATTERN_ID_OBJECT - PATTERN_ID_INTERVAL) 386 && p<PATTERN_ID_OBJECT) { 387 p = PATTERN_ID_OBJECT - p; 388 String res = ctx[0]; 389 if (p == 1) { int idx = res.lastIndexOf('.'); 391 if (idx != -1) { 392 res = res.substring(idx + 1); 393 } 394 } else if (p == 0) { 395 } else { 397 int idx = res.lastIndexOf('.'); 398 for(;p>1 && idx != -1;p--) { 399 if (idx != -1) { 400 idx = res.lastIndexOf('.', idx - 1); 401 } 402 } 403 if (idx != -1) { 404 res = res.substring(idx + 1); 405 } 406 } 407 sb.append(res); 408 } 409 } else if (p >= strings.length) { 410 System.err.println("ERROR: String identifier unknown: " + p); 411 } else { 412 sb.append(strings[p]); 413 } 414 } 415 } 416 if (record.getThrown() != null) { 417 StringWriter sw = new StringWriter (); 418 record.getThrown().printStackTrace(new PrintWriter (sw)); 419 sb.append(sw.getBuffer()); 420 } 421 return sb.toString(); 422 } 423 424 431 public static String [] getContext() { 432 433 Throwable t = new Throwable ().fillInStackTrace(); 434 StringWriter sw = new StringWriter (); 435 t.printStackTrace(new PrintWriter (sw)); 436 String m = sw.getBuffer().toString(); 437 int fin = 0; 438 int deb = 0; 439 for (int i = 0; i < STACK_TRACE_ITEMS; i++) { 441 deb = m.indexOf("\n", deb) + 1; 442 } 443 boolean isWrapper = true; 444 deb = m.indexOf("at ", deb) + 3; 445 while (isWrapper) { 446 isWrapper = false; 447 for (int i=0; i<LOGWRAPPER.length && !isWrapper; i++) { 448 isWrapper |= m.startsWith(LOGWRAPPER[i], deb); 449 } 450 if (isWrapper) { 451 deb = m.indexOf("at ", deb) + 3; 452 } 453 } 454 fin = m.indexOf("\n", deb); 455 m = m.substring(deb, fin); 456 457 deb = m.indexOf("("); 459 fin = m.indexOf(":"); 460 String [] res = new String [3]; 461 res[2] = (fin == -1 ? "unknown" : m.substring(fin + 1, m.length() - 1)); 462 m = m.substring(0, deb); 463 464 fin = m.lastIndexOf('.'); 466 res[0] = m.substring(0, fin); 467 res[1] = m.substring(fin + 1); 468 return res; 469 } 470 471 478 public void format(Date date, StringBuffer sbuf) { 479 long now = date.getTime(); 480 int millis = (int) (now % 1000); 481 482 if ((now - millis) != previousTime) { 483 487 calendar.setTime(date); 488 489 int start = sbuf.length(); 490 491 int year = calendar.get(Calendar.YEAR); 492 sbuf.append(year); 493 sbuf.append('-'); 494 int month = calendar.get(Calendar.MONTH); 495 month++; 496 if (month < 10) { 497 sbuf.append('0'); 498 } 499 sbuf.append(month); 500 sbuf.append('-'); 501 int day = calendar.get(Calendar.DAY_OF_MONTH); 502 if (day < 10) { 503 sbuf.append('0'); 504 } 505 sbuf.append(day); 506 507 sbuf.append(' '); 508 509 int hour = calendar.get(Calendar.HOUR_OF_DAY); 510 if (hour < 10) { 511 sbuf.append('0'); 512 } 513 sbuf.append(hour); 514 sbuf.append(':'); 515 516 int mins = calendar.get(Calendar.MINUTE); 517 if (mins < 10) { 518 sbuf.append('0'); 519 } 520 sbuf.append(mins); 521 sbuf.append(':'); 522 523 int secs = calendar.get(Calendar.SECOND); 524 if (secs < 10) { 525 sbuf.append('0'); 526 } 527 sbuf.append(secs); 528 sbuf.append(','); 529 530 sbuf.getChars(start, sbuf.length(), previousTimeWithoutMillis, 0); 532 533 previousTime = now - millis; 534 } else { 535 sbuf.append(previousTimeWithoutMillis); 536 } 537 if (millis < 100) { 538 sbuf.append('0'); 539 } 540 if (millis < 10) { 541 sbuf.append('0'); 542 } 543 sbuf.append(millis); 544 } 545 546 public String format(String msg, String levelName, String topic, long time) { 547 StringBuffer sb = new StringBuffer (); 548 String [] ctx = null; 549 for (int i = 0; i < pattern.length; i++) { 550 int p = pattern[i]; 551 if (AbstractFactory.debug) { 552 AbstractFactory.debug("format: pattern=" + p + "=" + patternIdToString(p)); 553 } 554 switch (p) { 555 case PATTERN_ID_LEVEL: 556 sb.append(levelName); 557 break; 558 case PATTERN_ID_TOPIC: 559 sb.append(topic); 560 break; 561 case PATTERN_ID_DATE: 562 format(new Date (time), sb); 563 break; 564 case PATTERN_ID_THREAD: 565 sb.append(Thread.currentThread().getName()); 566 break; 567 case PATTERN_ID_MESSAGE: 568 sb.append(msg); 569 break; 570 case PATTERN_ID_METHOD: 571 if (ctx == null) { 572 ctx = getContext(); 573 } 574 sb.append(ctx[1]); 575 break; 576 case PATTERN_ID_OBJECT: 577 if (ctx == null) { 578 ctx = getContext(); 579 } 580 sb.append(ctx[0]); 581 break; 582 case PATTERN_ID_LINE_NUMBER: 583 if (ctx == null) { 584 ctx = getContext(); 585 } 586 sb.append(ctx[2]); 587 break; 588 case PATTERN_ID_NEW_LINE: 589 sb.append("\n"); 590 break; 591 default: 592 if (p < 0) { 593 if (ctx == null) { 594 ctx = getContext(); 595 } 596 if (p > (PATTERN_ID_OBJECT - PATTERN_ID_INTERVAL) 597 && p<PATTERN_ID_OBJECT) { 598 p = PATTERN_ID_OBJECT - p; 599 String res = ctx[0]; 600 if (p == 1) { int idx = res.lastIndexOf('.'); 602 if (idx != -1) { 603 res = res.substring(idx + 1); 604 } 605 } else if (p == 0) { 606 } else { 608 int idx = res.lastIndexOf('.'); 609 for(;p>1 && idx != -1;p--) { 610 if (idx != -1) { 611 idx = res.lastIndexOf('.', idx - 1); 612 } 613 } 614 if (idx != -1) { 615 res = res.substring(idx + 1); 616 } 617 } 618 sb.append(res); 619 } 620 } else if (p >= strings.length) { 621 System.err.println("ERROR: String identifier unknown: " + p); 622 } else { 623 sb.append(strings[p]); 624 } 625 } 626 } 627 return sb.toString(); 628 } 629 630 } | Popular Tags |