blob: 11796b390121aa8abc9c301e9409e20d0aaf4cde [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000,2002 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM - Initial API and implementation
******************************************************************************/
package org.eclipse.core.internal.runtime;
import java.io.*;
import java.text.DateFormat;
import java.util.*;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
/**
* A log writer that writes log entries in XML format.
* See PlatformLogReader for reading logs back into memory.
*/
public class PlatformLogWriter implements ILogListener {
protected File logFile = null;
protected Writer log = null;
protected boolean newSession = true;
protected static final String SESSION = "!SESSION";//$NON-NLS-1$
protected static final String ENTRY = "!ENTRY";//$NON-NLS-1$
protected static final String SUBENTRY = "!SUBENTRY";//$NON-NLS-1$
protected static final String MESSAGE = "!MESSAGE";//$NON-NLS-1$
protected static final String STACK = "!STACK";//$NON-NLS-1$
protected static final String LINE_SEPARATOR;
protected static final String TAB_STRING = "\t";//$NON-NLS-1$
static {
String s = System.getProperty("line.separator");//$NON-NLS-1$
LINE_SEPARATOR = s == null ? "\n" : s;//$NON-NLS-1$
}
public PlatformLogWriter(File file) {
this.logFile = file;
}
/**
* This constructor should only be used to pass System.out .
*/
public PlatformLogWriter(OutputStream out) {
this.log = logForStream(out);
}
protected void closeLogFile() throws IOException {
try {
if (log != null) {
log.flush();
log.close();
}
} finally {
log = null;
}
}
/**
* @see ILogListener#logging.
*/
public synchronized void logging(IStatus status, String plugin) {
// thread safety: (Concurrency003)
if (logFile != null)
openLogFile();
if (log == null)
log = logForStream(System.err);
try {
try {
write(status, 0);
} finally {
if (logFile != null)
closeLogFile();
else
log.flush();
}
} catch (Exception e) {
System.err.println("An exception occurred while writing to the platform log:");//$NON-NLS-1$
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.err.println("Logging to the console instead.");//$NON-NLS-1$
//we failed to write, so dump log entry to console instead
try {
log = logForStream(System.err);
write(status, 0);
log.flush();
} catch (Exception e2) {
System.err.println("An exception occurred while logging to the console:");//$NON-NLS-1$
System.err.println(e.getClass().getName() + ": " + e.getMessage());
}
} finally {
log = null;
}
}
protected void openLogFile() {
try {
log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), "UTF-8"));
if (newSession) {
writeln(SESSION);
newSession = false;
}
} catch (IOException e) {
// there was a problem opening the log file so log to the console
log = logForStream(System.err);
}
}
protected Writer logForStream(OutputStream output) {
try {
return new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));//$NON-NLS-1$
} catch (UnsupportedEncodingException e) {
return new BufferedWriter(new OutputStreamWriter(output));
}
}
/**
* Writes the given string to the log, followed by the line terminator string.
*/
protected void writeln(String s) throws IOException {
write(s);
writeln();
}
/**
* Shuts down the platform log.
*/
public synchronized void shutdown() {
try {
if (logFile != null) {
closeLogFile();
logFile = null;
} else {
if (log != null) {
Writer old = log;
log = null;
old.flush();
old.close();
}
}
} catch (Exception e) {
//we've shutdown the log, so not much else we can do!
e.printStackTrace();
}
}
protected void write(Throwable throwable) throws IOException {
if (throwable == null)
return;
write(STACK);
writeSpace();
StringBuffer buffer = new StringBuffer();
throwable.printStackTrace(new PrintWriter(log));
}
protected void write(IStatus status, int depth) throws IOException {
if (depth == 0)
write(ENTRY);
else
write(SUBENTRY);
if (depth != 0) {
writeSpace();
write(Integer.toString(depth));
}
writeSpace();
write(status.getPlugin());
writeSpace();
write(Integer.toString(status.getSeverity()));
writeSpace();
write(Integer.toString(status.getCode()));
writeSpace();
write(new Date().toString());
writeln();
write(MESSAGE);
writeSpace();
writeln(status.getMessage());
write(status.getException());
if (status.isMultiStatus()) {
IStatus[] children = status.getChildren();
for (int i = 0; i < children.length; i++) {
write(children[i], depth+1);
}
}
}
protected void writeln() throws IOException {
write(LINE_SEPARATOR);
}
protected void write(String message) throws IOException {
log.write(message);
}
protected void writeSpace() throws IOException {
write(" ");//$NON-NLS-1$
}
}