user1207632
user1207632

Reputation: 767

How to log request/response in lift

I have a lift project in which
there is a class extending RestHelper that looks like this

   serve{
        "api" / "mystuff" prefix {
         case a => ...
         case b => ...
          }
    }

How can i log all the requests(including POST parameters) and responses without adding it to each case statement?

Upvotes: 2

Views: 401

Answers (3)

Dan Gravell
Dan Gravell

Reputation: 8230

As per Debugging a Request in the Lift Cookbook, you can use LiftRules.onBeginServicing and LiftRules.onEndServicing:

LiftRules.onBeginServicing.append {
  case r => println("Received: "+r)
}

LiftRules.onEndServicing.append {
    case (req, Full(resp)) => println("Responded: " + resp)
}

Upvotes: 0

Johnny Everson
Johnny Everson

Reputation: 8591

To log the requests you can use LiftRules.statelessRewrite (in bootstrap.liftweb.Boot):

LiftRules.statelessRewrite.append {
   case RewriteRequest(ParsePath("api" :: key :: Nil, "", true, _), _, _) =>
      log.info("REST: %s" format key)
      RewriteResponse("api" :: key :: Nil,true)
}

That will be intercepted before the following rest server:

case "api":: key :: Nil Get _ => {
  val email = S.param("email") getOrElse {
    "missing email parameter"
  }
  Full(PlainTextResponse("succeeded: %s, %s" format (key,email)))
}

Note that url params are kept.

To log the responses you use LiftRules.afterSend

UPDATE:

Using afterSend you can actually access both request and response.

Upvotes: 2

Dave Whittaker
Dave Whittaker

Reputation: 3102

The serve and prefix methods each take a PartialFunction[Req, Box[LiftResponse]]. You aren't using those types directly because RestHelper gives you a lot of handy methods and implicit conversions, but you still can access the Req directly. If you are only interested in logging access to "api" / "mystuff" prefixed URLS, it's dirty, but I think you could do something like this:

object Log {

  def unapply(req: Req): Option[Boolean] = {
     ... code to log the request ....
     None
   }

}

serve{
  "api" / "mystuff" prefix {
    case Log(true) => //matching code will always be called but never match
    case a => ...
    case b => ...
  }
}

Upvotes: 1

Related Questions