Add logging tab

This commit is contained in:
0xb00bface 2020-08-09 18:29:04 +02:00
parent a0779c118d
commit 2126b61e99
6 changed files with 148 additions and 1 deletions

View File

@ -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 3.8.5
======================== ========================
* Fixed Stripchat followed tab. It didn't work, if you have many favorited * Fixed Stripchat followed tab. It didn't work, if you have many favorited

View File

@ -71,7 +71,7 @@
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<scope>runtime</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.openjfx</groupId> <groupId>org.openjfx</groupId>

View File

@ -61,6 +61,7 @@ import ctbrec.ui.tabs.RecordingsTab;
import ctbrec.ui.tabs.SiteTab; import ctbrec.ui.tabs.SiteTab;
import ctbrec.ui.tabs.TabSelectionListener; import ctbrec.ui.tabs.TabSelectionListener;
import ctbrec.ui.tabs.UpdateTab; import ctbrec.ui.tabs.UpdateTab;
import ctbrec.ui.tabs.logging.LoggingTab;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.HostServices; import javafx.application.HostServices;
import javafx.application.Platform; import javafx.application.Platform;
@ -191,6 +192,7 @@ public class CamrecApplication extends Application {
tabPane.getTabs().add(new NewsTab()); tabPane.getTabs().add(new NewsTab());
tabPane.getTabs().add(new DonateTabFx()); tabPane.getTabs().add(new DonateTabFx());
tabPane.getTabs().add(new HelpTab()); tabPane.getTabs().add(new HelpTab());
tabPane.getTabs().add(new LoggingTab());
switchToStartTab(); switchToStartTab();
writeColorSchemeStyleSheet(); writeColorSchemeStyleSheet();

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -8,6 +8,12 @@
</pattern> </pattern>
</encoder> </encoder>
</appender> </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" <appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender"> class="ch.qos.logback.core.rolling.RollingFileAppender">
@ -32,6 +38,7 @@
<root level="DEBUG"> <root level="DEBUG">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
<appender-ref ref="GUI" />
</root> </root>
<logger name="ctbrec.LoggingInterceptor" level="INFO"/> <logger name="ctbrec.LoggingInterceptor" level="INFO"/>