Add logging tab
This commit is contained in:
parent
a0779c118d
commit
2126b61e99
|
@ -1,3 +1,8 @@
|
|||
3.8.6
|
||||
========================
|
||||
* Added setting to disable the online check for paused models
|
||||
* Added tab which shows the log output
|
||||
|
||||
3.8.5
|
||||
========================
|
||||
* Fixed Stripchat followed tab. It didn't work, if you have many favorited
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
|
|
|
@ -61,6 +61,7 @@ import ctbrec.ui.tabs.RecordingsTab;
|
|||
import ctbrec.ui.tabs.SiteTab;
|
||||
import ctbrec.ui.tabs.TabSelectionListener;
|
||||
import ctbrec.ui.tabs.UpdateTab;
|
||||
import ctbrec.ui.tabs.logging.LoggingTab;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.HostServices;
|
||||
import javafx.application.Platform;
|
||||
|
@ -191,6 +192,7 @@ public class CamrecApplication extends Application {
|
|||
tabPane.getTabs().add(new NewsTab());
|
||||
tabPane.getTabs().add(new DonateTabFx());
|
||||
tabPane.getTabs().add(new HelpTab());
|
||||
tabPane.getTabs().add(new LoggingTab());
|
||||
|
||||
switchToStartTab();
|
||||
writeColorSchemeStyleSheet();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package ctbrec.ui.tabs.logging;
|
||||
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
import ch.qos.logback.core.ConsoleAppender;
|
||||
import ctbrec.event.EventBusHolder;
|
||||
|
||||
public class CtbrecAppender extends ConsoleAppender<LoggingEvent> {
|
||||
|
||||
@Override
|
||||
protected void append(LoggingEvent event) {
|
||||
EventBusHolder.BUS.post(event);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package ctbrec.ui.tabs.logging;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.qos.logback.classic.spi.IThrowableProxy;
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
import ch.qos.logback.classic.spi.StackTraceElementProxy;
|
||||
import ctbrec.event.EventBusHolder;
|
||||
import ctbrec.ui.controls.SearchBox;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
|
||||
public class LoggingTab extends Tab {
|
||||
|
||||
private static final int HISTORY_LENGTH = 10_000;
|
||||
private SearchBox filter = new SearchBox();
|
||||
private TableView<LoggingEvent> table = new TableView<>();
|
||||
private ObservableList<LoggingEvent> history = FXCollections.observableList(Collections.synchronizedList(new LinkedList<>()));
|
||||
private ObservableList<LoggingEvent> filteredEvents = FXCollections.observableArrayList();
|
||||
private DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
private volatile boolean tabClosed = false;
|
||||
private Object eventBustSubscriber = new Object() {
|
||||
@Subscribe
|
||||
public void publishLoggingEevent(LoggingEvent event) {
|
||||
if (!tabClosed) {
|
||||
Platform.runLater(() -> {
|
||||
history.add(event);
|
||||
if (history.size() > HISTORY_LENGTH - 1) {
|
||||
history.remove(0);
|
||||
}
|
||||
filter();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void filter() {
|
||||
filteredEvents.clear();
|
||||
filteredEvents.addAll(history.stream().filter(evt -> {
|
||||
String q = filter.getText().toLowerCase();
|
||||
return evt.getLevel().toString().toLowerCase().contains(q)
|
||||
|| createLogMessage(evt).toLowerCase().contains(q);
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public LoggingTab() {
|
||||
setText("Logging");
|
||||
subscribeToEventBus();
|
||||
|
||||
table = new TableView<>(filteredEvents);
|
||||
|
||||
int idx = 0;
|
||||
TableColumn<LoggingEvent, String> level = createTableColumn("Level", 65, idx++);
|
||||
level.setCellValueFactory(cdf -> new SimpleStringProperty(cdf.getValue().getLevel().toString()));
|
||||
table.getColumns().add(level);
|
||||
|
||||
TableColumn<LoggingEvent, String> time = createTableColumn("Timestamp", 200, idx++);
|
||||
time.setCellValueFactory(cdf -> {
|
||||
Instant instant = Instant.ofEpochMilli(cdf.getValue().getTimeStamp());
|
||||
return new SimpleStringProperty(instant.atZone(ZoneId.systemDefault()).format(timeFormatter));
|
||||
});
|
||||
table.getColumns().add(time);
|
||||
|
||||
TableColumn<LoggingEvent, String> msg = createTableColumn("Message", 2000, idx++);
|
||||
msg.setCellValueFactory(cdf -> new SimpleStringProperty(createLogMessage(cdf.getValue())));
|
||||
table.getColumns().add(msg);
|
||||
|
||||
BorderPane layout = new BorderPane();
|
||||
BorderPane.setMargin(table, new Insets(10));
|
||||
BorderPane.setMargin(filter, new Insets(10, 10, 0, 10));
|
||||
layout.setCenter(table);
|
||||
layout.setTop(filter);
|
||||
|
||||
setContent(layout);
|
||||
setOnClosed(evt -> {
|
||||
EventBusHolder.BUS.unregister(eventBustSubscriber);
|
||||
tabClosed = true;
|
||||
});
|
||||
|
||||
filter.setPromptText("Search");
|
||||
filter.textProperty().addListener( (observableValue, oldValue, newValue) -> filter());
|
||||
}
|
||||
|
||||
private String createLogMessage(LoggingEvent evt) {
|
||||
StringBuilder sb = new StringBuilder(evt.getFormattedMessage());
|
||||
if(evt.getThrowableProxy() != null) {
|
||||
IThrowableProxy throwableProxy = evt.getThrowableProxy();
|
||||
sb.append('\n').append(throwableProxy.getClassName()).append(':').append(' ').append(throwableProxy.getMessage());
|
||||
for (StackTraceElementProxy step : throwableProxy.getStackTraceElementProxyArray()) {
|
||||
sb.append('\n').append('\t').append(step.getSTEAsString());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private <T> TableColumn<LoggingEvent, T> createTableColumn(String text, int width, int idx) {
|
||||
TableColumn<LoggingEvent, T> tc = new TableColumn<>(text);
|
||||
tc.setPrefWidth(width);
|
||||
tc.setUserData(idx);
|
||||
return tc;
|
||||
}
|
||||
|
||||
private void subscribeToEventBus() {
|
||||
EventBusHolder.BUS.register(eventBustSubscriber);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,12 @@
|
|||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="GUI" class="ctbrec.ui.tabs.logging.CtbrecAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>ctbrec.log</file>
|
||||
|
@ -32,6 +38,7 @@
|
|||
<root level="DEBUG">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="GUI" />
|
||||
</root>
|
||||
|
||||
<logger name="ctbrec.LoggingInterceptor" level="INFO"/>
|
||||
|
|
Loading…
Reference in New Issue