{"id":37021793,"url":"https://github.com/netmikey/logunit","last_synced_at":"2026-01-14T02:35:30.998Z","repository":{"id":45052009,"uuid":"175371280","full_name":"netmikey/logunit","owner":"netmikey","description":"A Java library for unit-testing logging.","archived":false,"fork":false,"pushed_at":"2023-06-01T21:52:12.000Z","size":107,"stargazers_count":45,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2023-09-21T20:15:35.309Z","etag":null,"topics":["java","logback","logging","slf4j","test","unit-testing"],"latest_commit_sha":null,"homepage":"","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/netmikey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-13T07:45:55.000Z","updated_at":"2023-07-20T06:31:11.000Z","dependencies_parsed_at":"2022-09-26T22:11:02.679Z","dependency_job_id":null,"html_url":"https://github.com/netmikey/logunit","commit_stats":null,"previous_names":[],"tags_count":6,"template":null,"template_full_name":null,"purl":"pkg:github/netmikey/logunit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netmikey%2Flogunit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netmikey%2Flogunit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netmikey%2Flogunit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netmikey%2Flogunit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/netmikey","download_url":"https://codeload.github.com/netmikey/logunit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netmikey%2Flogunit/sbom","scorecard":{"id":680894,"data":{"date":"2025-08-11","repo":{"name":"github.com/netmikey/logunit","commit":"04bc0e3092bae4ad3a9d9e0ef985d5b128f2ff34"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 2/24 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/netmikey/logunit/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/netmikey/logunit/build.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yaml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/netmikey/logunit/build.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yaml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/netmikey/logunit/build.yaml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T23:07:52.536Z","repository_id":45052009,"created_at":"2025-08-21T23:07:52.537Z","updated_at":"2025-08-21T23:07:52.537Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","logback","logging","slf4j","test","unit-testing"],"created_at":"2026-01-14T02:35:30.397Z","updated_at":"2026-01-14T02:35:30.982Z","avatar_url":"https://github.com/netmikey.png","language":"Java","readme":"LogUnit\n=======\n\n[![Build Status](https://github.com/netmikey/logunit/actions/workflows/build.yaml/badge.svg)](https://github.com/netmikey/logunit/actions)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.netmikey.logunit/logunit-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.netmikey.logunit/logunit-core)\n\nA Java library for unit-testing logging.\n\n\n## Purpose\n\nSometimes, writing specific information into its log(file) is an important part of an application's functionality. As such, it's probably a good idea to cover that behavior in the application's unit tests.\n\nAlthough there are other solutions to achieve this (like e.g. using mocks and test for the methods to be called), LogUnit aims at testing on another level: right within the logging framework, so you can still see all your logs while testing. No matter how you generate your log messages in your project, if they end up in one of the supported logging frameworks, you can use LogUnit.\n\n\n## Requirements\n\n- Java 8 or above\n- JUnit 5\n- You must be using one of the supported logging frameworks at test runtime\n- You may use [Slf4j](https://www.slf4j.org) or your logging framework's native API (or anything else that makes your log events end up in your logging framework at runtime)\n\n### Supported logging frameworks\n\n- java.util.logging (the JDK's logging API)\n- [Logback](https://logback.qos.ch)\n- [Log4j2](https://logging.apache.org/log4j/2.x/)\n\n\n## Limitations\n\nBecause of the very nature of how logging frameworks work, LogUnit cannot be used with parallel test execution. See [this issue](https://github.com/netmikey/logunit/issues/1) for a more detailed explanation.\n\n\n## Installation\n\nAdd LogUnit to your project's dependencies.\n\n* Declare `logunit-core` as compile-time dependency\n* Declare the binding-specific module (e.g. `logunit-logback`, `logunit-log4j2` or `logunit-jul`) as test-runtime dependency\n\n```\ndependencies {\n    ...\n    testImplementation(\"io.github.netmikey.logunit:logunit-core:2.0.0\")\n\n    // Choose one (and only one) of the following:\n\n    // for Logback:\n    // testRuntimeOnly(\"io.github.netmikey.logunit:logunit-logback:2.0.0\")\n\n    // for Log4j2:\n    // testRuntimeOnly(\"io.github.netmikey.logunit:logunit-log4j2:2.0.0\")\n\n    // for JUL:\n    // testRuntimeOnly(\"io.github.netmikey.logunit:logunit-jul:2.0.0\")\n}\n```\n\n\n## Usage\n\nLet's say we have a unit to be tested that looks something like this:\n\n``` Java\npublic class MyModule {\n    private static final LOG = LoggerFactory.getLogger(MyModule.class);\n\n    public void bobDoSomething() {\n        // ...\n        LOG.info(\"Bob did something.\");\n    }\n}\n```\n\nWithin `MyModule`'s test class, we register a `LogCapturer` for the logger of type `MyModule` as a JUnit extension:\n\n``` java\npublic class MyModuleTest {\n\n    @RegisterExtension\n    LogCapturer logs = LogCapturer.create().captureForType(MyModule.class);\n\n```\n\nIn our test method, we can use this extension to query the log events (messages) that have been emitted by the `MyModule` logger:\n\n``` java\n@org.junit.jupiter.api.Test\npublic void testBobDoSomethingLogging() {\n\n    MyModule tested = new MyModule();\n    tested.bobDoSomething();\n\n    // Run assertions on the logged messages\n    logs.assertContains(\"Bob did something\");\n}\n```\n\nBy default, only the log levels `INFO` and above are being captured. You can capture multiple loggers in a single `LogCapturer` and raise or lower the threshold log level to be captured per logger like this:\n\n``` java\n    @RegisterExtension\n    LogCapturer logs = LogCapturer.create()\n        .captureForType(MyModule.class, Level.WARN)\n        .captureForLogger(\"LOGGER_NAME\", Level.DEBUG);\n```\n\nSee [LogCapturerWithLogbackTest.java](https://github.com/netmikey/logunit/blob/master/logunit-logback/src/test/java/io/github/netmikey/logunit/logback/LogCapturerWithLogbackTest.java) for more in-depth examples.\n\n\n## Architecture\n\nLogUnit wants to remain as transparent and easy to setup as possible. That means your unit tests' logs should stay the way they are (or at least as close as possible). As such, we don't want to bring and force our own Slf4j binding implementation onto consuming projects.\n\nTherefor, LogUnit's architecture is similar to Slf4j's: At it's core, it uses the Slf4j API but in order to work at runtime, it provides binding-specific modules for hooking into the most popular logging frameworks.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetmikey%2Flogunit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetmikey%2Flogunit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetmikey%2Flogunit/lists"}