{"id":21519826,"url":"https://github.com/hkupty/penna","last_synced_at":"2025-08-10T06:45:00.564Z","repository":{"id":158435587,"uuid":"602090005","full_name":"hkupty/penna","owner":"hkupty","description":"Opinionated SLF4J backend that logs natively to json","archived":false,"fork":false,"pushed_at":"2025-07-16T19:54:21.000Z","size":3008,"stargazers_count":49,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"dev/0.9","last_synced_at":"2025-07-16T20:11:54.905Z","etag":null,"topics":["java","java-library","java-logging","json-logging","jvm","jvm-logging","slf4j","slf4j-logger","slf4j-loggers","structured-logging"],"latest_commit_sha":null,"homepage":"https://hkupty.github.io/penna/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hkupty.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"docs/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null},"funding":{"github":"hkupty","polar":"hkupty"}},"created_at":"2023-02-15T13:29:35.000Z","updated_at":"2025-07-16T19:54:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"46aa3a48-b410-4804-a41c-e75e57ca224c","html_url":"https://github.com/hkupty/penna","commit_stats":null,"previous_names":["hkupty/maple"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/hkupty/penna","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkupty%2Fpenna","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkupty%2Fpenna/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkupty%2Fpenna/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkupty%2Fpenna/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hkupty","download_url":"https://codeload.github.com/hkupty/penna/tar.gz/refs/heads/dev/0.9","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkupty%2Fpenna/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269688009,"owners_count":24459398,"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","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"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","java-library","java-logging","json-logging","jvm","jvm-logging","slf4j","slf4j-logger","slf4j-loggers","structured-logging"],"created_at":"2024-11-24T01:00:20.608Z","updated_at":"2025-08-10T06:45:00.530Z","avatar_url":"https://github.com/hkupty.png","language":"Java","funding_links":["https://github.com/sponsors/hkupty","https://polar.sh/hkupty"],"categories":["日志库"],"sub_categories":[],"readme":"# Penna\n![Penna](logo/logo_banner.svg)\n\u003e a contour feather, a penna; a quill, a feather used for writing; a pen; a pencil.\n\n[![version](https://img.shields.io/maven-central/v/com.hkupty.penna/penna-core?style=flat-square)](https://mvnrepository.com/artifact/com.hkupty.penna)\n[![Maintainability](https://api.codeclimate.com/v1/badges/646db2db253b2610143d/maintainability)](https://codeclimate.com/github/hkupty/penna/maintainability)\n[![CircleCI](https://dl.circleci.com/status-badge/img/gh/hkupty/penna/tree/dev/0.9.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/hkupty/penna/tree/dev/0.9)\n\nPenna is an opinionated backend for [slf4j](https://github.com/qos-ch/slf4j/) that focuses on doing one thing right: Logging structured logs in json format to the console.\n\n## A word of caution\n\nPenna is considered to be in beta stage.\nIt has been observed to be stable, no reports of data loss (loss of log messages) or data corruption (malformed/unprocessable log messages).\nYet, since no major system has reported using Penna under high load, it is only theoretically stable.\nUsage is advised with caution when rolling back to an alternate backend is easy.\n\nIt would be immensely appreciated if real world usages of Penna were reported in [discussions](https://github.com/hkupty/penna/discussions) section, so we can speed up promoting Penna to 1.x and consider it completely stable.\n\n## Why use Penna?\n\nPenna is an alternative to Logback, designed for a specific use case: **structured logging** straight to the console.\n\nThis is particularly useful for JVM applications running in **Kubernetes**, where structured logs are often preferred.\n\nIf this is your use case, you might prefer Penna over Logback because:\n\n- **Purpose-built**: Penna is specialized for this use case, working out of the box with sane defaults.\n- **Future-proof**: Penna is safe against the [Y2038 bug](https://hkupty.github.io/penna/blog/epochalypse/).\n- **Zero extra dependencies**: It does not require any JSON library (or any dependency other than SLF4J).\n- **Optimized for performance**: It delivers impressive speed compared to Logback.\n- **Minimal memory footprint**: Designed to avoid GC pressure, making it highly efficient.\n- **Easy configuration**: If needed, the optional penna-yaml-config extension allows configuration via YAML — a format more native to Kubernetes environments.\n\nThat said, **Penna is not a full Logback replacement**.\nIf you need **multiple log formats**, file-based logging, or other complex logging targets, Logback might still be the right tool.\n\n\n## Usage\n\nPenna is a backend for slf4j, so you don't need to interact with it directly.\n\nIn order to use it, add it to the [build manager of your preference](https://mvnrepository.com/artifact/com.hkupty.penna/penna-core/0.9.1), for example:\n\n```groovy\n// slf4j won't detect Penna if it's not packaged as `implementation`\nimplementation 'com.hkupty.penna:penna-core:0.9.1'\n\n// Penna doesn't have any strict dependencies aside from slf4j.\nimplementation 'org.slf4j:slf4j-api:2.0.17'\n```\n\n:warning: Note that Penna is built targeting JVM 21+.\n\nBy default, you will get log level `INFO` enabled as well as the following fields:\n- `timestamp`\n- `level`\n- `message`\n- `logger`\n- `thread`\n- `mdc`\n- `markers`\n- `data` (slf4j's 2.0 `.addKeyValue()`)\n- `throwable`\n\nIf you want to configure it, Penna provides a separate convenience library for configuring your log levels in yaml files:\n```yaml\n# resources/penna.yaml\n---\n# Since version 0.8, penna-yaml-config supports setting up a file watcher\n# so any updates to this file will be reflected immediately\nwatch: true\nloggers:\n    # All the loggers under `com.yourapp` will be configured to debug level.\n    com.yourapp: { level: debug }\n    org.noisylibrary: { level: warn }\n```\n\nIf you want to use [penna-yaml-config](penna-yaml-config/README.md), you have to add it as a dependency:\n\n```groovy\nruntimeOnly 'com.hkupty.penna:penna-yaml-config:0.9.1'\n\n// penna-yaml-config is a thin layer and uses a yaml parsing libray under the hood.\n// You can chose among jackson, snakeyaml (yaml 1.1) or snakeyaml engine (yaml 1.2)\n\n// Jackson\nruntimeOnly 'com.fasterxml.jackson.core:jackson-core:2.18.3'\nruntimeOnly 'com.fasterxml.jackson.core:jackson-databind:2.18.3'\nruntimeOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.3'\n\n// Snakeyaml\nruntimeOnly 'org.yaml:snakeyaml:2.4'\n\n// Snakeyaml engine\nruntimeOnly 'org.snakeyaml:snakeyaml-engine:2.9'\n```\n\n## Principles\n\n### Structured logging\n\nLogging is supposed to provide meaningful information and, with the evolution of log processing platforms,\nit is oftentimes difficult to convey the right information as written, natural text, in a way that it\nboth makes sense for humans and is easy for machines to process.\n\nInstead, we should embrace the notion that logs are effectively data and should be treated as such.\n\n### Lightweight configuration\n\nPenna comes packed with a sane defaults configuration that allows one to plug it and start using immediately.\nAlthough configuration is possible, by rolling with the shipped defaults one can already reap the benefits of structured\nlogging without having to set up any configuration.\n\n### Unobtrusiveness\n\nThe logging framework should not draw out much attention. It should just work.\nWith that in mind, Penna tries to be a simple yet effective component in your architecture.\nIt should not require you to add in more dependencies. Instead, it should work with whatever you have available.\nAlso, it should make its best effort to consume the fewer resources as possible, being efficient and sparing your app of GC pauses\nwhen under heavy load. [Read more on our performance tests.](performance/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhkupty%2Fpenna","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhkupty%2Fpenna","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhkupty%2Fpenna/lists"}