package org.ovirt.engine.ui.common.logging;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import org.ovirt.engine.ui.common.system.ClientStorage;
import org.ovirt.engine.ui.common.utils.AddOnlyRingBuffer;
import org.ovirt.engine.ui.common.utils.AddOnlyRingBuffer.LinearBuffer;
import com.google.gwt.logging.client.TextLogFormatter;
import com.google.inject.Inject;
/**
* Log handler that uses {@link ClientStorage} for persisting log records.
*/
public class LocalStorageLogHandler extends Handler implements LinearBuffer<String>, ClientLogProvider {
private static final String KEY_LOG_PREFIX = "Log_"; //$NON-NLS-1$
private static final String KEY_HEAD = "LogHead"; //$NON-NLS-1$
private static final String KEY_SIZE = "LogSize"; //$NON-NLS-1$
// Maximum number of log records to keep in underlying storage
private static final int LOG_CAPACITY = 100;
private final ClientStorage clientStorage;
private final AddOnlyRingBuffer<String> logBuffer;
private boolean active = false;
@Inject
public LocalStorageLogHandler(ClientStorage clientStorage) {
this.clientStorage = clientStorage;
this.logBuffer = new AddOnlyRingBuffer<>(LOG_CAPACITY, this);
}
public void init() {
setFormatter(new TextLogFormatter(true));
setLevel(Level.ALL);
setActive(true);
}
public void setActive(boolean active) {
this.active = active;
if (active) {
// Read logBuffer state
int newHead = readInt(KEY_HEAD, 0);
int newSize = readInt(KEY_SIZE, 0);
logBuffer.reset(newHead, newSize);
}
}
int readInt(String key, int defaultValue) {
try {
return Integer.parseInt(clientStorage.getLocalItem(key));
} catch (NumberFormatException e) {
return defaultValue;
}
}
void writeInt(String key, int value) {
clientStorage.setLocalItem(key, String.valueOf(value));
}
@Override
public void publish(LogRecord record) {
if (active && isLoggable(record)) {
// Add message to logBuffer
String message = getFormatter().format(record);
logBuffer.add(message);
// Write logBuffer state
writeInt(KEY_HEAD, logBuffer.head());
writeInt(KEY_SIZE, logBuffer.size());
}
}
@Override
public boolean isLoggable(LogRecord record) {
return super.isLoggable(record) && clientStorage.isWebStorageAvailable();
}
@Override
public void flush() {
// No action needed
}
@Override
public void close() {
// No action needed
}
@Override
public void write(int index, String element) {
clientStorage.setLocalItem(getLogRecordKey(index), element);
}
@Override
public String read(int index) {
return clientStorage.getLocalItem(getLogRecordKey(index));
}
@Override
public List<String> getLogRecords() {
return logBuffer.list();
}
String getLogRecordKey(int index) {
return KEY_LOG_PREFIX + index;
}
}