Register all requests to Play 2

How can I log all requests coming in to the Play 2 application, similar to how Apache logs (i.e. including the URL and client IP)?

+4
source share
4 answers

What are http filters for? Here are some detailed examples: http://www.playframework.com/documentation/2.1.1/ScalaHttpFilters

+5
source

I wanted to do the same with Play 2.5.4. It took me a little time to assemble the pieces, so I decided to share my steps in the hope that this would save time for someone else:

  • Make sure you have an access registrar. Here is an example of how to configure it on https://www.playframework.com/documentation/2.5.x/SettingsLogger but you can play with the settings; I installed my logger with <file>${application.home:-.}/logs/access.log</file> and <immediateFlush>true</immediateFlush> .

  • Create a new RequestHandler in the root package, extending the default handler:

 import javax.inject.Inject import play.api.http._ import play.api.routing._ import play.api.mvc.RequestHeader import play.api.Logger /** * Implemented to get custom, apache-style logging of requests without dumping the full netty wire. */ class RequestHandler @Inject() (router: Router, errorHandler: HttpErrorHandler, configuration: HttpConfiguration, filters: HttpFilters) extends DefaultHttpRequestHandler( router, errorHandler, configuration, filters) { override def routeRequest(request: RequestHeader) = { Logger("access").info(s"Request from ${request.remoteAddress}: ${request}") super.routeRequest(request) } } 

I came from Play 2.3, so I originally planned to use GlobalSettings until I found this guide: https://www.playframework.com/documentation/2.5.x/GlobalSettings

I apologize for anyone who wants to get answers specific to Play 2.0, but when I saw that my own 2.5-oriented searches brought me here, I think that this answer will not harm.

+8
source

Create your own action much more powerful and flexible.

 object MyAction { def apply[A](bodyParser: BodyParser[A])(block: Request[A] => Result): Action[A] = Action(bodyParser) { request => // TODO : authentication, cache logics here // time it val start = ... // process val r = block(request) val end = ... // log remote address, user agent, time, etc. r } // simply override to use MyAction def apply(block: Request[AnyContent] => Result): Action[AnyContent] = this.apply(BodyParsers.parse.anyContent)(block) // simply override to use MyAction def apply(block: => Result): Action[AnyContent] = this.apply(_ => block) } 

to use it in the controller just replace Action with MyAction

 def index = MyAction { implicit request => // nothing to be changed here } 
0
source

In Play 2.5.x I used the following

 import javax.inject.Inject import akka.stream.Materializer import play.api.Logger import play.api.mvc._ import scala.concurrent.{ExecutionContext, Future} import java.util.Calendar import java.text.SimpleDateFormat class ApacheLoggingFilter @Inject() (implicit val mat: Materializer, ec: ExecutionContext) extends Filter { def apply(nextFilter: RequestHeader => Future[Result]) (requestHeader: RequestHeader): Future[Result] = { nextFilter(requestHeader).map { result => val responseSize = result.body.contentLength.getOrElse("-") Logger("access").info(s"""${requestHeader.remoteAddress} - - [${serverTime}] "${requestHeader}" ${result.header.status} ${responseSize}""") result } } private def serverTime = { val calendar = Calendar.getInstance() val dateFormat = new SimpleDateFormat( "dd/MMM/yyyy:HH:mm:ss Z") dateFormat.setTimeZone(calendar.getTimeZone) dateFormat.format(calendar.getTime()) } } 

Make sure you have configured this filter correctly - https://www.playframework.com/documentation/2.5.x/ScalaHttpFilters#Using-filters

0
source

Source: https://habr.com/ru/post/1482544/


All Articles