{"id":15021082,"url":"https://github.com/saschpe/log4k","last_synced_at":"2025-10-30T11:14:31.528Z","repository":{"id":36093136,"uuid":"221440719","full_name":"saschpe/Log4K","owner":"saschpe","description":"Lightweight logging library for Kotlin/Multiplatform. Supports Android, iOS, JavaScript and plain JVM environments.","archived":false,"fork":false,"pushed_at":"2025-10-02T14:41:58.000Z","size":948,"stargazers_count":27,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-27T10:41:46.177Z","etag":null,"topics":["android","gradle","ios","ios-library","kotlin","kotlin-android","kotlin-ios","kotlin-js","kotlin-jvm","kotlin-multiplatform","kotlin-multiplatform-library","kotlin-multiplatform-mobile","logger","logging"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/saschpe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"saschpe"}},"created_at":"2019-11-13T11:11:43.000Z","updated_at":"2025-09-26T12:16:24.000Z","dependencies_parsed_at":"2024-03-25T21:28:11.894Z","dependency_job_id":"b1b8d2c7-bcc8-44a8-aeae-14b417e96620","html_url":"https://github.com/saschpe/Log4K","commit_stats":{"total_commits":164,"total_committers":1,"mean_commits":164.0,"dds":0.0,"last_synced_commit":"702b147a149eee3dca396e1d3e551290a6c73058"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/saschpe/Log4K","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschpe%2FLog4K","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschpe%2FLog4K/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschpe%2FLog4K/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschpe%2FLog4K/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saschpe","download_url":"https://codeload.github.com/saschpe/Log4K/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschpe%2FLog4K/sbom","scorecard":{"id":637714,"data":{"date":"2025-08-21T07:43:10Z","repo":{"name":"github.com/saschpe/Log4K","commit":"f520c62fef9e4917b373abe4789f1a6f34de16f5"},"scorecard":{"version":"v5.0.0","commit":"ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4"},"score":7.4,"checks":[{"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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":8,"reason":"5 out of 6 merged PRs checked by a CI test -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#ci-tests"}},{"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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":1,"reason":"Found 1/6 approved changesets -- score normalized to 1","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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#code-review"}},{"name":"Contributors","score":10,"reason":"project has 3 contributing companies or organizations -- score normalized to 10","details":["Info: openSUSE contributor org/company found, hotelde contributor org/company found, peilicke it consulting contributor org/company found, "],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#contributors"}},{"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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dependency-update-tool"}},{"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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#license"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#maintained"}},{"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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":5,"reason":"dependency not pinned by hash detected -- score normalized to 5","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:78: update your workflow using https://app.stepsecurity.io/secureworkflow/saschpe/Log4K/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/saschpe/Log4K/scorecard.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/saschpe/Log4K/security.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/saschpe/Log4K/security.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/security.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/saschpe/Log4K/security.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/security.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/saschpe/Log4K/security.yml/main?enable=pin","Info:  11 out of  15 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   3 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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":9,"reason":"SAST tool is not run on all commits -- score normalized to 9","details":["Warn: 28 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#sast"}},{"name":"Security-Policy","score":4,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Warn: no linked content found","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#security-policy"}},{"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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#signed-releases"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/security.yml:14","Info: topLevel 'contents' permission set to 'read': .github/workflows/main.yml:20","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/security.yml:9","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/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T09:41:38.377Z","repository_id":36093136,"created_at":"2025-08-21T09:41:38.378Z","updated_at":"2025-08-21T09:41:38.378Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281794047,"owners_count":26562632,"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-10-30T02:00:06.501Z","response_time":61,"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":["android","gradle","ios","ios-library","kotlin","kotlin-android","kotlin-ios","kotlin-js","kotlin-jvm","kotlin-multiplatform","kotlin-multiplatform-library","kotlin-multiplatform-mobile","logger","logging"],"created_at":"2024-09-24T19:56:06.802Z","updated_at":"2025-10-30T11:14:31.490Z","avatar_url":"https://github.com/saschpe.png","language":"Kotlin","funding_links":["https://github.com/sponsors/saschpe"],"categories":[],"sub_categories":[],"readme":"# Log4K\n[![Build Status](https://github.com/saschpe/log4k/workflows/Main%20CI/badge.svg)](https://github.com/saschpe/log4k/actions)\n[![Security](https://github.com/saschpe/Log4K/actions/workflows/security.yml/badge.svg)](https://github.com/saschpe/Log4K/actions/workflows/security.yml)\n[![Maven Central](https://img.shields.io/maven-central/v/de.peilicke.sascha/log4k.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22de.peilicke.sascha%22%20AND%20a:%22log4k%22)\n![Kotlin Version](https://img.shields.io/badge/Kotlin-v2.0.20-purple?style=flat\u0026logo=kotlin)\n[![GitHub license](https://img.shields.io/badge/License-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)\n\n![badge-android](http://img.shields.io/badge/Platform-Android-brightgreen.svg?logo=android)\n![badge-ios](http://img.shields.io/badge/Platform-iOS-orange.svg?logo=apple)\n![badge-js](http://img.shields.io/badge/Platform-NodeJS-yellow.svg?logo=javascript)\n![badge-jvm](http://img.shields.io/badge/Platform-JVM-red.svg?logo=openjdk)\n![badge-macos](http://img.shields.io/badge/Platform-macOS-orange.svg?logo=apple)\n![badge-tvos](http://img.shields.io/badge/Platform-tvOS-orange.svg?logo=apple)\n![badge-watchos](http://img.shields.io/badge/Platform-watchOS-orange.svg?logo=apple)\n\nLightweight logging library for Kotlin/Multiplatform. Supports Android, iOS, JavaScript and plain JVM environments.\n\n- **log4k**: Base library, provides infrastructure and logging to the console or files with configurable rotation and retention policies.\n- **log4k-slf4j**: Integration with [SLF4J](https://www.slf4j.org)\n\n## Download\nArtifacts are published to [Maven Central][maven-central]:\n\n```kotlin\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(\"de.peilicke.sascha:log4k:1.5.2\")\n}\n```\n\n## Usage\nLogging messages is straightforward, the **Log** object provides the usual functions you'd expect:\n\n```kotlin\n// Log to your heart's content\nLog.verbose(\"FYI\")\nLog.debug(\"Debugging ${foo.bar}\")\nLog.info(\"Nice to know\", tag = \"SomeClass\")\nLog.warn(\"Warning about $stuff ...\")\nLog.error(\"Oops!\")\nLog.assert(\"Something went wrong!\", throwable)\n```\n\nOr, if you prefer:\n\n```kotlin\nLog.verbose { \"FYI\" }\nLog.debug { \"Debugging ${foo.bar}\" }\nLog.info(tag = \"SomeClass\") { \"Nice to know\" }\nLog.warn { \"Warning about $stuff ...\" }\nLog.error { \"Oops!\" }\nLog.assert(throwable = Exception(\"Ouch!\")) { \"Something went wrong!\" }\n```\n\nThe log output includes the function name and line and pretty-prints exceptions on all supported platforms:\n\n    I/Application.onCreate: Log4K rocks!\n\n### Logging objects\nIn case you want to log `Any` Kotlin class instance or object:\n\n```kotlin\nval map = mapOf(\"Hello\" to \"World\")\nmap.logged()\n```\n\nThe above example logs `{Hello=World}` with the tag `SingletonMap` with the log level `Debug`.\n\n### Logging expensive results\nSometimes, the log output involves a heavy computation that is not always necessary. For example, if the global log\nlevel is set to `Info` or above, the following text would not appear in any log output:\n\n```kotlin\nLog.debug(\"Some ${veryHeavyStuff()}\")\n```\n\nHowever, the function `veryHeavyStuff()` will be executed regardless. To avoid this, use:\n\n```kotlin\nLog.debug { \"Some ${veryHeavyStuff()}\" }\n```\n\n## Configuration (Android example)\nTo only output messages with log-level *info* and above, you can configure the console logger in your Application class:\n\n```kotlin\nclass MyApplication : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        Log.loggers.forEach {\n            if (!BuildConfig.DEBUG) {\n                it.minimumLogLevel = Log.Level.Info\n            }\n        }\n    }\n}\n```\n\n## Logging to a file\n\nBy default, the library only logs to the current platform's console.\nAdditionally or instead, add one or multiple file loggers:\n\n```kotlin\n// Log with daily rotation and keep five log files at max:\nLog.loggers += FileLogger(rotate = Rotate.Daily, limit = Limit.Files(max = 5))\n\n// Log to a custom path and rotate every 1000 lines written:\nLog.loggers += FileLogger(rotate = Rotate.After(lines = 1000), logPath = \"myLogPath\")\n\n// Log with sensible defaults (daily, keep 10 files)\nLog.loggers += FileLogger()\n\n// One huge eternal log file:\nLog.loggers += FileLogger(rotate = Rotate.Never, limit = Limit.Not)\n```\n\n## Custom logger (Android Crashlytics example)\nThe library provides a cross-platform `ConsoleLogger` by default. Custom loggers can easily be added. For instance, to\nsend only `ERROR` and `ASSERT` messages to Crashlytics in production builds, you could do the following:\n\n```kotlin\nclass MyApplication : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        Log.loggers.clear() // Remove default loggers\n        Log.loggers += when {\n            BuildConfig.DEBUG -\u003e ConsoleLogger()\n            else -\u003e CrashlyticsLogger()\n        }\n    }\n\n    private class CrashlyticsLogger : Logger() {\n        override fun print(level: Log.Level, tag: String, message: String?, throwable: Throwable?) {\n            val priority = when (level) {\n                Log.Level.Verbose -\u003e VERBOSE\n                Log.Level.Debug -\u003e DEBUG\n                Log.Level.Info -\u003e INFO\n                Log.Level.Warning -\u003e WARN\n                Log.Level.Error -\u003e ERROR\n                Log.Level.Assert -\u003e ASSERT\n            }\n            if (priority \u003e= ERROR) {\n                FirebaseCrashlytics.getInstance().log(\"$priority $tag $message\")\n                throwable?.let { FirebaseCrashlytics.getInstance().recordException(it) }\n            }\n        }\n    }\n}\n```\n\n## Ktor integration\n\nKtor supports [providing a custom logger][ktor-logging]:\n\n```kotlin\nimport io.ktor.client.*\nimport io.ktor.client.engine.cio.*\nimport io.ktor.client.plugins.logging.*\nimport saschpe.log4k.Log\n\nval httpClient = HttpClient(CIO) {\n    install(Logging) {\n        level = LogLevel.ALL\n        logger = object : Logger {\n            override fun log(message: String) = Log.info { message }\n        }\n    }\n}\n```\n\n## Users\n\n- [Alpha+ Player — Unofficial player for Soma FM](https://play.google.com/store/apps/details?id=saschpe.alphaplus)\n- [GameOn — Get games on sale](https://play.google.com/store/apps/details?id=saschpe.gameon)\n\n## License\n\n    Copyright 2019 Sascha Peilicke\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n\n[ktor-logging]: https://ktor.io/docs/client-logging.html#custom_logger\n\n[maven-central]: https://search.maven.org/artifact/de.peilicke.sascha/android-customtabs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaschpe%2Flog4k","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaschpe%2Flog4k","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaschpe%2Flog4k/lists"}