typelevel/log4cats
60.1
Adequate · 20 September 2026
3.7k
lines of production code
Scala
primary language
1
measurement over time
What this system is
This system is a functional logging library for Scala that provides a unified, effect-safe API for structured logging across JVM, JavaScript, and Native platforms. It integrates with SLF4J for production use while offering specialized implementations for testing, deferred buffering, and browser console output. The library emphasizes non-blocking operations, lazy evaluation, and compile-time logger name derivation to ensure robustness and ease of use within effectful applications.
How it got here
2018–2021 — Structured logging and cross-platform modernization
16 changes.
The project underwent a major architectural overhaul, migrating to sbt-typelevel and supporting Scala 2.12, 2.13, and 3 across JVM, JS, and Native platforms. Core logging capabilities were significantly expanded with the introduction of structured logging, message pagination, and new deferred and writer-based logger implementations. Integration with SLF4J was refactored to ensure non-blocking MDC handling and macro-based logger creation for both Scala 2 and 3.
2022–2024 — Scala 2 compatibility and JS console support
5 changes.
This period focused on enhancing platform support by introducing a Scala 2 macro for automatic logger name derivation and adding a new js-console module for browser logging. The work also involved refactoring the NoOpLogger into the core module and expanding test coverage for logger name resolution and deferred logging capabilities.
Features
Add Scala 2 macro for automatic logger name derivation
Introduced a Scala 2-specific compatibility layer that automatically derives the logger name from the enclosing class or module at compile time. This is implemented via a new \LoggerNameCompat\ trait and the \LoggerNameMacro\ implementation, which resolves the enclosing symbol and generates the appropriate \LoggerName\ instance, handling edge cases such as package objects, inner classes, and higher-kinded types to ensure correct naming behavior for Scala 2 users.
core/shared/src/main/scala-2, core/shared/src/main/scala-3 · high confidence
Add Scala.js console logging support
Introduces a new \js-console\ module that enables logging to the browser's Web Console in Scala.js applications. This includes a \ConsoleLogger\ implementation that maps log levels to browser console methods (info, warn, error, debug), a \ConsoleLoggerFactory\ for creating instances, and internal facade classes (\Console\, \ConsoleF\) to interact with the JavaScript environment via \cats-effect-kernel\.
js-console · high confidence
Add string interpolation syntax for Logger methods
Users can now use string interpolation syntax (e.g., logger"message") to log messages at various levels (error, warn, info, debug, trace) via the new LoggerInterpolator implicit class in the syntax package.
core/shared/src/main/scala/org/typelevel/log4cats/syntax · high confidence
Added Scala 2 compatibility layer for SLF4J logger creation
Introduced a new compatibility package for Scala 2 that provides macro-based implementations for creating SLF4J loggers. This includes \Slf4jLoggerCompat\ and \GetLoggerMacros\, which enable the \getLogger\ and \create\ methods to function correctly on Scala 2 by generating the appropriate logger instances via compile-time macros, ensuring binary compatibility and correct behavior for users on this platform.
slf4j/src/main/scala-2 · high confidence
New deferred and Writer-based logger implementations in log4cats extras
The \org.typelevel.log4cats.extras\ package now includes \DeferredLogger\, \DeferredStructuredLogger\, \DeferredSelfAwareStructuredLogger\, and \DeferredLoggerFactory\, which buffer log messages in memory and only emit them when explicitly triggered or when a resource scope fails or is cancelled—making them safer for scenarios like failure-only logging. Additionally, \WriterLogger\, \WriterStructuredLogger\, \WriterTLogger\, and \WriterTStructuredLogger\ provide logger implementations backed by \cats.data.Writer\ and \WriterT\, allowing logs to be accumulated alongside computation results, with a README documenting important caveats about their lifecycle and error-handling behavior.
core/shared/src/main/scala/org/typelevel/log4cats/extras · high confidence
New testing and extras utilities for structured logging
This change introduces new utilities in the \testing\ and \extras\ modules to support structured logging and easier testing. It adds \LogLevel\, \LogMessage\, and \StructuredLogMessage\ types to the \extras\ package, providing a standardized way to represent log levels and messages, including context maps for structured logging. Additionally, it provides \TestingLogger\, \StructuredTestingLogger\, and \TestingLoggerFactory\ in the \testing\ module, allowing developers to capture and inspect log messages during tests, with support for both standard and structured logging contexts.
repository · high confidence
Removals
Removal of placeholder Main entry point
The default application entry point (Main.scala) has been removed from the project. This eliminates the initial placeholder code that simply printed a startup message, indicating the project is moving past its initial scaffolding phase.
src/main · high confidence
Behavioural changes
Introduce structured logging traits and paging support
The core logging API has been refactored to support structured logging and message pagination. New traits—MessageLogger, ErrorLogger, StructuredLogger, SelfAwareLogger, and SelfAwareStructuredLogger—provide granular control over log levels and context injection via methods like addContext and withModifiedString. The LoggerFactory now exposes mapK, addContext, and withModifiedString to transform logger instances. Additionally, PagingSelfAwareStructuredLogger allows wrapping loggers to split large messages into paginated chunks, preventing truncation by underlying logging providers, with the previous withPaging method deprecated in favor of paged.
core/shared/src/main/scala/org/typelevel/log4cats · high confidence
NoOpLogger implementation moved to core module
The \NoOpLogger\ and \NoOpFactory\ implementations have been relocated to the \core/shared\ module. This change reorganizes the internal structure of the library, making the no-operation logger components part of the core shared codebase rather than a separate or peripheral location, without altering their functionality.
core/shared/src/main/scala/org/typelevel/log4cats/noop · high confidence
Ported SLF4J logger creation macros to Scala 3
The SLF4J logger creation logic has been migrated to Scala 3 using the new \scala.quoted\ macro system. This change introduces \Slf4jLoggerCompat\ and \GetLoggerMacros\ to handle the generation of \SelfAwareStructuredLogger\ instances, ensuring binary compatibility while updating the underlying implementation to use Scala 3's quote-based metaprogramming instead of the previous Scala 2 macros.
slf4j/src/main/scala-3 · high confidence
Refactor SLF4J logger creation with explicit factory pattern
The SLF4J integration now uses a new \Slf4jFactory\ trait and companion object to manage logger creation, replacing the previous implicit resolution mechanism. Users should now explicitly call \Slf4jFactory.create\[F\]\ to obtain a factory instance, as the previous implicit \loggerFactoryforSync\ has been deprecated. The \Slf4jLogger\ object provides updated methods like \getLoggerFromBlockingSlf4j\ and \fromBlockingSlf4j\ to support non-blocking logger instantiation, ensuring that creating logger instances does not block the calling thread.
slf4j/src/main/scala/org/typelevel/log4cats/slf4j · high confidence
Refactored internal SLF4J logger to handle MDC safely and non-blockingly
The internal \Slf4jLoggerInternal\ implementation has been rewritten to ensure that interactions with the SLF4J MDC (Mapped Diagnostic Context) are non-blocking and resilient to misconfiguration. The new code uses \Sync.delay\ to wrap MDC operations, preventing potential deadlocks in effectful contexts, and includes error handling to salvage logging output even if the MDC adapter is missing or throws an \IllegalStateException\. Additionally, the logger now exposes MDC state checks via \isEnabled\ methods and ensures that context is managed without blocking the calling thread.
slf4j/src/main/scala/org/typelevel/log4cats/slf4j/internal · high confidence
Switch to Apache 2.0 license and update build configuration
The project license has been changed to Apache 2.0. The build environment is now configured with specific JVM options in \.sbtopts\ (including G1GC and memory settings), and the Scala Steward configuration pins \slf4j-api\ and \logback-classic\ to version 1.x to prevent unwanted updates. Additionally, the \.scalafmt.conf\ file has been updated to version 3.11.5 with Scala 3 dialect support, and the Travis CI configuration has been removed.
(repo-wide) · high confidence
Test coverage
Added MUnit-based tests for paging structured logger; Added compilation hygiene and macro tests for Slf4jLogger; Added comprehensive tests for Slf4jLoggerInternal MDC handling and lazy evaluation; Added syntax compilation tests for LoggerFactory and Logger; Added tests for LoggerName resolution; Added tests for deferred logging capabilities; Removed obsolete MainSpec test.
Dependencies
Major dependency and build system overhaul
The project has been significantly modernized by upgrading core dependencies to Cats 2.13.0 and Cats-Effect 3.7.1, and updating the Scala versions to 2.12.21, 2.13.18, and 3.3.7. The build infrastructure has migrated to the sbt-typelevel plugin, replacing the previous release and CI setup, and the project structure has been split into distinct modules (core, testing, noop, slf4j, docs, js-console) with cross-compilation support for JVM, JS, and Native platforms.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 60.
Lenses
- Code Health 96
- Architecture 100
- Maturity 46
- Readiness 67
- Security 65
Changes since last survey
- 300 commits — 296 feature/other, 4 fixes
By area
- (repo) — 134 commits
- (root) — 59 commits
- project/build.properties — 34 commits
- project/plugins.sbt — 29 commits
- slf4j/src — 16 commits
- core/shared — 14 commits
- .github/workflows — 9 commits
- testing/shared — 5 commits
Notable commits
- fix: Fix misalignment of types
- fix: Fix some warnings related to -xsource:3
- fix: Fix unused import
- fix: Merge pull request #845 from danicheg/fix-#844
- change: Add .sbtopts
- change: Add DeferredLoggerFactory
- change: Add TestingLoggerFactory
- change: Add missing overrides for mapK and friends
- change: Add test explicitly demonstrating MDC behavior
- change: Always handle the MDC
- change: Apply suggestions from code review
- change: Attempt to balance warn message changes between Scala 2/3
- change: Attempt to salvage the log if the MDC is busted
- change: Bump base version
- change: Bump tlBaseVersion
- change: Clean up unneeded calls to Show
- change: Colocate the logging levels in Slf4jLoggerInternal
- change: Expand test coverage of Slf4jLogger
- change: Expose MDC to Slf4jLoggerInternal isEnabled
- change: Formatting and documentation cleanup
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
typelevel/log4cats was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 575a9320c5e824a25ee463db6d437fa199d5380d — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.