Skip to content

Latest commit

 

History

History
 
 

util-slf4j-api

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Twitter Util SLF4J API Support

This library provides a Scala-friendly logging wrapper around the slf4j-api Logger interface.

Differences with util-logging

The code in util-logging is a scala wrapper over java.util.logging (JUL) which is a logging API and implementation. util-slf4j-api is an API-only and adds a thin scala wrapper over the slf4j-api which allows users to choose their logging implementation. It is recommended that users move to using util-slf4j-api over util-logging.

Since the slf4j-api is only an interface it requires an actual logging implementation. You should ensure that you do not end-up with multiple logging implementations on your classpath, e.g., you should not have multiple SLF4J bindings (slf4j-nop, slf4j-log4j12, slf4j-jdk14, etc.) and/or a java.util.logging implementation, etc. on your classpath as these are all competing implementations and since classpath order is non-deterministic, can lead to unexpected logging behavior.

Usages

You can create a c.t.util.logging.Logger in different ways. You can pass a name to the Logger#apply factory method on the c.t.util.logging.Logger companion object:

val logger = Logger("name") // scala

or in Java, use the Logger#getLogger method:

Logger log = Logger.getLogger("name"); // java

Or, pass in a class:

val logger = Logger(classOf[MyClass]) // scala
Logger log = Logger.getLogger(MyClass.class); // java

Or, use the runtime class wrapped by the implicit ClassTag parameter:

val logger = Logger[MyClass] // scala

Or, finally, use an SLF4J Logger instance:

val logger = Logger(LoggerFactory.getLogger("name")) // scala
Logger log = Logger.getLogger(LoggerFactory.getLogger("name")); // java

There is also the c.t.util.logging.Logging trait which can be mixed into a class. Note, that the underlying SLF4J logger will be named according to the leaf class of any hierarchy into which the trait is mixed:

package com.twitter

class Stock(symbol: String, price: BigDecimal) extends Logging {
  info(f"New stock with symbol = $symbol and price = $price%1.2f")
  ...
}

This would produce a logging statement along the lines of:

2017-01-05 13:05:49,349 INF c.t.Stock New stock with symbol = ASDF and price = 100.00

If you are using Java and happen to extend a Scala class which mixes in the c.t.util.logging.Logging trait, you can either access the logger directly or choose to instantiate a new logger in your Java class to log your statements. Again, note that the underlying SLF4J logger when mixed in via the trait will be named according to the leaf class into which it is mixed.

E.g., for a Scala class:

class MyBaseScalaClass extends Logging {
  ...
}

You could choose to use the inherited logger instance directly (since the inherited c.t.util.logging.Logging trait methods would require using a scala.Function0 as the trait methods are explicitly call-by-name):

class MyJavaClass extends MyBaseScalaClass {
  ...

  public void methodThatDoesSomeLogging() {
    logger().info("Accessing the superclass logger");
  }
}

Or instantiate a new logger explicitly:

class MyJavaClass extends MyBaseScalaClass {
  private static final Logger LOG = Logger.getLogger(MyJavaClass.class);

  ...

  public void methodThatDoesSomeLogging() {
    LOG.info("Accessing the superclass logger");
  }
}

For another Scala class which extends the above example Scala class with the mixed-in c.t.util.logging.Logging trait, you have the same options along with:

  • simply use the inherited Logging trait methods.
  • extend the c.t.util.logging.Logging trait again.