{"id":18456634,"url":"https://github.com/qupath/log-viewer","last_synced_at":"2025-04-08T04:35:02.241Z","repository":{"id":176956234,"uuid":"623405492","full_name":"qupath/log-viewer","owner":"qupath","description":null,"archived":false,"fork":false,"pushed_at":"2024-09-10T07:52:35.000Z","size":1090,"stargazers_count":5,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-23T06:41:25.486Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qupath.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-04T09:59:54.000Z","updated_at":"2024-09-10T07:51:44.000Z","dependencies_parsed_at":"2024-03-28T16:04:35.359Z","dependency_job_id":"5f47a0a3-1277-45ae-9a64-b2b201585d58","html_url":"https://github.com/qupath/log-viewer","commit_stats":null,"previous_names":["qupath/log-viewer"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qupath%2Flog-viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qupath%2Flog-viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qupath%2Flog-viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qupath%2Flog-viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qupath","download_url":"https://codeload.github.com/qupath/log-viewer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247779795,"owners_count":20994569,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T08:12:19.523Z","updated_at":"2025-04-08T04:35:01.262Z","avatar_url":"https://github.com/qupath.png","language":"Java","readme":"# Log Viewer\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/logviewer.png\" height=\"200\" alt=\"Log viewer\"\u003e\n\u003c/p\u003e\n\nA simple JavaFX log viewer that can be integrated to any Java application (it is currently used by the [QuPath](https://qupath.github.io/) software) and that displays live logs generated using the [SLF4J API](https://www.slf4j.org/).\n\nThe project contains three UI implementations:\n* An advanced user interface (`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.\n* A simple text area (`logviewer-ui-textarea`) where logs are displayed on a console-like interface.\n* A rich text area (`logviewer-ui-richtextfx`) which adds coloring support.\n\nThree logging frameworks are currently supported: the [JavaTM 2 platform's core logging facilities](https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html), [Logback](https://logback.qos.ch/), and [reload4j](https://reload4j.qos.ch/).\n\n## Installing\nThe repository contains eight subprojects:\n* Three subprojects containing UI implementations, as described above.\n* Three subprojects adding support for the Java (`logviewer-logging-jdk`), Logback (`logviewer-logging-logback`), and reload4j (`logviewer-logging-reload4j`) logging frameworks.\n* One subproject (`logviewer-api`) used internally to link a UI implementation to a logging framework.\n* One subproject (`logviewer-app`) to start one of the UI implementation as a standalone application. It is mainly used for development.\n\nTo use the log viewer, choose one of the UI implementation, one of the logging framework, and install them:\n```groovy\n//build.gradle\n\ndependencies {\n  def logViewerVersion = \"0.1.0-SNAPSHOT\"\n\n  // Choose one of those UI implementation:\n  implementation \"io.github.qupath:logviewer-ui-main:${logViewerVersion}\"\n  implementation \"io.github.qupath:logviewer-ui-textarea:${logViewerVersion}\"\n  implementation \"io.github.qupath:logviewer-ui-richtextfx:${logViewerVersion}\"\n\n  // Choose one of those logging framework:\n  implementation \"io.github.qupath:logviewer-logging-jdk:${logViewerVersion}\"\n  implementation \"io.github.qupath:logviewer-logging-logback:${logViewerVersion}\"\n  implementation \"io.github.qupath:logviewer-logging-reload4j:${logViewerVersion}\"\n}\n```\n\nIf you don't use Java modules in your application, you also have to import the `javafx.controls` and `javafx.fxml` modules:\n```groovy\n//build.gradle\n\njavafx {\n    version = ...\n    modules = [ 'javafx.controls', 'javafx.fxml' ]\n}\n```\n\nThen, create the chosen UI implementation. Here is an example with `log-viewer`:\n```java\n//TestApp.java\n\npublic class TestApp extends Application {\n    private final static Logger logger = LoggerFactory.getLogger(TestApp.class);\n    \n    public static void main(String[] args) {\n        Application.launch(TestApp.class, args);\n    }\n    \n    @Override\n    public void start(Stage primaryStage) throws IOException {\n        LogViewer logviewer = new LogViewer();\n        Scene scene = new Scene(logviewer, 800, 600);\n        primaryStage.setScene(scene);\n        primaryStage.show();\n\n        // These messages should appear in the log viewer\n        logger.info(\"Here's my first log message, for information\");\n        logger.error(\"Here's an error\");\n    }\n}\n```\nAll messages logged with the SLF4J API will automatically be displayed by the log viewer (if they are not filtered).\n\nTake a look at the code of the `logviewer-app` subproject to see how to use the other UI implementations.\n\n## Building\nYou can build every module of the log viewer from source with:\n```shell\n./gradlew clean build\n```\nThe outputs will be under each subproject's `build/libs`.\n\n## Developing\nThe easiest way to develop the application is to use the `logviewer-app` subproject.\nIt starts an application that uses one of the UI implementation depending on the provided arguments:\n* `--app=\u003capp\u003e` specifies which UI implementation to use. `\u003capp\u003e` can be one of:\n  * `main` (selected by default) for `log-viewer-ui-main`.\n  * `textarea` for `log-viewer-ui-textarea`.\n  * `richtextfx` for `log-viewer-ui-richtextfx`.\n* `-t` indicates whether to log random messages.\n\nHere are two example:\n```shell\n./gradlew logviewer-app:run --args=\"--app=main\"          // starts the log viewer. No logs are generated\n./gradlew logviewer-app:run --args=\"--app=richtextfx -t\" // starts the richtextfx implementation and log random messages\n```\n\nIf you want to add a new UI implementation:\n* Create a dependency on `logviewer-api`.\n* Create a class that implements the `LoggerListener` interface of the `logviewer-api` project and make it listen to log messages:\n```java\npublic class UiImplementation implements LoggerListener {\n    public UiImplementation() {\n        Optional\u003cLoggerManager\u003e loggerManagerOptional = getCurrentLoggerManager();\n        if (loggerManagerOptional.isPresent()) {\n            loggerManagerOptional.get().addListener(this);\n        } else {\n            throw new RuntimeException(\"No logging manager found\");\n        }\n    }\n\n    @Override\n    public void addLogMessage(LogMessage logMessage) {\n        // This method will be called each time a message is logged\n    }\n}\n```\n\nIf you want to add a new logging framework:\n* Create a dependency on `logviewer-api`.\n* Create a class that implements the `LoggerManager` interface of the `logviewer-api` project and override the required methods.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqupath%2Flog-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqupath%2Flog-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqupath%2Flog-viewer/lists"}