1 19 20 package org.netbeans.core.startup; 21 22 import java.io.ByteArrayInputStream ; 23 import java.io.ByteArrayOutputStream ; 24 import java.io.File ; 25 import java.io.FileOutputStream ; 26 import java.io.IOException ; 27 import java.io.PrintStream ; 28 import java.io.PrintWriter ; 29 import java.io.StringWriter ; 30 import java.io.UnsupportedEncodingException ; 31 import java.text.DateFormat ; 32 import java.util.Collection ; 33 import java.util.Date ; 34 import java.util.HashSet ; 35 import java.util.Iterator ; 36 import java.util.Locale ; 37 import java.util.Map ; 38 import java.util.MissingResourceException ; 39 import java.util.Set ; 40 import java.util.StringTokenizer ; 41 import java.util.concurrent.Callable ; 42 import java.util.logging.Formatter ; 43 import java.util.logging.Handler ; 44 import java.util.logging.Level ; 45 import java.util.logging.LogManager ; 46 import java.util.logging.LogRecord ; 47 import java.util.logging.Logger ; 48 import java.util.logging.StreamHandler ; 49 import org.openide.filesystems.FileUtil; 50 import org.openide.util.Lookup; 51 import org.openide.util.LookupEvent; 52 import org.openide.util.LookupListener; 53 import org.openide.util.NbBundle; 54 import org.openide.util.RequestProcessor; 55 import org.xml.sax.SAXParseException ; 56 57 63 public final class TopLogging { 64 private static boolean disabledConsole = ! Boolean.getBoolean("netbeans.logger.console"); 66 private static final PrintStream OLD_ERR = System.err; 67 static { 68 System.setProperty("sun.awt.exception.handler", "org.netbeans.core.startup.TopLogging$AWTHandler"); } 70 71 73 public TopLogging() { 74 ByteArrayOutputStream os = new ByteArrayOutputStream (); 75 PrintStream ps = new PrintStream (os); 76 77 Iterator it = System.getProperties().entrySet().iterator(); 78 while (it.hasNext()) { 79 Map.Entry e = (Map.Entry )it.next(); 80 81 String key = (String )e.getKey(); 82 83 if ("sun.os.patch.level".equals(key)) { continue; 86 } 87 88 String v = (String )e.getValue(); 89 90 if (key.endsWith(".level")) { 91 ps.print(key); 92 ps.print("="); 93 ps.println(v); 94 } 95 } 96 ps.close(); 97 try { 98 LogManager.getLogManager().readConfiguration(new ByteArrayInputStream (os.toByteArray())); 99 } catch (IOException ex) { 100 ex.printStackTrace(); 101 } 102 103 104 Logger logger = Logger.getLogger (""); 106 Handler [] old = logger.getHandlers(); 107 for (int i = 0; i < old.length; i++) { 108 logger.removeHandler(old[i]); 109 } 110 logger.addHandler(defaultHandler ()); 111 if (!disabledConsole) { logger.addHandler (streamHandler ()); 113 } 114 logger.addHandler(new LookupDel()); 115 116 121 } 122 123 private static String previousUser; 124 static final void initialize() { 125 if (previousUser == null || previousUser.equals(System.getProperty("netbeans.user"))) { 126 streamHandler = null; 128 defaultHandler = null; 129 } 130 131 if (System.getProperty("java.util.logging.config.file") != null) { return; 133 } 134 String v = System.getProperty("java.util.logging.config.class"); String p = TopLogging.class.getName(); 136 if (v != null && !v.equals(p)) { 137 return; 138 } 139 140 new TopLogging(); 142 System.setProperty("java.util.logging.config.class", p); 144 145 ByteArrayOutputStream os = new ByteArrayOutputStream (); 146 PrintStream ps = new PrintStream (os); 147 printSystemInfo(ps); 148 ps.close(); 149 try { 150 Logger logger = Logger.getLogger (TopLogging.class.getName()); logger.log(Level.INFO, os.toString("utf-8")); 152 } catch (UnsupportedEncodingException ex) { 153 assert false; 154 } 155 156 if (!(System.err instanceof LgStream)) { 157 System.setErr(new LgStream(Logger.getLogger("stderr"))); } 159 } 160 161 162 private static void printSystemInfo(PrintStream ps) { 163 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US); 164 Date date = new Date (); 165 166 ps.println("-------------------------------------------------------------------------------"); ps.println(">Log Session: "+df.format (date)); ps.println(">System Info: "); 170 String buildNumber = System.getProperty ("netbeans.buildnumber"); String currentVersion = NbBundle.getMessage(TopLogging.class, "currentVersion", buildNumber ); 172 ps.println(" Product Version = " + currentVersion); ps.println(" Operating System = " + System.getProperty("os.name", "unknown") 174 + " version " + System.getProperty("os.version", "unknown") 175 + " running on " + System.getProperty("os.arch", "unknown")); 176 ps.println(" Java; VM; Vendor; Home = " + System.getProperty("java.version", "unknown") + "; " + 177 System.getProperty("java.vm.name", "unknown") + " " + System.getProperty("java.vm.version", "") + "; " + 178 System.getProperty("java.vendor", "unknown") + "; " + 179 System.getProperty("java.home", "unknown")); 180 ps.print( " System Locale; Encoding = " + Locale.getDefault()); String branding = NbBundle.getBranding (); 182 if (branding != null) { 183 ps.print(" (" + branding + ")"); } 185 ps.println("; " + System.getProperty("file.encoding", "unknown")); ps.println(" Home Dir.; Current Dir. = " + System.getProperty("user.home", "unknown") + "; " + 187 System.getProperty("user.dir", "unknown")); 188 ps.print( " Installation; User Dir. = "); String nbdirs = System.getProperty("netbeans.dirs"); 190 if (nbdirs != null) { StringTokenizer tok = new StringTokenizer (nbdirs, File.pathSeparator); 192 while (tok.hasMoreTokens()) { 193 ps.print(FileUtil.normalizeFile(new File (tok.nextToken()))); 194 ps.print(File.pathSeparatorChar); 195 } 196 } 197 ps.println(CLIOptions.getHomeDir() + "; " + CLIOptions.getUserDir()); ps.println(" Boot & Ext. Classpath = " + createBootClassPath()); ps.println(" Application Classpath = " + System.getProperty("java.class.path", "unknown")); ps.println(" Startup Classpath = " + System.getProperty("netbeans.dynamic.classpath", "unknown")); ps.println("-------------------------------------------------------------------------------"); } 203 204 private static String createBootClassPath() { 206 String boot = System.getProperty("sun.boot.class.path"); StringBuffer sb = (boot != null ? new StringBuffer (boot) : new StringBuffer ()); 209 210 findBootJars(System.getProperty("java.ext.dirs"), sb); 212 findBootJars(System.getProperty("java.endorsed.dirs"), sb); 213 return sb.toString(); 214 } 215 216 220 private static void findBootJars(final String extensions, final StringBuffer sb) { 221 if (extensions != null) { 222 for (StringTokenizer st = new StringTokenizer (extensions, File.pathSeparator); st.hasMoreTokens();) { 223 File dir = new File (st.nextToken()); 224 File [] entries = dir.listFiles(); 225 if (entries != null) { 226 for (int i = 0; i < entries.length; i++) { 227 String name = entries[i].getName().toLowerCase(Locale.US); 228 if (name.endsWith(".zip") || name.endsWith(".jar")) { if (sb.length() > 0) { 230 sb.append(File.pathSeparatorChar); 231 } 232 sb.append(entries[i].getPath()); 233 } 234 } 235 } 236 } 237 } 238 } 239 240 242 static Handler createStreamHandler (PrintStream pw) { 243 StreamHandler s = new StreamHandler ( 244 pw, NbFormatter.FORMATTER 245 ); 246 return s; 247 } 248 249 private static java.util.logging.Handler streamHandler; 250 private static synchronized java.util.logging.Handler streamHandler () { 251 if (streamHandler == null) { 252 StreamHandler sth = new StreamHandler (OLD_ERR, NbFormatter.FORMATTER); 253 sth.setLevel(Level.ALL); 254 streamHandler = new NonClose(sth, 500); 255 } 256 return streamHandler; 257 } 258 259 private static java.util.logging.Handler defaultHandler; 260 private static synchronized java.util.logging.Handler defaultHandler () { 261 if (defaultHandler != null) return defaultHandler; 262 263 String home = System.getProperty("netbeans.user"); 264 if (home != null && !"memory".equals(home) && !CLIOptions.noLogging) { 265 try { 266 File dir = new File (new File (new File (home), "var"), "log"); 267 dir.mkdirs (); 268 File f = new File (dir, "messages.log"); 269 File f1 = new File (dir, "messages.log.1"); 270 File f2 = new File (dir, "messages.log.2"); 271 272 if (f1.exists()) { 273 f1.renameTo(f2); 274 } 275 if (f.exists()) { 276 f.renameTo(f1); 277 } 278 279 FileOutputStream fout = new FileOutputStream (f, false); 280 Handler h = new StreamHandler (fout, NbFormatter.FORMATTER); 281 h.setLevel(Level.ALL); 282 h.setFormatter(NbFormatter.FORMATTER); 283 defaultHandler = new NonClose(h, 5000); 284 } catch (IOException ex) { 285 ex.printStackTrace(); 286 } 287 } 288 289 if (defaultHandler == null) { 290 defaultHandler = streamHandler(); 291 disabledConsole = true; 292 } 293 return defaultHandler; 294 } 295 296 297 static void flush(boolean clear) { 298 Handler s = streamHandler; 299 if (s != null) { 300 s.flush(); 301 } 302 303 Handler d = defaultHandler; 304 if (d != null) { 305 d.flush(); 306 } 307 308 if (clear) { 309 streamHandler = null; 310 defaultHandler = null; 311 } 312 } 313 static void close() { 314 Handler s = streamHandler; 315 if (s instanceof NonClose) { 316 NonClose ns = (NonClose)s; 317 ns.doClose(); 318 } 319 320 Handler d = defaultHandler; 321 if (d != null) { 322 NonClose nd = (NonClose)d; 323 nd.doClose(); 324 } 325 } 326 327 329 private static final class NonClose extends Handler 330 implements Runnable { 331 private static RequestProcessor RP = new RequestProcessor("Logging Flush"); 333 private final Handler delegate; 334 private RequestProcessor.Task flush; 335 private int delay; 336 337 public NonClose(Handler h, int delay) { 338 delegate = h; 339 flush = RP.create(this, true); 340 flush.setPriority(Thread.MIN_PRIORITY); 341 this.delay = delay; 342 } 343 344 public void publish(LogRecord record) { 345 delegate.publish(record); 346 flush.schedule(delay); 347 } 348 349 public void flush() { 350 flush.cancel(); 351 flush.waitFinished(); 352 delegate.flush(); 353 } 354 355 public void close() throws SecurityException { 356 flush(); 357 delegate.flush(); 358 } 359 360 public void doClose() throws SecurityException { 361 flush(); 362 delegate.close(); 363 } 364 365 public Formatter getFormatter() { 366 return delegate.getFormatter(); 367 } 368 369 static Handler getInternal(Handler h) { 370 if (h instanceof NonClose) { 371 return ((NonClose)h).delegate; 372 } 373 return h; 374 } 375 376 public void run() { 377 delegate.flush(); 378 } 379 } 380 381 383 private static final class NbFormatter extends java.util.logging.Formatter { 384 private static String lineSeparator = System.getProperty ("line.separator"); static java.util.logging.Formatter FORMATTER = new NbFormatter (); 386 387 388 public String format(java.util.logging.LogRecord record) { 389 StringBuilder sb = new StringBuilder (); 390 print(sb, record, new HashSet <Throwable >()); 391 return sb.toString(); 392 } 393 394 395 private void print(StringBuilder sb, LogRecord record, Set <Throwable > beenThere) { 396 String message = formatMessage(record); 398 if (message != null && message.indexOf('\n') != -1 && record.getThrown() == null) { 399 sb.append(message); 401 return; 402 } 403 if ("stderr".equals(record.getLoggerName()) && record.getLevel() == Level.INFO) { sb.append(message); 406 return; 407 } 408 409 sb.append(record.getLevel().getLocalizedName()); 410 addLoggerName (sb, record); 411 if (message != null) { 412 sb.append(": "); 413 sb.append(message); 414 } 415 sb.append(lineSeparator); 416 if (record.getThrown() != null && record.getLevel().intValue() != 1973) { try { 418 StringWriter sw = new StringWriter (); 419 PrintWriter pw = new PrintWriter (sw); 420 StackTraceElement [] tStack = record.getThrown().getStackTrace(); 423 StackTraceElement [] hereStack = new Throwable ().getStackTrace(); 424 int idx = -1; 425 for (int i = 1; i <= Math.min(tStack.length, hereStack.length); i++) { 426 if (!tStack[tStack.length - i].equals(hereStack[hereStack.length - i])) { 427 idx = tStack.length - i + 1; 428 break; 429 } 430 } 431 String [] tLines = decompose(record.getThrown()); 432 for (int i = 0; i < tLines.length; i++) { 433 if (i == idx) { 434 pw.print("[catch]"); if (tLines[i].charAt(0) == '\t') { 438 pw.print(' '); 439 tLines[i] = tLines[i].substring(1); 440 } 441 } 442 pw.println(tLines[i]); 443 } 444 pw.close(); 445 sb.append(sw.toString()); 446 } catch (Exception ex) { 447 } 448 449 LogRecord [] arr = extractDelegates(sb, record.getThrown(), beenThere); 450 if (arr != null) { 451 for (LogRecord r : arr) { 452 print(sb, r, beenThere); 453 } 454 } 455 456 specialProcessing(sb, record.getThrown(), beenThere); 457 } 458 } 459 460 private static void addLoggerName (StringBuilder sb, java.util.logging.LogRecord record) { 461 String name = record.getLoggerName (); 462 if (!"".equals (name)) { 463 sb.append(" ["); 464 sb.append(name); 465 sb.append(']'); 466 } 467 } 468 469 private static LogRecord [] extractDelegates(StringBuilder sb, Throwable t, Set <Throwable > beenThere) { 470 if (!beenThere.add(t)) { 471 sb.append("warning: cyclic dependency between annotated throwables"); return null; 473 } 474 475 if (t instanceof Callable ) { 476 Object rec = null; 477 try { 478 rec = ((Callable ) t).call(); 479 } catch (Exception ex) { 480 ex.printStackTrace(); 481 } 482 if (rec instanceof LogRecord []) { 483 return (LogRecord [])rec; 484 } 485 } 486 if (t == null) { 487 return null; 488 } 489 return extractDelegates(sb, t.getCause(), beenThere); 490 } 491 492 493 private void specialProcessing(StringBuilder sb, Throwable t, Set <Throwable > beenThere) { 494 if (t instanceof MissingResourceException ) { 496 MissingResourceException mre = (MissingResourceException ) t; 497 String cn = mre.getClassName(); 498 if (cn != null) { 499 LogRecord rec = new LogRecord (Level.CONFIG, null); 500 rec.setResourceBundle(NbBundle.getBundle(TopLogging.class)); 501 rec.setMessage("EXC_MissingResourceException_class_name"); 502 rec.setParameters(new Object [] { cn }); 503 print(sb, rec, beenThere); 504 } 505 String k = mre.getKey(); 506 if (k != null) { 507 LogRecord rec = new LogRecord (Level.CONFIG, null); 508 rec.setResourceBundle(NbBundle.getBundle(TopLogging.class)); 509 rec.setMessage("EXC_MissingResourceException_key"); 510 rec.setParameters(new Object [] { k }); 511 print(sb, rec, beenThere); 512 } 513 } 514 if (t instanceof SAXParseException ) { 515 SAXParseException spe = (SAXParseException )t; 517 String pubid = spe.getPublicId(); 518 String sysid = spe.getSystemId(); 519 if (pubid != null || sysid != null) { 520 int col = spe.getColumnNumber(); 521 int line = spe.getLineNumber(); 522 String msg; 523 Object [] param; 524 if (col != -1 || line != -1) { 525 msg = "EXC_sax_parse_col_line"; param = new Object [] {String.valueOf(pubid), String.valueOf(sysid), new Integer (col), new Integer (line)}; 527 } else { 528 msg = "EXC_sax_parse"; param = new Object [] { String.valueOf(pubid), String.valueOf(sysid) }; 530 } 531 LogRecord rec = new LogRecord (Level.CONFIG, null); 532 rec.setResourceBundle(NbBundle.getBundle(TopLogging.class)); 533 rec.setMessage(msg); 534 rec.setParameters(param); 535 print(sb, rec, beenThere); 536 } 537 } 538 } 539 540 private static String [] decompose(Throwable t) { 541 StringWriter sw = new StringWriter (); 542 t.printStackTrace(new PrintWriter (sw)); 543 return sw.toString().split("(\r\n?|\n)($|(?=\\s*at ))"); } 545 } 547 549 private static final class LgStream extends PrintStream { 550 private Logger log; 551 private StringBuffer sb = new StringBuffer (); 552 553 public LgStream(Logger log) { 554 super(new ByteArrayOutputStream ()); 555 this.log = log; 556 } 557 558 public void write(byte[] buf, int off, int len) { 559 sb.append(new String (buf, off, len)); 560 checkFlush(); 561 } 562 563 public void write(byte[] b) throws IOException { 564 write(b, 0, b.length); 565 } 566 567 public void write(int b) { 568 sb.append((char)b); 569 checkFlush(); 570 } 571 572 private void checkFlush() { 573 boolean justNewLine = false; 574 for (;;) { 575 int first = sb.indexOf("\n"); if (first < 0) { 577 break; 578 } 579 justNewLine = false; 580 if (first == 0) { 581 justNewLine = true; 582 sb.delete(0, 1); 583 continue; 584 } 585 log.log(Level.INFO, sb.substring(0, first + 1)); 586 sb.delete(0, first + 1); 587 } 588 589 if (justNewLine) { 590 log.log(Level.INFO, "\n"); 591 } 592 } 593 } 595 private static final class LookupDel extends Handler 596 implements LookupListener { 597 private Lookup.Result<Handler > handlers; 598 private Collection <? extends Handler > instances; 599 600 601 public LookupDel() { 602 handlers = Lookup.getDefault().lookupResult(Handler .class); 603 instances = handlers.allInstances(); 604 handlers.addLookupListener(this); 605 } 606 607 608 public void publish(LogRecord record) { 609 for (Handler h : instances) { 610 h.publish(record); 611 } 612 } 613 614 public void flush() { 615 for (Handler h : instances) { 616 h.flush(); 617 } 618 } 619 620 public void close() throws SecurityException { 621 for (Handler h : instances) { 622 h.close(); 623 } 624 } 625 626 public void resultChanged(LookupEvent ev) { 627 instances = handlers.allInstances(); 628 } 629 } 631 632 public static final class AWTHandler { 633 634 public static void handle(Throwable t) { 635 if (t.getClass().getName().endsWith(".ExitSecurityException")) { return; 638 } 639 Logger.global.log(Level.SEVERE, null, t); 640 } 641 } 643 } 644 | Popular Tags |