How do I configure Logback to print out the class name

无人久伴 提交于 2020-01-09 10:37:52

问题


I'm using Play 2.1. I'm using the default logger play.api.Logger. I'm confused about how it works.

In my scala code, a line in class "com.myapp.tickets" in the method "getPayment()" like this

Logger.info("getTickets")

generates a log message like this.

14:58:58.005 INFO  application play.api.LoggerLike$class info  getTickets

My application-logger.xml pattern is

%d{HH:mm:ss.SSS} %-5level %logger %class %method  %msg%n

The issue I have is that %logger tells me "application", %class tells me "play.api.LoggerLike$class and %method tells me "info". I know all of that. I of course want to avoid adding more cruft into the message itself (like the class name or method).

If I print out the call stack (%caller) then level 2 has what I want, but that does not seem a viable way to generate a log.

How do I configure it to output the application specific class and method, not the class and method of the logger itself?


回答1:


Logback pattern :

%d{HH:mm:ss.SSS} [%thread] %-5level %class{36}.%M %L - %msg%n

Result :

14:53:47.816 [http-bio-8080-exec-3] DEBUG  c.f.s.w.s.i.example.ExServiceImpl.getStatus 993 - blocked-->0
  • [http-bio-8080-exec-3] is the thread name

  • c.f.s.w.s.i.example is the package name

  • ExServiceImpl is the class name

  • getStatus is method name

  • 993 is the line number




回答2:


%class{0} will only output the class name, so instead of:

com.something.MyClass

You'll get:

MyClass

This is how my pattern for logback normally looks:

%d{HH:mm:ss} [%thread] %-5p %class{0} - %m%n

You can also add the method and the line if you are interested by doing:

%d{HH:mm:ss} [%thread] %-5p %class{0}.%method:%L - %m%n



回答3:


Old thread, but common problem. Play uses a wrapper around slf4j, which causes everything to be logged as [Logger$ALogger] or [application]. There are a few ways to log the actual class name.

Put this in your class:

private static org.slf4j.Logger logger = play.logger.underlying();

And put this in your methods:

logger.info("Your message");

Another option is to replace all of your Logger calls with this, but it will add overhead since it has to fetch the underlying object every time you want to log something:

Logger.underlying().info("Your message");



回答4:


I'm not sure that it's really what you want but do you try this? :

Logger(this.getClass()).info("getTickets")




回答5:


I'm in the process of abandoning the single application.log approach that Play seems to default to with its Logger. My application requires the kind-of fine grained logging and runtime adjustment of it that straight-up logback does so well when classname == Logger name. I've had pretty good success going just "old school" in my controllers like...

package controllers
import play.api._
import play.api.mvc._
import org.slf4j.LoggerFactory

object Application extends Controller {
  val log = LoggerFactory.getLogger(getClass())

  def index = Action {
    log.trace("index")
    NotFound
  }

  def hb = Action {
    log.trace("hb")
    val message = makeMessage()
    log.info(message)
    Ok(message)
  }

  def makeMessage(): String = {
    val version = "@buildsig.version@"
    val tag = "@buildsig.tag@"
    val timestamp = "@buildsig.timestamp@"
    val status = makeStatus()
    return "DM2 [Version: %s] [Build: %s] [Date: %s] [Status: %s]".format(version, tag, timestamp, status)
  }

  def makeStatus(): String = {
    // TODO: Implement datastore healthcheck
    return "TODO"
  }
}

For any developer used to slf4j/logback or log4j, this approach will seem familiar. On the other hand, I am currently struggling through start shell script from "play dist" fails to locate logger.xml in JAR file where by the start script is failing to use my conf/logger.xml that gets JARed up by the "play dist" command.

If I was just a little bit better of a Scala developer, I think the same effect can be achieved with something like a Logging trait.




回答6:


Since Play's Logger wraps the underlying SLF4J calls, the logger class is always "application":

13:45:21 INFO  application: - Some message

But there is an easy way round this.

Create a trait:

import play.api.Logger

trait WithLogging {
   val logger: Logger = Logger(this.getClass())
}

And in your classes just mix in the trait:

import WithLogging

class Foobarr extends WithLogging {
   def doFoo = {
      logger.info("Im in foooo")
   }
}

Now this should be:

13:45:21 INFO  models.Foobarr: - Im in foooo


来源:https://stackoverflow.com/questions/15258144/how-do-i-configure-logback-to-print-out-the-class-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!