Skip to content

Commit

Permalink
logger taking constructor arg macro, for when you have a context, but…
Browse files Browse the repository at this point in the history
… you don't want to pass it each time via implicit for every call, just set it once when you instantiate the logger.

see lightbend-labs#208
  • Loading branch information
grunzwei committed Mar 24, 2020
1 parent 686b4c7 commit 338c76a
Show file tree
Hide file tree
Showing 8 changed files with 878 additions and 64 deletions.
85 changes: 85 additions & 0 deletions src/main/scala/com/typesafe/scalalogging/ALogger.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.typesafe.scalalogging

import org.slf4j.Marker

/**
*
* abstract class common for both Logger and LoggerTakingConstructorArg,
* if you have a library that is sometimes used in a context - in which case you want to log the context,
* but other times is used outside of a context in which case you want to log "normally", your base class can have a logger of this abstract type
*/
trait ALogger {

// Error

def error(message: String): Unit = {}

def error(message: String, cause: Throwable): Unit = {}

def error(message: String, args: Any*): Unit = {}

def error(marker: Marker, message: String): Unit = {}

def error(marker: Marker, message: String, cause: Throwable): Unit = {}

def error(marker: Marker, message: String, args: Any*): Unit = {}

// Warn

def warn(message: String): Unit = {}

def warn(message: String, cause: Throwable): Unit = {}

def warn(message: String, args: Any*): Unit = {}

def warn(marker: Marker, message: String): Unit = {}

def warn(marker: Marker, message: String, cause: Throwable): Unit = {}

def warn(marker: Marker, message: String, args: Any*): Unit = {}

// Info

def info(message: String): Unit = {}

def info(message: String, cause: Throwable): Unit = {}

def info(message: String, args: Any*): Unit = {}

def info(marker: Marker, message: String): Unit = {}

def info(marker: Marker, message: String, cause: Throwable): Unit = {}

def info(marker: Marker, message: String, args: Any*): Unit = {}

// Debug

def debug(message: String): Unit = {}

def debug(message: String, cause: Throwable): Unit = {}

def debug(message: String, args: Any*): Unit = {}

def debug(marker: Marker, message: String): Unit = {}

def debug(marker: Marker, message: String, cause: Throwable): Unit = {}

def debug(marker: Marker, message: String, args: Any*): Unit = {}

// Trace

def trace(message: String): Unit = {}

def trace(message: String, cause: Throwable): Unit = {}

def trace(message: String, args: Any*): Unit = {}

def trace(marker: Marker, message: String): Unit = {}

def trace(marker: Marker, message: String, cause: Throwable): Unit = {}

def trace(marker: Marker, message: String, args: Any*): Unit = {}

}


96 changes: 65 additions & 31 deletions src/main/scala/com/typesafe/scalalogging/Logger.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ object Logger {
def takingImplicit[A](underlying: Underlying)(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
new LoggerTakingImplicit[A](underlying)

/**
* Create a [[LoggerTakingConstructorArg]] wrapping the given underlying `org.slf4j.Logger`.
*/
def inContextOf[A](underlying: Underlying)(implicit ev: CanLog[A], a: A): LoggerTakingConstructorArg[A] =
new LoggerTakingConstructorArg[A](underlying, ev, a)

/**
* Create a [[Logger]] for the given name.
* Example:
Expand All @@ -57,6 +63,17 @@ object Logger {
def takingImplicit[A](name: String)(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
new LoggerTakingImplicit[A](LoggerFactory.getLogger(name))


/**
* Create a [[LoggerTakingConstructorArg]] for the given name.
* Example:
* {{{
* val logger = Logger.inContextOf[CorrelationId]("application")
* }}}
*/
def inContextOf[A](name: String)(implicit ev: CanLog[A], a: A): LoggerTakingConstructorArg[A] =
new LoggerTakingConstructorArg[A](LoggerFactory.getLogger(name), ev, a)

/**
* Create a [[Logger]] wrapping the created underlying `org.slf4j.Logger`.
*/
Expand All @@ -69,6 +86,12 @@ object Logger {
def takingImplicit[A](clazz: Class[_])(implicit ev: CanLog[A]): LoggerTakingImplicit[A] =
new LoggerTakingImplicit[A](LoggerFactory.getLogger(clazz.getName))

/**
* Create a [[LoggerTakingConstructorArg]] named after the given class parameter.
*/
def inContextOf[A](clazz: Class[_])(implicit ev: CanLog[A], a: A): LoggerTakingConstructorArg[A] =
new LoggerTakingConstructorArg[A](LoggerFactory.getLogger(clazz.getName), ev, a)

/**
* Create a [[Logger]] for the runtime class wrapped by the implicit class
* tag parameter.
Expand All @@ -90,91 +113,102 @@ object Logger {
*/
def takingImplicit[T, A](implicit ct: ClassTag[T], ev: CanLog[A]): LoggerTakingImplicit[A] =
new LoggerTakingImplicit[A](LoggerFactory.getLogger(ct.runtimeClass.getName.stripSuffix("$")))

/**
* Create a [[LoggerTakingConstructorArg]] for the runtime class wrapped by the implicit class
* tag parameter.
* Example:
* {{{
* val logger = Logger.inContextOf[MyClass, CorrelationId]
* }}}
*/
def inContextOf[T,A](implicit ct: ClassTag[T], ev: CanLog[A], a: A): LoggerTakingConstructorArg[A] =
new LoggerTakingConstructorArg[A](LoggerFactory.getLogger(ct.runtimeClass.getName.stripSuffix("$")), ev, a)
}

/**
* Implementation of a fast logger based on macros and an underlying `org.slf4j.Logger`.
*/
@SerialVersionUID(538248225L)
final class Logger private (val underlying: Underlying) extends Serializable {
final class Logger private (val underlying: Underlying) extends ALogger with Serializable {

// Error

def error(message: String): Unit = macro LoggerMacro.errorMessage
override def error(message: String): Unit = macro LoggerMacro.errorMessage

def error(message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCause
override def error(message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCause

def error(message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgs
override def error(message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgs

def error(marker: Marker, message: String): Unit = macro LoggerMacro.errorMessageMarker
override def error(marker: Marker, message: String): Unit = macro LoggerMacro.errorMessageMarker

def error(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCauseMarker
override def error(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.errorMessageCauseMarker

def error(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgsMarker
override def error(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.errorMessageArgsMarker

def whenErrorEnabled(body: Unit): Unit = macro LoggerMacro.errorCode

// Warn

def warn(message: String): Unit = macro LoggerMacro.warnMessage
override def warn(message: String): Unit = macro LoggerMacro.warnMessage

def warn(message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCause
override def warn(message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCause

def warn(message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgs
override def warn(message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgs

def warn(marker: Marker, message: String): Unit = macro LoggerMacro.warnMessageMarker
override def warn(marker: Marker, message: String): Unit = macro LoggerMacro.warnMessageMarker

def warn(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCauseMarker
override def warn(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.warnMessageCauseMarker

def warn(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgsMarker
override def warn(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.warnMessageArgsMarker

def whenWarnEnabled(body: Unit): Unit = macro LoggerMacro.warnCode

// Info

def info(message: String): Unit = macro LoggerMacro.infoMessage
override def info(message: String): Unit = macro LoggerMacro.infoMessage

def info(message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCause
override def info(message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCause

def info(message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgs
override def info(message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgs

def info(marker: Marker, message: String): Unit = macro LoggerMacro.infoMessageMarker
override def info(marker: Marker, message: String): Unit = macro LoggerMacro.infoMessageMarker

def info(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCauseMarker
override def info(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.infoMessageCauseMarker

def info(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgsMarker
override def info(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.infoMessageArgsMarker

def whenInfoEnabled(body: Unit): Unit = macro LoggerMacro.infoCode

// Debug

def debug(message: String): Unit = macro LoggerMacro.debugMessage
override def debug(message: String): Unit = macro LoggerMacro.debugMessage

def debug(message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCause
override def debug(message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCause

def debug(message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgs
override def debug(message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgs

def debug(marker: Marker, message: String): Unit = macro LoggerMacro.debugMessageMarker
override def debug(marker: Marker, message: String): Unit = macro LoggerMacro.debugMessageMarker

def debug(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCauseMarker
override def debug(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.debugMessageCauseMarker

def debug(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgsMarker
override def debug(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.debugMessageArgsMarker

def whenDebugEnabled(body: Unit): Unit = macro LoggerMacro.debugCode

// Trace

def trace(message: String): Unit = macro LoggerMacro.traceMessage
override def trace(message: String): Unit = macro LoggerMacro.traceMessage

def trace(message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCause
override def trace(message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCause

def trace(message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgs
override def trace(message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgs

def trace(marker: Marker, message: String): Unit = macro LoggerMacro.traceMessageMarker
override def trace(marker: Marker, message: String): Unit = macro LoggerMacro.traceMessageMarker

def trace(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCauseMarker
override def trace(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerMacro.traceMessageCauseMarker

def trace(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgsMarker
override def trace(marker: Marker, message: String, args: Any*): Unit = macro LoggerMacro.traceMessageArgsMarker

def whenTraceEnabled(body: Unit): Unit = macro LoggerMacro.traceCode

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.typesafe.scalalogging

import org.slf4j.{Marker, Logger => Underlying}

import scala.language.experimental.macros

/**
* ALogger that takes some data A and uses it according to strategy CanLog[A] during every log operation.
* Useful for logging things in a context, such as a request id, assuming it's available during construction time.
* */
class LoggerTakingConstructorArg[A] private[scalalogging](val underlying: Underlying, val canLogEv: CanLog[A], val a: A) extends ALogger with Serializable with LogsAdditionalData[A] {

// Error

override def error(message: String): Unit = macro LoggerTakingConstructorArgMacro.errorMessage[A]

override def error(message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.errorMessageCause[A]

override def error(message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.errorMessageArgs[A]

override def error(marker: Marker, message: String): Unit = macro LoggerTakingConstructorArgMacro.errorMessageMarker[A]

override def error(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.errorMessageCauseMarker[A]

override def error(marker: Marker, message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.errorMessageArgsMarker[A]

// Warn

override def warn(message: String): Unit = macro LoggerTakingConstructorArgMacro.warnMessage[A]

override def warn(message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.warnMessageCause[A]

override def warn(message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.warnMessageArgs[A]

override def warn(marker: Marker, message: String): Unit = macro LoggerTakingConstructorArgMacro.warnMessageMarker[A]

override def warn(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.warnMessageCauseMarker[A]

override def warn(marker: Marker, message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.warnMessageArgsMarker[A]

// Info

override def info(message: String): Unit = macro LoggerTakingConstructorArgMacro.infoMessage[A]

override def info(message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.infoMessageCause[A]

override def info(message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.infoMessageArgs[A]

override def info(marker: Marker, message: String): Unit = macro LoggerTakingConstructorArgMacro.infoMessageMarker[A]

override def info(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.infoMessageCauseMarker[A]

override def info(marker: Marker, message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.infoMessageArgsMarker[A]

// Debug

override def debug(message: String): Unit = macro LoggerTakingConstructorArgMacro.debugMessage[A]

override def debug(message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.debugMessageCause[A]

override def debug(message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.debugMessageArgs[A]

override def debug(marker: Marker, message: String): Unit = macro LoggerTakingConstructorArgMacro.debugMessageMarker[A]

override def debug(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.debugMessageCauseMarker[A]

override def debug(marker: Marker, message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.debugMessageArgsMarker[A]

// Trace

override def trace(message: String): Unit = macro LoggerTakingConstructorArgMacro.traceMessage[A]

override def trace(message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.traceMessageCause[A]

override def trace(message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.traceMessageArgs[A]

override def trace(marker: Marker, message: String): Unit = macro LoggerTakingConstructorArgMacro.traceMessageMarker[A]

override def trace(marker: Marker, message: String, cause: Throwable): Unit = macro LoggerTakingConstructorArgMacro.traceMessageCauseMarker[A]

override def trace(marker: Marker, message: String, args: Any*): Unit = macro LoggerTakingConstructorArgMacro.traceMessageArgsMarker[A]

}
Loading

0 comments on commit 338c76a

Please sign in to comment.