Commit 2cf6a9b6 authored by Skylot's avatar Skylot

gui: fixed object reference holding by LogCollector (#302)

parent 5b712e8d
......@@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.JadxSettingsAdapter;
import jadx.gui.ui.MainWindow;
import jadx.gui.utils.LogCollector;
import jadx.gui.utils.logs.LogCollector;
public class JadxGUI {
private static final Logger LOG = LoggerFactory.getLogger(JadxGUI.class);
......
......@@ -7,8 +7,9 @@ import ch.qos.logback.classic.Level;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import jadx.gui.settings.JadxSettings;
import jadx.gui.utils.LogCollector;
import jadx.gui.utils.NLS;
import jadx.gui.utils.logs.ILogListener;
import jadx.gui.utils.logs.LogCollector;
class LogViewer extends JDialog {
private static final long serialVersionUID = -2188700277429054641L;
......@@ -67,7 +68,7 @@ class LogViewer extends JDialog {
LogCollector logCollector = LogCollector.getInstance();
logCollector.resetListener();
textPane.setText("");
logCollector.registerListener(new LogCollector.ILogListener() {
logCollector.registerListener(new ILogListener() {
@Override
public Level getFilterLevel() {
return level;
......@@ -75,10 +76,7 @@ class LogViewer extends JDialog {
@Override
public void onAppend(final String logStr) {
SwingUtilities.invokeLater(() -> {
textPane.append(logStr);
textPane.updateUI();
});
SwingUtilities.invokeLater(() -> textPane.append(logStr));
}
});
}
......
package jadx.gui.utils.logs;
import ch.qos.logback.classic.Level;
public interface ILogListener {
Level getFilterLevel();
void onAppend(String logStr);
}
package jadx.gui.utils;
package jadx.gui.utils.logs;
import java.util.Deque;
import java.util.LinkedList;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.read.CyclicBufferAppender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.LoggerFactory;
public class LogCollector extends CyclicBufferAppender<ILoggingEvent> {
private static LogCollector instance = new LogCollector();
public class LogCollector extends AppenderBase<ILoggingEvent> {
public static final int BUFFER_SIZE = 5000;
private static final LogCollector INSTANCE = new LogCollector();
public static LogCollector getInstance() {
return instance;
return INSTANCE;
}
public static void register() {
......@@ -27,18 +31,11 @@ public class LogCollector extends CyclicBufferAppender<ILoggingEvent> {
layout.setPattern("%-5level: %msg%n");
layout.start();
instance.setContext(loggerContext);
instance.setLayout(layout);
instance.start();
rootLogger.addAppender(instance);
}
public interface ILogListener {
Level getFilterLevel();
INSTANCE.setContext(loggerContext);
INSTANCE.setLayout(layout);
INSTANCE.start();
void onAppend(String logStr);
rootLogger.addAppender(INSTANCE);
}
private Layout<ILoggingEvent> layout;
......@@ -46,20 +43,29 @@ public class LogCollector extends CyclicBufferAppender<ILoggingEvent> {
@Nullable
private ILogListener listener;
private final Deque<LogEvent> buffer = new LinkedList<>();
public LogCollector() {
setName("LogCollector");
setMaxSize(5000);
}
@Override
protected void append(ILoggingEvent event) {
super.append(event);
if (listener != null
&& event.getLevel().isGreaterOrEqual(listener.getFilterLevel())) {
synchronized (this) {
listener.onAppend(layout.doLayout(event));
Level level = event.getLevel();
String msg = layout.doLayout(event);
store(level, msg);
if (listener != null && level.isGreaterOrEqual(listener.getFilterLevel())) {
listener.onAppend(msg);
}
}
}
private void store(Level level, String msg) {
buffer.addLast(new LogEvent(level, msg));
if (buffer.size() > BUFFER_SIZE) {
buffer.pollFirst();
}
}
public void setLayout(Layout<ILoggingEvent> layout) {
......@@ -79,11 +85,9 @@ public class LogCollector extends CyclicBufferAppender<ILoggingEvent> {
private String init(Level filterLevel) {
StringBuilder sb = new StringBuilder();
int length = getLength();
for (int i = 0; i < length; i++) {
ILoggingEvent event = get(i);
for (LogEvent event : buffer) {
if (event.getLevel().isGreaterOrEqual(filterLevel)) {
sb.append(layout.doLayout(event));
sb.append(event.getMsg());
}
}
return sb.toString();
......
package jadx.gui.utils.logs;
import ch.qos.logback.classic.Level;
final class LogEvent {
private final Level level;
private final String msg;
LogEvent(Level level, String msg) {
this.level = level;
this.msg = msg;
}
public Level getLevel() {
return level;
}
public String getMsg() {
return msg;
}
@Override
public String toString() {
return level + ": " + msg;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment