{"id":15045501,"url":"https://github.com/lightbend-labs/scala-logging","last_synced_at":"2025-12-16T01:36:49.556Z","repository":{"id":9551929,"uuid":"11459398","full_name":"lightbend-labs/scala-logging","owner":"lightbend-labs","description":"Convenient and performant logging library for Scala wrapping SLF4J.","archived":false,"fork":false,"pushed_at":"2025-03-25T00:59:27.000Z","size":370,"stargazers_count":918,"open_issues_count":36,"forks_count":130,"subscribers_count":25,"default_branch":"main","last_synced_at":"2025-05-13T14:21:44.425Z","etag":null,"topics":["jvm","logback","logging","macros","sbt","scala","slf4j"],"latest_commit_sha":null,"homepage":"","language":"Scala","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/lightbend-labs.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,"zenodo":null}},"created_at":"2013-07-16T20:24:15.000Z","updated_at":"2025-04-28T00:47:44.000Z","dependencies_parsed_at":"2024-01-30T22:37:51.774Z","dependency_job_id":"862100b7-0a00-4357-85af-78276cba3fbc","html_url":"https://github.com/lightbend-labs/scala-logging","commit_stats":{"total_commits":316,"total_committers":45,"mean_commits":7.022222222222222,"dds":0.629746835443038,"last_synced_commit":"0356a4669caeb1a121ce82b8179038905c9ba3a2"},"previous_names":["lightbend/scala-logging","typesafehub/scala-logging"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lightbend-labs%2Fscala-logging","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lightbend-labs%2Fscala-logging/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lightbend-labs%2Fscala-logging/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lightbend-labs%2Fscala-logging/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lightbend-labs","download_url":"https://codeload.github.com/lightbend-labs/scala-logging/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254133118,"owners_count":22020274,"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":["jvm","logback","logging","macros","sbt","scala","slf4j"],"created_at":"2024-09-24T20:51:57.209Z","updated_at":"2025-10-06T15:11:57.206Z","avatar_url":"https://github.com/lightbend-labs.png","language":"Scala","funding_links":[],"categories":["Table of Contents","日志库"],"sub_categories":["Extensions"],"readme":"Scala Logging is a **convenient** and **fast** logging library wrapping [SLF4J](http://www.slf4j.org).\n\nIt's convenient, because you can simply call log methods, *without* checking whether the respective log level is enabled:\n\n```scala\nlogger.debug(s\"Some $expensive message!\")\n```\n\nIt's fast, because thanks to Scala macros the *check-enabled-idiom* is applied and the following code is generated:\n\n```scala\nif (logger.isDebugEnabled) logger.debug(s\"Some $expensive message!\")\n```\n\n## Prerequisites\n\n* Java 8 or higher\n* Scala 2.11, 2.12, 2.13 or 3.0\n* Logging backend compatible with SLF4J\n\nA compatible logging backend is [Logback](http://logback.qos.ch), add it to your sbt build definition:\n\n```scala\nlibraryDependencies += \"ch.qos.logback\" % \"logback-classic\" % \"1.2.10\"\n```\n\nIf you are looking for a version compatible with Scala 2.10, check out Scala Logging 2.x.\n\n## Getting Scala Logging\n\nScala Logging is published to Sonatype OSS and Maven Central:\n\n- Group id / organization: *com.typesafe.scala-logging*\n- Artifact id / name: *scala-logging*\n\nsbt users may add this to their `build.sbt`:\n\n```scala\nlibraryDependencies += \"com.typesafe.scala-logging\" %% \"scala-logging\" % \"3.9.4\"\n```\n\n## Using Scala Logging\n\nThe `Logger` class from the `com.typesafe.scalalogging` package wraps an underlying SLF4J logger.\nIn order to create a `Logger`, you pass a name to the `apply` factory method defined in the `Logger` companion object:\n\n```scala\nval logger = Logger(\"name\")\n```\n\nOr, you pass in a SLF4J logger instance:\n\n```scala\nval logger = Logger(LoggerFactory.getLogger(\"name\"))\n```\n\nOr, you pass in the name of the class into which it is defined:\n\n```scala\nval logger = Logger(getClass.getName)\n```\n\nOr, you pass in a class:\n\n```scala\nval logger = Logger(classOf[MyClass])\n```\n\nOr, using the runtime class wrapped by the implicit class tag parameter:\n\n```scala\nval logger = Logger[MyClass]\n```\n\nThe `LazyLogging` and `StrictLogging` traits from the `com.typesafe.scalalogging` package define the `logger` member as\na lazy or strict value respectively, whereas the `AnyLogging` trait defines an abstract `logger`.\n\nIt depends on the individual use case which trait to use. However, we have defined some scenarios where you can use these traits:\n\n- Use `LazyLogging` if you are creating lots of objects with this trait repetitively.\n- Use `StrictLogging` pretty much by default, especially if the class is a singleton, or you know the log methods will always be invoked.\n- Use `AnyLogging` when writing some trait which needs access to any logger without deciding on a specific implementation.\n\nIn case of `LazyLogging` and `StrictLogging`, the underlying SLF4J logger is named according to the class into which\nthese traits are mixed:\n\n```scala\nclass LazyLoggingExample extends LazyLogging {\n  logger.debug(\"This is Lazy Logging ;-)\")\n\n  logger.whenDebugEnabled {\n    println(\"This would only execute when the debug level is enabled.\")\n    (1 to 10).foreach(x =\u003e println(\"Scala logging is great!\"))\n  }\n}\n```\n\n```scala\nclass StrictLoggingExample extends StrictLogging {\n  logger.debug(\"This is Strict Logging ;-)\")\n\n  logger.whenDebugEnabled {\n    println(\"This would only execute when the debug level is enabled.\")\n    (1 to 10).foreach(x =\u003e println(\"Scala logging is great!\"))\n  }\n}\n```\n\n```scala\nclass AnyLoggingExample extends AnyLogging {\n  override protected val logger: Logger = Logger(\"name\")\n\n  logger.info(\"This is Any Logging ;-)\")\n\n  logger.whenInfoEnabled {\n    println(\"This would only execute when the info level is enabled.\")\n    (1 to 10).foreach(x =\u003e println(\"Scala logging is great!\"))\n  }\n}\n```\n\n`LoggerTakingImplicit` provides the same methods as `Logger` class, but with additional implicit parameter `A`.\nDuring creation of the `LoggerTakingImplicit` evidence `CanLog[A]` is required.\nIt may be useful when contextual parameter (e.g. _Correlation ID_) is being passed around and you would like to include it in the log messages:\n\n```scala\ncase class CorrelationId(value: String)\nimplicit case object CanLogCorrelationId extends CanLog[CorrelationId] {\n  override def logMessage(originalMsg: String, a: CorrelationId): String = s\"${a.value} $originalMsg\"\n}\n\nimplicit val correlationId = CorrelationId(\"ID\")\n\nval logger = Logger.takingImplicit[CorrelationId](\"test\")\nlogger.info(\"Test\") // takes implicit correlationId and logs \"ID Test\"\n```\n\nIf you want to extract the context object associated with your logger i.e. `correlationId` here, use `getContext`.\n```scala\nval context = logger.canLogEv.getContext()\n```\n\nIt's also possible to use `MDC` through `CanLog` without any troubles with execution context.\n\n```scala\ncase class CorrelationId(value: String)\nimplicit case object CanLogCorrelationId extends CanLog[CorrelationId] {\n  override def logMessage(originalMsg: String, a: CorrelationId): String = {\n    MDC.put(\"correlationId\", a.value)\n    originalMsg\n  }\n\n  override def afterLog(a: CorrelationId): Unit = {\n    MDC.remove(\"correlationId\")\n  }\n}\n\nimplicit val correlationId = CorrelationId(\"ID\")\n\nval logger = Logger.takingImplicit[CorrelationId](\"test\")\n\ndef serviceMethod(implicit correlationId: CorrelationId): Future[Result] = {\n  dbCall.map { value =\u003e\n    logger.trace(s\"Received value $value from db\") // takes implicit correlationId\n    toResult(value)\n  }\n}\n```\n\n## String Interpolation\n\nIt is idiomatic to use Scala's string interpolation `logger.error(s\"log $value\")` instead of SLF4J string interpolation `logger.error(\"log {}\", value)`.\nHowever there are some tools (such as [Sentry](https://sentry.io)) that use the log message format as grouping key. Therefore they do not work well with\nScala's string interpolation.\n\nScala Logging replaces simple string interpolations with their SLF4J counterparts like this:\n\n```scala\nlogger.error(s\"my log message: $arg1 $arg2 $arg3\")\n```\n\n```scala\nlogger.error(\"my log message: {} {} {}\", arg1, arg2, arg3)\n```\n\nThis has no effect on behavior and performace should be comparable (depends on the underlying logging library).\n\n### Limitations\n\n - Works only when string interpolation is directly used inside the logging statement. That is when the log message is static (available at compile time).\n - Works only for the `logger.\u003clevel\u003e(message)` and `logger.\u003clevel\u003e(marker, message)` logging methods. It does not work if you want to log an exception and\n use string interpolation too (this is a limitation of the SLF4J API).\n\n## Line numbers in log message?\n\nUsing the [sourcecode](https://github.com/lihaoyi/sourcecode#logging) library, it's possible to add line number\ninformation (especially useful for debugging):\n\n```scala\ndef foo(arg: String)(implicit line: sourcecode.Line, file: sourcecode.File) = {\n  ... do something with arg ...\n  ... do something with file.value ...\n}\n\nfoo(\"hello\") // the implicit sourcecode.File is filled in automatically\n```\n\n## Maintenance status\n\nThis library is community-maintained. It is not supported under the Lightbend subscription.\n\n## Contribution policy\n\nContributions via GitHub pull requests are gladly accepted from their original author. Before we can accept pull requests, you will need to agree to the [Lightbend Contributor License Agreement](https://www.lightbend.com/contribute/cla) online, using your GitHub account.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flightbend-labs%2Fscala-logging","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flightbend-labs%2Fscala-logging","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flightbend-labs%2Fscala-logging/lists"}