问题
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 namec.f.s.w.s.i.example
is the package nameExServiceImpl
is the class namegetStatus
is method name993
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