{"id":30610236,"url":"https://github.com/koriit/slf4j-utils-logback","last_synced_at":"2025-10-20T08:02:17.756Z","repository":{"id":57725961,"uuid":"224047092","full_name":"Koriit/slf4j-utils-logback","owner":"Koriit","description":"SLF4J + Logback utils for Kotlin","archived":false,"fork":false,"pushed_at":"2022-01-09T20:49:00.000Z","size":114,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-07-28T09:17:06.821Z","etag":null,"topics":["kotlin","logback","logging","slf4j","utils"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/Koriit.png","metadata":{"files":{"readme":"README.adoc","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}},"created_at":"2019-11-25T21:43:11.000Z","updated_at":"2022-01-15T22:47:09.000Z","dependencies_parsed_at":"2022-09-02T03:41:38.920Z","dependency_job_id":null,"html_url":"https://github.com/Koriit/slf4j-utils-logback","commit_stats":null,"previous_names":[],"tags_count":2,"template":null,"template_full_name":null,"purl":"pkg:github/Koriit/slf4j-utils-logback","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Koriit%2Fslf4j-utils-logback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Koriit%2Fslf4j-utils-logback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Koriit%2Fslf4j-utils-logback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Koriit%2Fslf4j-utils-logback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Koriit","download_url":"https://codeload.github.com/Koriit/slf4j-utils-logback/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Koriit%2Fslf4j-utils-logback/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272805353,"owners_count":24995909,"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-30T02:00:09.474Z","response_time":77,"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":["kotlin","logback","logging","slf4j","utils"],"created_at":"2025-08-30T04:32:43.138Z","updated_at":"2025-10-20T08:02:17.672Z","avatar_url":"https://github.com/Koriit.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"= SLF4J+Logback Utils\n\nimage:https://github.com/Koriit/slf4j-utils-logback/actions/workflows/build.yaml/badge.svg[Build, link=\"https://github.com/Koriit/slf4j-utils-logback/actions/workflows/build.yaml\"]\nimage:https://www.codefactor.io/repository/github/koriit/slf4j-utils-logback/badge[CodeFactor,link=https://www.codefactor.io/repository/github/koriit/slf4j-utils-logback]\nimage:https://img.shields.io/badge/code%20style-%E2%9D%A4-FF4081.svg[ktlint,link=https://ktlint.github.io/]\n\nimage:https://img.shields.io/maven-central/v/com.koriit.kotlin/slf4j-utils-logback.svg?label=Maven%20Central[Maven Central, link=\"https://search.maven.org/search?q=g:%22com.koriit.kotlin%22%20AND%20a:%22slf4j-utils-logback%22\"]\nimage:https://img.shields.io/github/license/koriit/slf4j-utils-logback[GitHub]\n\nWARNING: From version 0.4.0 all package names have been renamed to match new artifact group id.\n\nhttps://github.com/Koriit/slf4j-utils[SLF4J Utils] + Logback + Logback Utils\n\n== Default Configuration\nThis library overrides the default configuration provided by Logback.\n\nThe configuration is injected with service loading, so you can still override it with\n`logback-test.xml`, `logback.groovy` or `logback.xml`.\n\nYou can configure the root logger level with the `logging.root.level` system property or\n`LOGGING_ROOT_LEVEL` environment variable.\n\n[NOTE]\nLogs are printed to the standard output. Which - with modern containers - is not a problem if you want to\ngather your logs in files or centralized database.\n\n[WARNING]\nIf you override this configuration, please, remember to also properly initialize the SLF4J bridge\nfor j.u.l. (see _BasicConfiguration_ class)\n\n=== Default Format\nOptimized for human readability and local development.\n\n----\n2019-11-28 11:51:41.234 INFO  [main           ] (Application.kt:59)                                          : Application configured, starting... 2bef553b 03c49529\n2019-11-28 11:51:42.706 INFO  [atcher-worker-1] (BaseApplicationEngine.kt:39)                                : Responding at http://0.0.0.0:8080 2bef553b 03c49529\n2019-11-28 11:51:42.735 INFO  [main           ] (Application.kt:81)                                          : Application startup finished: 2.925s 2bef553b\n----\n----\n2019-11-28 11:51:41.234                \u003c1\u003e\nINFO                                   \u003c2\u003e\n[main]                                 \u003c3\u003e\n(Application.kt:59)                    \u003c4\u003e\n:                                      \u003c5\u003e\nApplication configured, starting...    \u003c6\u003e\n2bef553b                               \u003c7\u003e\n03c49529                               \u003c8\u003e\n----\n\u003c1\u003e Timestamp of the log with millisecond precision (note that there is no timezone offset)\n\u003c2\u003e http://www.slf4j.org/apidocs/org/slf4j/event/Level.html[Log level]\n\u003c3\u003e Thread name\n\u003c4\u003e File name and line (If IDE can find the file this should be clickable)\n\u003c5\u003e Visual `:` delimiter\n\u003c6\u003e Log message\n\u003c7\u003e Optional MDC `correlationId`\n\u003c8\u003e Optional MDC `subCorrelationId`\n\nElements 1-4 are fixed length to make reading messages easier for humans.\n\n=== JSON Format\nOptimized for gathering and machine processing.\n\nIt is possible to enable JSON format by providing `logging.format=json` system property or\n`LOGGING_FORMAT=json` environment variable.\n\nBy directly logging with JSON documents we can avoid CPU intensive and costly parsing of log strings.\nThe JSON format is achieved with `LogstashEncoder` which is adjusted for ELK, however,\nany NoSQL/JSON Storage should be able to receive such logs.\n\n[source,json]\n----\n{\"@timestamp\":\"2019-11-28T12:30:06.314+01:00\",\"@version\":\"1\",\"message\":\"Application configured, starting...\",\"logger_name\":\"koriit.kotlin.kodein.application.ApplicationKt\",\"thread_name\":\"main\",\"level\":\"INFO\",\"level_value\":20000,\"subCorrelationId\":\"ffe5b8f0-10af-4192-94df-853ea5da4aa2\",\"correlationId\":\"71a89c2a-5915-4f44-909c-90ae6b9e5755\"}\n{\"@timestamp\":\"2019-11-28T12:30:07.383+01:00\",\"@version\":\"1\",\"message\":\"Responding at http://0.0.0.0:8080\",\"logger_name\":\"koriit.kotlin.app.Logging\",\"thread_name\":\"DefaultDispatcher-worker-1\",\"level\":\"INFO\",\"level_value\":20000,\"subCorrelationId\":\"ffe5b8f0-10af-4192-94df-853ea5da4aa2\",\"correlationId\":\"71a89c2a-5915-4f44-909c-90ae6b9e5755\"}\n{\"@timestamp\":\"2019-11-28T12:30:07.410+01:00\",\"@version\":\"1\",\"message\":\"Application startup finished: 2.397s\",\"logger_name\":\"koriit.kotlin.kodein.application.ApplicationKt\",\"thread_name\":\"main\",\"level\":\"INFO\",\"level_value\":20000,\"subCorrelationId\":\"ffe5b8f0-10af-4192-94df-853ea5da4aa2\",\"correlationId\":\"71a89c2a-5915-4f44-909c-90ae6b9e5755\"}\n----\n\n[source,json]\n----\n{\n  \"@timestamp\": \"2019-11-28T12:30:06.314+01:00\",\n  \"@version\": \"1\",\n  \"message\": \"Application configured, starting...\",\n  \"logger_name\": \"koriit.kotlin.kodein.application.ApplicationKt\",\n  \"thread_name\": \"main\",\n  \"level\": \"INFO\",\n  \"level_value\": 20000,\n  \"subCorrelationId\": \"ffe5b8f0-10af-4192-94df-853ea5da4aa2\",\n  \"correlationId\": \"71a89c2a-5915-4f44-909c-90ae6b9e5755\"\n}\n----\n\n[NOTE]\nPlease, note that there is `logger_name` instead of a file name and line.\nThat's because computing file name and line is not particularly fast according to Logback documentation.\nIn the end, the logger name also allows us to precisely locate the logging site.\n\n[NOTE]\nAny log markers will be put into the `tags` array.\n\n== Graceful closing\nDo you make sure to gracefully close your async loggers? :)\n\nIf your application finishes with your `main` you can do the following:\n[source,kotlin]\n----\nfun main() {\n    // Application code...\n\n    // Close logging threads and flush buffers\n    closeLoggers()\n}\n----\n\n== Performance logs\nOne of the most interesting things you can extract from your logs is the performance of your\napplication - certain sections, API methods, startup, etc.\n\nHowever, calculating averages and percentiles assumes we are working with numbers, thus you would need\nto parse your log strings. With help comes JSON format.\n\nWith `net.logstash.logback.argument.StructuredArguments.value` you can put any arbitrary value into your\nJSON log. In particular a number - some duration.\n\n[source,kotlin]\n----\nlog.info(\"Request took {} ms\", value(\"duration\", duration))\n----\n[source,json]\n----\n{\n  \"@timestamp\": \"2019-11-28T13:04:50.961+01:00\",\n  \"@version\": \"1\",\n  \"message\": \"Request took 12 ms\",\n  \"logger_name\": \"koriit.kotlin.app.Logging\",\n  \"thread_name\": \"worker-1\",\n  \"level\": \"INFO\",\n  \"level_value\": 20000,\n  \"correlationId\": \"caf9b662-a0cd-4d0a-8b75-e4cde32b232f\",\n  \"duration\": 12\n}\n----\n\nThis library provides a set of `performance` extension functions that do this for you and also\nadd `PERFORMANCE` marker.\n\n[source,kotlin]\n----\n//...\nval additionalInfo = mapOf(\n    \"request\" to requestInfo,\n    \"response\" to responseInfo\n)\n\nlog.performance(\"{} ms - {} - {} {}\", duration, responseInfo[\"status\"], method, requestInfo[\"url\"], appendEntries(additionalInfo))\n----\n[source,json]\n----\n{\n  \"@timestamp\": \"2019-11-28T13:24:47.832+01:00\",\n  \"@version\": \"1\",\n  \"message\": \"3 ms - 200 - GET http://localhost:8080/api/entities\",\n  \"logger_name\": \"koriit.kotlin.app.Logging\",\n  \"thread_name\": \"worker-4\",\n  \"level\": \"INFO\",\n  \"level_value\": 20000,\n  \"correlationId\": \"db4f0ccb-0ba8-45f8-a21b-6adb83c6bd86\",\n  \"tags\": [\n    \"PERFORMANCE\"\n  ],\n  \"duration\": 3,\n  \"request\": {\n    \"method\": \"GET\",\n    \"protocol\": \"HTTP/1.1\",\n    \"url\": \"http://localhost:8080/api/entities\",\n    \"api\": \"GET /api/entities\",\n    \"route\": \"/api/entities\",\n    \"remoteHost\": \"unknown\",\n    \"contentType\": \"*/*\",\n    \"contentLength\": null\n  },\n  \"response\": {\n    \"status\": 200,\n    \"contentType\": \"application/json; charset=UTF-8\",\n    \"contentLength\": 5606\n  }\n}\n----\n\n[NOTE]\nPerformance logs are still logged as `INFO`. Whether this difference is visible in the\noutput depends on your format, whether it includes markers in some way.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoriit%2Fslf4j-utils-logback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoriit%2Fslf4j-utils-logback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoriit%2Fslf4j-utils-logback/lists"}