All Projects → wvlet → Log

wvlet / Log

Licence: apache-2.0
Fancy logging library for Scala

Programming Languages

scala
5932 projects

Labels

Projects that are alternatives of or similar to Log

Serverless Es Logs
A Serverless plugin to transport logs to ElasticSearch
Stars: ✭ 51 (-15%)
Mutual labels:  logging
Autologging
一个非常强大的监控日志输出框架,支持 SpringAOP 和动态字节码注入两种方式输出方法执行的监控日志,而且包含链路追踪功能,只要一个注解即可开启所有功能
Stars: ✭ 56 (-6.67%)
Mutual labels:  logging
Yii2 Psr Log Target
Yii 2.0 log target that is able to write messages to PSR-3 compatible logger
Stars: ✭ 58 (-3.33%)
Mutual labels:  logging
Lager
A logging framework for Erlang/OTP
Stars: ✭ 1,060 (+1666.67%)
Mutual labels:  logging
Aspnetcorenlog
ASP.NET Core NLog MS SQL Server PostgreSQL MySQL Elasticsearch
Stars: ✭ 54 (-10%)
Mutual labels:  logging
Pygelf
Python logging handlers with GELF (Graylog Extended Log Format) support
Stars: ✭ 56 (-6.67%)
Mutual labels:  logging
Qtwebapp
QtWebApp is a HTTP server like Java servlets, written in C++ with the Qt framework.
Stars: ✭ 50 (-16.67%)
Mutual labels:  logging
Log Viewer
Web UI to viewing logs
Stars: ✭ 59 (-1.67%)
Mutual labels:  logging
Gin Glog
Gin middleware to use glog
Stars: ✭ 53 (-11.67%)
Mutual labels:  logging
Log
Structured logging package for Go.
Stars: ✭ 1,094 (+1723.33%)
Mutual labels:  logging
Raspberrypi tempmon
Raspberry pi CPU temperature monitor with many functions such as logging, GPIO output, graphing, email, alarm, notifications and stress testing. Python 3.
Stars: ✭ 52 (-13.33%)
Mutual labels:  logging
Slog
Structured, contextual, extensible, composable logging for Rust
Stars: ✭ 1,068 (+1680%)
Mutual labels:  logging
Heroku Logger
A dead simple logger, designed to be perfect for Heroku apps.
Stars: ✭ 57 (-5%)
Mutual labels:  logging
Plog
Portable, simple and extensible C++ logging library
Stars: ✭ 1,061 (+1668.33%)
Mutual labels:  logging
Wp Rest Api Log
WordPress plugin for logging REST API requests and responses
Stars: ✭ 58 (-3.33%)
Mutual labels:  logging
Log4cplus
log4cplus is a simple to use C++ logging API providing thread-safe, flexible, and arbitrarily granular control over log management and configuration. It is modelled after the Java log4j API.
Stars: ✭ 1,054 (+1656.67%)
Mutual labels:  logging
Ios Sdk
AppSpector is a debugging service for mobile apps
Stars: ✭ 56 (-6.67%)
Mutual labels:  logging
Pioneer Console Boilerplate
Dependency injection, logging and configuration in a .NET Core console application.
Stars: ✭ 60 (+0%)
Mutual labels:  logging
Bulk
👨‍💻 Bulk is a library for buffering the objects. Pipeline(Sink) receives the object and emits the object bulked.
Stars: ✭ 59 (-1.67%)
Mutual labels:  logging
Events
Go package for routing, formatting and publishing events produced by a program.
Stars: ✭ 57 (-5%)
Mutual labels:  logging

wvlet-log Gitter Chat Build Status Coverage Status Latest version Scala.js

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:

screenshot

Scala.js is also supported:

screenshot

Features

  • Simple to use
    • You can start logging by adding wvlet.log.LogSupport trait to your code. No need to write Logger.getLogger(xxx) anymore.
  • 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

Maven Central

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:

  1. log-test.properties in the classpath.
  2. 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:

Spec.scala

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:

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"

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, or ifDebug(log) method to avoid expensive log message generation.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].