A simple JavaFX log viewer that can be integrated to any Java application (it is currently used by the QuPath software) and that displays live logs generated using the SLF4J API.
The project contains three UI implementations:
logviewer-ui-main
) where logs are displayed using a TableView and can be filtered by level, message, and thread. It is also possible to set the minimum log level. A text area at the bottom of the application provides more details about a log.logviewer-ui-textarea
) where logs are displayed on a console-like interface.logviewer-ui-richtextfx
) which adds coloring support.Three logging frameworks are currently supported: the JavaTM 2 platform's core logging facilities, Logback, and reload4j.
The repository contains eight subprojects:
logviewer-logging-jdk
), Logback (logviewer-logging-logback
), and reload4j (logviewer-logging-reload4j
) logging frameworks.logviewer-api
) used internally to link a UI implementation to a logging framework.logviewer-app
) to start one of the UI implementation as a standalone application. It is mainly used for development.To use the log viewer, choose one of the UI implementation, one of the logging framework, and install them:
//build.gradle
dependencies {
def logViewerVersion = "0.1.0-SNAPSHOT"
// Choose one of those UI implementation:
implementation "io.github.qupath:logviewer-ui-main:${logViewerVersion}"
implementation "io.github.qupath:logviewer-ui-textarea:${logViewerVersion}"
implementation "io.github.qupath:logviewer-ui-richtextfx:${logViewerVersion}"
// Choose one of those logging framework:
implementation "io.github.qupath:logviewer-logging-jdk:${logViewerVersion}"
implementation "io.github.qupath:logviewer-logging-logback:${logViewerVersion}"
implementation "io.github.qupath:logviewer-logging-reload4j:${logViewerVersion}"
}
If you don't use Java modules in your application, you also have to import the javafx.controls
and javafx.fxml
modules:
//build.gradle
javafx {
version = ...
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
Then, create the chosen UI implementation. Here is an example with log-viewer
:
//TestApp.java
public class TestApp extends Application {
private final static Logger logger = LoggerFactory.getLogger(TestApp.class);
public static void main(String[] args) {
Application.launch(TestApp.class, args);
}
@Override
public void start(Stage primaryStage) throws IOException {
LogViewer logviewer = new LogViewer();
Scene scene = new Scene(logviewer, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
// These messages should appear in the log viewer
logger.info("Here's my first log message, for information");
logger.error("Here's an error");
}
}
All messages logged with the SLF4J API will automatically be displayed by the log viewer (if they are not filtered).
Take a look at the code of the logviewer-app
subproject to see how to use the other UI implementations.
You can build every module of the log viewer from source with:
./gradlew clean build
The outputs will be under each subproject's build/libs
.
The easiest way to develop the application is to use the logviewer-app
subproject.
It starts an application that uses one of the UI implementation depending on the provided arguments:
--app=<app>
specifies which UI implementation to use. <app>
can be one of:
main
(selected by default) for log-viewer-ui-main
.textarea
for log-viewer-ui-textarea
.richtextfx
for log-viewer-ui-richtextfx
.-t
indicates whether to log random messages.Here are two example:
./gradlew logviewer-app:run --args="--app=main" // starts the log viewer. No logs are generated
./gradlew logviewer-app:run --args="--app=richtextfx -t" // starts the richtextfx implementation and log random messages
If you want to add a new UI implementation:
logviewer-api
.Create a class that implements the LoggerListener
interface of the logviewer-api
project and make it listen to log messages:
public class UiImplementation implements LoggerListener {
public UiImplementation() {
Optional<LoggerManager> loggerManagerOptional = getCurrentLoggerManager();
if (loggerManagerOptional.isPresent()) {
loggerManagerOptional.get().addListener(this);
} else {
throw new RuntimeException("No logging manager found");
}
}
@Override
public void addLogMessage(LogMessage logMessage) {
// This method will be called each time a message is logged
}
}
If you want to add a new logging framework:
logviewer-api
.LoggerManager
interface of the logviewer-api
project and override the required methods.