Last active
August 29, 2015 14:21
-
-
Save padurean/86289cdb3c1c24456f94 to your computer and use it in GitHub Desktop.
Play 2 request logging using composed actions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Actions in controllers will be defined like this: | |
def create = ComposedAction.async(parse.tolerantJson) { implicit request => ... } | |
// instead of this: | |
def create = Action.async(parse.tolerantJson) { implicit request => ... } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package utils.actions | |
import scala.concurrent.Future | |
import play.api.mvc.{Action, ActionBuilder, Request, SimpleResult} | |
object ComposedAction extends ActionBuilder[Request] { | |
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = block(request) | |
// More actions can be composed here as in: LoggedAction(AuthenticatedAction(action)) | |
override def composeAction[A](action: Action[A]) = LoggedAction(action) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package utils.actions | |
import scala.concurrent.Future | |
import play.api.Logger | |
import play.api.libs.concurrent.Execution.Implicits.defaultContext | |
import play.api.libs.iteratee.{Enumeratee, Iteratee} | |
import play.api.libs.json.Json | |
import play.api.mvc._ | |
import spring.config.ApplicationConfiguration._ | |
case class LoggedAction[A](action: Action[A]) extends Action[A] { | |
private[this] val logger = Logger("utils.actions.LoggedAction") | |
def apply(request: Request[A]): Future[SimpleResult] = { | |
val httpMethod = request.method | |
val start = System.currentTimeMillis() | |
val futureResult = action(request) | |
if (logRequests && logRequestsMethods.contains(httpMethod.toUpperCase)) { | |
futureResult.map { result => | |
val duration = System.currentTimeMillis() - start | |
val uri = request.uri | |
val reqBody = request.body | |
val referrer = request.remoteAddress | |
val requestStr = s"Received Request @$start '$httpMethod $uri' with body '$reqBody'" | |
logger.info(s"$requestStr from $referrer. HTTP Response code: " + | |
s"${result.header.status}. Took $duration ms to respond.") | |
result.withHeaders("Request-Time" -> duration.toString) | |
} | |
} else { | |
futureResult | |
} | |
} | |
lazy val parser = action.parser | |
} | |
object LoggedAction extends ActionBuilder[Request] { | |
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = block(request) | |
override def composeAction[A](action: Action[A]) = LoggedAction(action) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment