1 11 package org.eclipse.core.runtime.adaptor; 12 13 import java.io.*; 14 import java.lang.reflect.InvocationTargetException ; 15 import java.security.AccessController ; 16 import java.util.Calendar ; 17 import java.util.Date ; 18 import org.eclipse.core.runtime.internal.adaptor.EclipseEnvironmentInfo; 19 import org.eclipse.osgi.framework.internal.core.FrameworkProperties; 20 import org.eclipse.osgi.framework.log.FrameworkLog; 21 import org.eclipse.osgi.framework.log.FrameworkLogEntry; 22 import org.eclipse.osgi.framework.util.SecureAction; 23 import org.osgi.framework.*; 24 25 32 public class EclipseLog implements FrameworkLog { 33 private static final String PASSWORD = "-password"; 35 protected static final String SESSION = "!SESSION"; 37 protected static final String ENTRY = "!ENTRY"; 39 protected static final String SUBENTRY = "!SUBENTRY"; 41 protected static final String MESSAGE = "!MESSAGE"; 43 protected static final String STACK = "!STACK"; 45 46 protected static final String LINE_SEPARATOR; 47 48 protected static final String TAB_STRING = "\t"; 50 52 public static final int DEFAULT_LOG_SIZE = 1000; 53 54 public static final int DEFAULT_LOG_FILES = 10; 55 56 public static final int LOG_SIZE_MIN = 10; 57 58 59 public static final String PROP_LOG_SIZE_MAX = "eclipse.log.size.max"; 61 public static final String PROP_LOG_FILE_MAX = "eclipse.log.backup.max"; 63 public static final String LOG_EXT = ".log"; 65 public static final String BACKUP_MARK = ".bak_"; 67 static { 68 String s = System.getProperty("line.separator"); LINE_SEPARATOR = s == null ? "\n" : s; } 71 private static final SecureAction secureAction = (SecureAction) AccessController.doPrivileged(SecureAction.createSecureAction());; 72 73 74 protected boolean consoleLog = false; 75 76 protected boolean newSession = true; 77 80 protected File outFile; 81 82 85 protected Writer writer; 86 87 int maxLogSize = DEFAULT_LOG_SIZE; int maxLogFiles = DEFAULT_LOG_FILES; 89 int backupIdx = 0; 90 91 95 public EclipseLog(File outFile) { 96 this.outFile = outFile; 97 this.writer = null; 98 readLogProperties(); 99 } 100 101 105 public EclipseLog(Writer writer) { 106 if (writer == null) 107 this.writer = logForStream(System.err); 109 else 110 this.writer = writer; 111 } 112 113 117 public EclipseLog() { 118 this((Writer) null); 119 } 120 121 private Throwable getRoot(Throwable t) { 122 Throwable root = null; 123 if (t instanceof BundleException) 124 root = ((BundleException) t).getNestedException(); 125 if (t instanceof InvocationTargetException ) 126 root = ((InvocationTargetException ) t).getTargetException(); 127 if (root instanceof InvocationTargetException || root instanceof BundleException) { 129 Throwable deeplyNested = getRoot(root); 130 if (deeplyNested != null) 131 root = deeplyNested; 133 } 134 return root; 135 } 136 137 142 protected void writeArgs(String header, String [] args) throws IOException { 143 if (args == null || args.length == 0) 144 return; 145 write(header); 146 for (int i = 0; i < args.length; i++) { 147 if (i > 0 && PASSWORD.equals(args[i - 1])) 149 write(" (omitted)"); else 151 write(" " + args[i]); } 153 writeln(); 154 } 155 156 160 protected String getSessionTimestamp() { 161 String ts = FrameworkProperties.getProperty("eclipse.startTime"); if (ts != null) { 165 try { 166 return getDate(new Date (Long.parseLong(ts))); 167 } catch (NumberFormatException e) { 168 } 170 } 171 return getDate(new Date ()); 172 } 173 174 178 protected void writeSession() throws IOException { 179 write(SESSION); 180 writeSpace(); 181 String date = getSessionTimestamp(); 182 write(date); 183 writeSpace(); 184 for (int i = SESSION.length() + date.length(); i < 78; i++) { 185 write("-"); } 187 writeln(); 188 try { 190 String key = "eclipse.buildId"; String value = FrameworkProperties.getProperty(key, "unknown"); writeln(key + "=" + value); 194 key = "java.fullversion"; value = System.getProperty(key); 196 if (value == null) { 197 key = "java.version"; value = System.getProperty(key); 199 writeln(key + "=" + value); key = "java.vendor"; value = System.getProperty(key); 202 writeln(key + "=" + value); } else { 204 writeln(key + "=" + value); } 206 } catch (Exception e) { 207 } 210 write("BootLoader constants: OS=" + EclipseEnvironmentInfo.getDefault().getOS()); write(", ARCH=" + EclipseEnvironmentInfo.getDefault().getOSArch()); write(", WS=" + EclipseEnvironmentInfo.getDefault().getWS()); writeln(", NL=" + EclipseEnvironmentInfo.getDefault().getNL()); writeArgs("Framework arguments: ", EclipseEnvironmentInfo.getDefault().getNonFrameworkArgs()); writeArgs("Command-line arguments: ", EclipseEnvironmentInfo.getDefault().getCommandLineArgs()); } 220 221 public void close() { 222 try { 223 if (writer != null) { 224 Writer tmpWriter = writer; 225 writer = null; 226 tmpWriter.close(); 227 } 228 } catch (IOException e) { 229 e.printStackTrace(); 230 } 231 } 232 233 237 protected void openFile() { 238 if (writer == null) { 239 if (outFile != null) { 240 try { 241 writer = logForStream(secureAction.getFileOutputStream(outFile, true)); 242 } catch (IOException e) { 243 writer = logForStream(System.err); 244 } 245 } else { 246 writer = logForStream(System.err); 247 } 248 } 249 } 250 251 254 protected void closeFile() { 255 if (outFile != null) { 256 if (writer != null) { 257 try { 258 writer.close(); 259 } catch (IOException e) { 260 e.printStackTrace(); 262 } 263 writer = null; 264 } 265 } 266 } 267 268 public void log(FrameworkEvent frameworkEvent) { 269 Bundle b = frameworkEvent.getBundle(); 270 Throwable t = frameworkEvent.getThrowable(); 271 String entry = b.getSymbolicName() == null ? b.getLocation() : b.getSymbolicName(); 272 int severity; 273 switch (frameworkEvent.getType()) { 274 case FrameworkEvent.INFO : 275 severity = FrameworkLogEntry.INFO; 276 break; 277 case FrameworkEvent.ERROR : 278 severity = FrameworkLogEntry.ERROR; 279 break; 280 case FrameworkEvent.WARNING : 281 severity = FrameworkLogEntry.WARNING; 282 break; 283 default : 284 severity = FrameworkLogEntry.OK; 285 } 286 FrameworkLogEntry logEntry = new FrameworkLogEntry(entry, severity, 0, "", 0, t, null); log(logEntry); 288 } 289 290 public synchronized void log(FrameworkLogEntry logEntry) { 291 if (logEntry == null) 292 return; 293 try { 294 checkLogFileSize(); 295 openFile(); 296 if (newSession) { 297 writeSession(); 298 newSession = false; 299 } 300 writeLog(0, logEntry); 301 writer.flush(); 302 } catch (Exception e) { 303 System.err.println("An exception occurred while writing to the platform log:"); e.printStackTrace(System.err); 306 System.err.println("Logging to the console instead."); try { 309 writer = logForStream(System.err); 310 writeLog(0, logEntry); 311 writer.flush(); 312 } catch (Exception e2) { 313 System.err.println("An exception occurred while logging to the console:"); e2.printStackTrace(System.err); 315 } 316 } finally { 317 closeFile(); 318 } 319 } 320 321 public synchronized void setWriter(Writer newWriter, boolean append) { 322 setOutput(null, newWriter, append); 323 } 324 325 public synchronized void setFile(File newFile, boolean append) throws IOException { 326 if (newFile != null && !newFile.equals(this.outFile)) { 327 readLogProperties(); 329 backupIdx = 0; 330 } 331 setOutput(newFile, null, append); 332 FrameworkProperties.setProperty(EclipseStarter.PROP_LOGFILE, newFile.getAbsolutePath()); 333 } 334 335 public synchronized File getFile() { 336 return outFile; 337 } 338 339 public void setConsoleLog(boolean consoleLog) { 340 this.consoleLog = consoleLog; 341 } 342 343 private void setOutput(File newOutFile, Writer newWriter, boolean append) { 344 if (newOutFile == null || !newOutFile.equals(this.outFile)) { 345 if (this.writer != null) { 346 try { 347 this.writer.close(); 348 } catch (IOException e) { 349 e.printStackTrace(); 350 } 351 this.writer = null; 352 } 353 File oldOutFile = this.outFile; 357 this.outFile = newOutFile; 358 this.writer = newWriter; 359 boolean copyFailed = false; 360 if (append && oldOutFile != null && oldOutFile.isFile()) { 361 Reader fileIn = null; 362 try { 363 openFile(); 364 fileIn = new InputStreamReader(secureAction.getFileInputStream(oldOutFile), "UTF-8"); copyReader(fileIn, this.writer); 366 } catch (IOException e) { 367 copyFailed = true; 368 e.printStackTrace(); 369 } finally { 370 if (fileIn != null) { 371 try { 372 fileIn.close(); 373 } catch (IOException e) { 374 e.printStackTrace(); 375 } 376 if (!copyFailed) 378 oldOutFile.delete(); 379 } 380 closeFile(); 381 } 382 } 383 } 384 } 385 386 private void copyReader(Reader reader, Writer aWriter) throws IOException { 387 char buffer[] = new char[1024]; 388 int count; 389 while ((count = reader.read(buffer, 0, buffer.length)) > 0) { 390 aWriter.write(buffer, 0, count); 391 } 392 } 393 394 399 protected String getDate(Date date) { 400 Calendar c = Calendar.getInstance(); 401 c.setTime(date); 402 StringBuffer sb = new StringBuffer (); 403 appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-'); 404 appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-'); 405 appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' '); 406 appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':'); 407 appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':'); 408 appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.'); 409 appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb); 410 return sb.toString(); 411 } 412 413 private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) { 414 pad = pad - 1; 415 if (pad == 0) 416 return buffer.append(Integer.toString(value)); 417 int padding = (int) Math.pow(10, pad); 418 if (value >= padding) 419 return buffer.append(Integer.toString(value)); 420 while (padding > value && padding > 1) { 421 buffer.append('0'); 422 padding = padding / 10; 423 } 424 buffer.append(value); 425 return buffer; 426 } 427 428 433 protected String getStackTrace(Throwable t) { 434 if (t == null) 435 return null; 436 437 StringWriter sw = new StringWriter(); 438 PrintWriter pw = new PrintWriter(sw); 439 440 t.printStackTrace(pw); 441 Throwable root = getRoot(t); 443 if (root != null) { 444 pw.println("Root exception:"); root.printStackTrace(pw); 446 } 447 return sw.toString(); 448 } 449 450 455 protected Writer logForStream(OutputStream output) { 456 try { 457 return new BufferedWriter(new OutputStreamWriter(output, "UTF-8")); } catch (UnsupportedEncodingException e) { 459 return new BufferedWriter(new OutputStreamWriter(output)); 460 } 461 } 462 463 471 protected void writeLog(int depth, FrameworkLogEntry entry) throws IOException { 472 writeEntry(depth, entry); 473 writeMessage(entry); 474 writeStack(entry); 475 476 FrameworkLogEntry[] children = entry.getChildren(); 477 if (children != null) { 478 for (int i = 0; i < children.length; i++) { 479 writeLog(depth + 1, children[i]); 480 } 481 } 482 } 483 484 492 protected void writeEntry(int depth, FrameworkLogEntry entry) throws IOException { 493 if (depth == 0) { 494 writeln(); write(ENTRY); 496 } else { 497 write(SUBENTRY); 498 writeSpace(); 499 write(Integer.toString(depth)); 500 } 501 writeSpace(); 502 write(entry.getEntry()); 503 if (entry.getSeverity() != 0 || entry.getBundleCode() != 0) { 504 writeSpace(); 505 write(Integer.toString(entry.getSeverity())); 506 writeSpace(); 507 write(Integer.toString(entry.getBundleCode())); 508 } 509 writeSpace(); 510 write(getDate(new Date ())); 511 writeln(); 512 } 513 514 519 protected void writeMessage(FrameworkLogEntry entry) throws IOException { 520 write(MESSAGE); 521 writeSpace(); 522 writeln(entry.getMessage()); 523 } 524 525 530 protected void writeStack(FrameworkLogEntry entry) throws IOException { 531 Throwable t = entry.getThrowable(); 532 if (t != null) { 533 String stack = getStackTrace(t); 534 write(STACK); 535 writeSpace(); 536 write(Integer.toString(entry.getStackCode())); 537 writeln(); 538 write(stack); 539 } 540 } 541 542 547 protected void write(String message) throws IOException { 548 if (message != null) { 549 writer.write(message); 550 if (consoleLog) 551 System.out.print(message); 552 } 553 } 554 555 560 protected void writeln(String s) throws IOException { 561 write(s); 562 writeln(); 563 } 564 565 569 protected void writeln() throws IOException { 570 write(LINE_SEPARATOR); 571 } 572 573 577 protected void writeSpace() throws IOException { 578 write(" "); } 580 581 586 protected boolean checkLogFileSize() { 587 if (maxLogSize == 0) 588 return true; 590 boolean isBackupOK = true; 591 if (outFile != null) { 592 if ((outFile.length() >> 10) > maxLogSize) { String logFilename = outFile.getAbsolutePath(); 594 595 String backupFilename = ""; if (logFilename.toLowerCase().endsWith(LOG_EXT)) { 598 backupFilename = logFilename.substring(0, logFilename.length() - LOG_EXT.length()) + BACKUP_MARK + backupIdx + LOG_EXT; 599 } else { 600 backupFilename = logFilename + BACKUP_MARK + backupIdx; 601 } 602 File backupFile = new File(backupFilename); 603 if (backupFile.exists()) { 604 if (!backupFile.delete()) { 605 System.err.println("Error when trying to delete old log file: " + backupFile.getName()); if (backupFile.renameTo(new File(backupFile.getAbsolutePath() + System.currentTimeMillis()))) { 607 System.err.println("So we rename it to filename: " + backupFile.getName()); } else { 609 System.err.println("And we also cannot rename it!"); isBackupOK = false; 611 } 612 } 613 } 614 615 boolean isRenameOK = outFile.renameTo(backupFile); 617 if (!isRenameOK) { 618 System.err.println("Error when trying to rename log file to backup one."); isBackupOK = false; 620 } 621 File newFile = new File(logFilename); 622 setOutput(newFile, null, false); 623 624 openFile(); 626 try { 627 writeSession(); 628 writeln(); 629 writeln("This is a continuation of log file " + backupFile.getAbsolutePath()); writeln("Created Time: " + getDate(new Date (System.currentTimeMillis()))); writer.flush(); 632 } catch (IOException ioe) { 633 ioe.printStackTrace(System.err); 634 } 635 closeFile(); 636 backupIdx = (++backupIdx) % maxLogFiles; 637 } 638 } 639 return isBackupOK; 640 } 641 642 645 protected void readLogProperties() { 646 String newMaxLogSize = secureAction.getProperty(PROP_LOG_SIZE_MAX); 647 if (newMaxLogSize != null) { 648 maxLogSize = Integer.parseInt(newMaxLogSize); 649 if (maxLogSize != 0 && maxLogSize < LOG_SIZE_MIN) { 650 maxLogSize = LOG_SIZE_MIN; 653 } 654 } 655 656 String newMaxLogFiles = secureAction.getProperty(PROP_LOG_FILE_MAX); 657 if (newMaxLogFiles != null) { 658 maxLogFiles = Integer.parseInt(newMaxLogFiles); 659 if (maxLogFiles < 1) { 660 maxLogFiles = DEFAULT_LOG_FILES; 662 } 663 } 664 } 665 } 666 | Popular Tags |