wvlet-log alternatives and similar packages
Based on the "Extensions" category.
Alternatively, view wvlet-log alternatives based on common mentions on social networks and blogs.
-
cats
Lightweight, modular, and extensible library for functional programming. -
Cassovary
Cassovary is a simple big graph processing library for the JVM -
scala.meta
Library to read, analyze, transform and generate Scala programs -
Enumeratum
A type-safe, reflection-free, powerful enumeration implementation for Scala with exhaustive pattern match warnings and helpful integrations. -
Scala-Logging
Convenient and performant logging library for Scala wrapping SLF4J. -
Chimney
Scala library for boilerplate-free, type-safe data transformations -
Freestyle
A cohesive & pragmatic framework of FP centric Scala libraries -
tinylog
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android -
Scala Graph
Graph for Scala is intended to provide basic graph functionality seamlessly fitting into the Scala Collection Library. Like the well known members of scala.collection, Graph for Scala is an in-memory graph library aiming at editing and traversing graphs, finding cycles etc. in a user-friendly way. -
scribe
The fastest logging library in the world. Built from scratch in Scala and programmatically configurable. -
Each
A macro library that converts native imperative syntax to scalaz's monadic expressions -
Rapture
a collection of libraries for common, everyday programming tasks (I/O, JSON, i18n, etc.) -
Stateless Future
Asynchronous programming in fully featured Scala syntax. -
Scala Blitz
Scala framework for efficient sequential and data-parallel collections - -
Squid
Squid – type-safe metaprogramming and compilation framework for Scala -
Records for Scala
Labeled records for Scala based on structural refinement types and macros. -
Play monadic actions
A simple scala DSL to allow clean and monadic style for Play! Actions -
enableIf.scala
A library that toggles Scala code at compile-time, like #if in C/C++ -
Freasy Monad
Easy way to create Free Monad using Scala macros with first-class Intellij support. -
Lamma
Lamma schedule generator for Scala is a professional schedule generation library for periodic schedules like fixed income coupon payment, equity deravitive fixing date generation etc. -
Resolvable
A library to optimize fetching immutable data structures from several endpoints in several formats. -
Freedsl
Practical effect composition library based on abstract wrapping type and the free monad
Access the most powerful time series database as a service
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of wvlet-log or a related project?
README
wvlet-log

NOTICE: wvlet-log has been renamed to Airframe Log and merged into Airframe project. You can find the latest source code under wvlet/airframe.
wvlet-log is a libray for enhancing your Scala application logging with colors and source code locations. Here are examples of pre-defined LogFormatters in wvlet-log:
Scala.js is also supported:
Features
- Simple to use
- You can start logging by adding
wvlet.log.LogSupport
trait to your code. No need to writeLogger.getLogger(xxx)
anymore.
- You can start logging by adding
- Fast and light-weight
- wvlet-log uses Scala macros for efficiency; log messages will be instanciated only when the log level is effective.
- wvlet-log is just an extension of JVM's built-in
java.util.logging
. So no need exists to add custom binding jars, such as logback-classic as in slf4j.
- Informative
- ANSI colored logging support.
- You can also show the source code locations (line number and pos) of log messages.
- Fully customizable
- log levels can be changed at ease with the periodic log-level scanner.
- You can also change the log level through the standard JMX interface for
java.util.logging
. - Easy to customize your own log format and log levels inside the code. No external XML configuration is required.
- Production ready
- wvlet-log has built-in handlers for log file rotations, asynchronous logging.
- Scala 2.11, 2.12, Scala.js support
Usage
libraryDependencies += "org.wvlet" %% "wvlet-log" % "(version)"
// For Scala.js (Since wvlet-log 1.2)
libraryDependencies += "org.wvlet" %%% "wvlet-log" % "(version)"
Using LogSupport trait
The most convenient way to use wvlet-log is adding LogSupport
to your class:
import wvlet.log.LogSupport
object MyApp extends LogSupport {
info("info log")
debug("debug log")
}
The logger name will be determined from your class name (e.g., MyApp
).
Alternatively you can load Logger
instance manually:
import wvlet.log.Logger
class YourApp {
private val logger = Logger.of[YourApp]
}
Configuring log levels
(This feature is not available in Scala.js)
If Logger.scheduleLogLevelScan
is called, wvlet-log periodically scans log-level properties file (default every 1 minute) to configure logger levels:
import wvlet.log.Logger
## Scan log files (not available for Scala.js)
Logger.scheduleLogLevelScan
log.properties example:
# You can use all, trace, debug, info, warn, error, info, all as log level
wvlet.airframe=debug
org.eclipse.jetty=info
org.apache.http=info
com.amazonaws=info
The format follows Java Properties file format.
In default, loglevel file will be found in this order:
log-test.properties
in the classpath.- If 1. is not found, use
log.properties
in the classpath.
To change the log file path, you can use Logger.scheduleLogLevelScan(file paths, duration)
.
In debugging your application, create src/test/resources/log-test.properties
file, and
call Logger.scheduleLogLevelScan
before running test cases. This is useful for quickly checking the log messages.
Using LoglevelScanner with ScalaTest
To scan log level properties periodically with ScalaTest, define the base trait as follows:
import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll, WordSpec, _}
import wvlet.log.LogFormatter.SourceCodeLogFormatter
trait Spec extends WordSpec with Matchers with BeforeAndAfterAll with LogSupport {
// Set the default log formatter
Logger.setDefaultFormatter(SourceCodeLogFormatter)
override protected def beforeAll(): Unit = {
// Run LogLevel scanner (log-test.properties or log.properties in classpath) every 1 minute
Logger.scheduleLogLevelScan
super.beforeAll()
}
override protected def afterAll(): Unit = {
Logger.stopScheduledLogLevelScan
super.afterAll()
}
}
class YourSpec extends Spec {
"my application" should {
"run correctly" in {
// ....
}
}
}
Customizing log format
You can show the source code location where the log message is generated:
import wvlet.log._
object MyApp with LogSupport {
Logger.setDefaultFormatter(LogFormatter.SourceCodeLogFormatter)
info("log with source code")
}
This code will show:
[MyApp$] log with source code - (MyApp.scala:6)
Pre-defined log formatters:
Here is the list of pre-defined log formatters.
- SourceCodeLogFormatter (with source code location)
- AppLogFormatter (without source code location)
- TSVLogFormatter (logging in TSV format)
- IntelliJLogFormatter (for debugging using IntelliJ console)
- SimpleLogFormatter (just logger name and log message)
- BareFormatter (shows only log message)
Customising LogFormatter
You can also define your own LogFormatter:
import wvlet.log.LogFormatter._
object CustomLogFormatter extends LogFormatter {
override def formatLog(r: LogRecord): String = {
val log = s"[${highlightLog(r.level, r.leafLoggerName)}] ${highlightLog(r.level, r.getMessage)}"
appendStackTrace(log, r)
}
}
Logger.setDefaultFormatter(CustomLogFormatter)
See also the examples in [LogFormat.scala](src/main/scala/wvlet/log/LogFormat.scala):
Using wvlet-log in Scala.js
import wvlet.log._
Logger.setDefaultHandler(JSConsoleLogHandler())
class YourAppClass extends LogSupport {
info("hello")
}
The log message will be showin in your browser's developer console.
To configure the log level, use wvlet.log.setDefaultLogLevel
or wvlet.log.setLogLevel
:
> wvlet.log.setDefaultLogLevel("debug")
> wvlet.log.setLogLevel("your.logger.name", "trace")
Using with slf4j
If you are using slf4j, just add slf4j-jdk14
to your dependency. The log messages from slf4j will be sent to wvlet-log:
libraryDependencies += "org.slf4j" % "slf4j-jdk14" % "1.7.21"
- See also the article, How to start using wvlet-log with slf4j projects, written by @seratch (author of skinny-framework, scalikejdbc, etc.)
Writing and rotating logs with files
To write and rotate your logs, use LogRotationHandler
:
logger.resetHandler(new LogRotationHandler(
fileName = "your-app.log",
maxNumberOfFiles = 100, // rotate up to 100 log files
maxSizeInBytes = 100 * 1024 * 1024 // 100MB
AppLogFormatter // Any log formatter you like
))
If you simply need to output logs to a single file without any rotation, use FileHandler
:
logger.resetHandler(new FileHandler(
fileName = "your-app.log", // Log file name
formatter = AppLogFormatter // Any log formatter you like
))
Asynchronous logging
If you know your LogHandler is a heavy process (e.g., writing to network or slow disks), you can use
AsyncHandler
to do the logging in a background thread:
val asyncHandler = new AsyncHandler(a heavy parent log handler)
try {
logger.resetHandler(asyncHandler)
}
finally {
asyncHandler.close // To flush unwritten log messages
}
Note that however AsyncHandler has usually higher overhead than the default handler since the asynchronous process involves locking and signal calls. We recommend to use AsyncHandler only if you know the overhead of the log writing is considerably high. LogRotationHandler is already optimized for writing logs to files, so you usually don't need to use AsyncHandler with LogRotationHandler.
Internals
Scala macro based logging code generation
wvlet-log is efficient since it generate the log message objects only when necessary. For example, this logging code:
debug(s"heavy debug log generation ${obj.toString}")
will be translated into the following efficient one with Scala macros:
if(logger.isDebugEnabled) {
debug(s"heavy debug log generation ${obj.toString}")
}
Log message String generation will not happen unless the debug log is effective. Scala macro is also used for finding source code location (LogSource).
Why it uses java.util.logging instead of slf4j?
slf4j is just an API for logging string messages, so there is no way to configure the log levels and log format within your program. To use slf4j, you always need to include an slf4j binding library, such as logback-classic. slf4j's logging configuration is binder-specific (e.g., slf4j-simple, logback-classic, etc.), and your application always need to include a dependency to one of the slf4j implementations. There is nothing wrong in it if these slf4j bindings are used properly, but third-party libraries often include slf4j bindings as dependencies, and cause unexpected logging behaviour.
java.util.logging
is a standard API of Java and no binding library is required, but configuring java.util.logging
was still difficult and error prone (See an example in Stack Overflow)
wvlet-log makes things easier for Scala developers.
Related Projects
scala-logging: An wrapper of slf4j for Scala. This also uses Scala macros to make logging efficient. No built-in source code location format, and you still need some slf4j bindings and its configuration.
twitter/util-logging: This is also an wrapper of
java.util.logging
for Scala, but it doesn't use Scala macros, so you need to use an old sprintf style log generation, orifDebug(log)
method to avoid expensive log message generation.