Merge pull request #16158 from spray/w/15920-DebuggingDirectives
+htp #15920 import DebuggingDirectives from spray
This commit is contained in:
commit
96ba0d07e5
3 changed files with 164 additions and 1 deletions
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.server
|
||||
package directives
|
||||
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.http.util._
|
||||
|
||||
class DebuggingDirectivesSpec extends RoutingSpec {
|
||||
var debugMsg = ""
|
||||
|
||||
def resetDebugMsg(): Unit = { debugMsg = "" }
|
||||
|
||||
val log = new LoggingAdapter {
|
||||
def isErrorEnabled = true
|
||||
def isWarningEnabled = true
|
||||
def isInfoEnabled = true
|
||||
def isDebugEnabled = true
|
||||
|
||||
def notifyError(message: String): Unit = {}
|
||||
def notifyError(cause: Throwable, message: String): Unit = {}
|
||||
def notifyWarning(message: String): Unit = {}
|
||||
def notifyInfo(message: String): Unit = {}
|
||||
def notifyDebug(message: String): Unit = { debugMsg += message + '\n' }
|
||||
}
|
||||
|
||||
"The 'logRequest' directive" should {
|
||||
"produce a proper log message for incoming requests" in {
|
||||
val route =
|
||||
withLog(log)(
|
||||
logRequest("1")(
|
||||
completeOk))
|
||||
|
||||
resetDebugMsg()
|
||||
Get("/hello") ~> route ~> check {
|
||||
response shouldEqual Ok
|
||||
debugMsg shouldEqual "1: HttpRequest(HttpMethod(GET),http://example.com/hello,List(),Strict(none/none,ByteString()),HttpProtocol(HTTP/1.1))\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"The 'logResponse' directive" should {
|
||||
"produce a proper log message for outgoing responses" in {
|
||||
val route =
|
||||
withLog(log)(
|
||||
logResult("2")(
|
||||
completeOk))
|
||||
|
||||
resetDebugMsg()
|
||||
Get("/hello") ~> route ~> check {
|
||||
response shouldEqual Ok
|
||||
debugMsg shouldEqual "2: Complete(HttpResponse(200 OK,List(),Strict(none/none,ByteString()),HttpProtocol(HTTP/1.1)))\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"The 'logRequestResponse' directive" should {
|
||||
"produce proper log messages for outgoing responses, thereby showing the corresponding request" in {
|
||||
val route =
|
||||
withLog(log)(
|
||||
logRequestResult("3")(
|
||||
completeOk))
|
||||
|
||||
resetDebugMsg()
|
||||
Get("/hello") ~> route ~> check {
|
||||
response shouldEqual Ok
|
||||
debugMsg shouldEqual """|3: Response for
|
||||
| Request : HttpRequest(HttpMethod(GET),http://example.com/hello,List(),Strict(none/none,ByteString()),HttpProtocol(HTTP/1.1))
|
||||
| Response: Complete(HttpResponse(200 OK,List(),Strict(none/none,ByteString()),HttpProtocol(HTTP/1.1)))
|
||||
|""".stripMarginWithNewline("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ trait Directives extends RouteConcatenation
|
|||
with CacheConditionDirectives
|
||||
//with ChunkingDirectives
|
||||
with CookieDirectives
|
||||
//with DebuggingDirectives
|
||||
with DebuggingDirectives
|
||||
with CodingDirectives
|
||||
with ExecutionDirectives
|
||||
//with FileAndResourceDirectives
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.server
|
||||
package directives
|
||||
|
||||
import akka.event.Logging._
|
||||
import akka.event.LoggingAdapter
|
||||
import akka.http.model._
|
||||
|
||||
trait DebuggingDirectives {
|
||||
import BasicDirectives._
|
||||
|
||||
def logRequest(magnet: LoggingMagnet[HttpRequest ⇒ Unit]): Directive0 =
|
||||
extractRequestContext.flatMap { ctx ⇒
|
||||
magnet.f(ctx.log)(ctx.request)
|
||||
pass
|
||||
}
|
||||
|
||||
def logResult(magnet: LoggingMagnet[RouteResult ⇒ Unit]): Directive0 =
|
||||
extractRequestContext.flatMap { ctx ⇒
|
||||
mapRouteResult { result ⇒
|
||||
magnet.f(ctx.log)(result)
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
def logRequestResult(magnet: LoggingMagnet[HttpRequest ⇒ RouteResult ⇒ Unit]): Directive0 =
|
||||
extractRequestContext.flatMap { ctx ⇒
|
||||
val logResult = magnet.f(ctx.log)(ctx.request)
|
||||
mapRouteResult { result ⇒
|
||||
logResult(result)
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object DebuggingDirectives extends DebuggingDirectives
|
||||
|
||||
case class LoggingMagnet[T](f: LoggingAdapter ⇒ T) // # logging-magnet
|
||||
|
||||
object LoggingMagnet {
|
||||
implicit def forMessageFromMarker[T](marker: String) = // # message-magnets
|
||||
forMessageFromMarkerAndLevel[T](marker -> DebugLevel)
|
||||
|
||||
implicit def forMessageFromMarkerAndLevel[T](markerAndLevel: (String, LogLevel)) = // # message-magnets
|
||||
forMessageFromFullShow[T] {
|
||||
val (marker, level) = markerAndLevel
|
||||
Message ⇒ LogEntry(Message, marker, level)
|
||||
}
|
||||
|
||||
implicit def forMessageFromShow[T](show: T ⇒ String) = // # message-magnets
|
||||
forMessageFromFullShow[T](msg ⇒ LogEntry(show(msg), DebugLevel))
|
||||
|
||||
implicit def forMessageFromFullShow[T](show: T ⇒ LogEntry): LoggingMagnet[T ⇒ Unit] = // # message-magnets
|
||||
LoggingMagnet(log ⇒ show(_).logTo(log))
|
||||
|
||||
implicit def forRequestResponseFromMarker(marker: String) = // # request-response-magnets
|
||||
forRequestResponseFromMarkerAndLevel(marker -> DebugLevel)
|
||||
|
||||
implicit def forRequestResponseFromMarkerAndLevel(markerAndLevel: (String, LogLevel)) = // # request-response-magnets
|
||||
forRequestResponseFromFullShow {
|
||||
val (marker, level) = markerAndLevel
|
||||
request ⇒ response ⇒ Some(
|
||||
LogEntry("Response for\n Request : " + request + "\n Response: " + response, marker, level))
|
||||
}
|
||||
|
||||
implicit def forRequestResponseFromFullShow(show: HttpRequest ⇒ RouteResult ⇒ Option[LogEntry]): LoggingMagnet[HttpRequest ⇒ RouteResult ⇒ Unit] = // # request-response-magnets
|
||||
LoggingMagnet { log ⇒
|
||||
request ⇒
|
||||
val showResult = show(request)
|
||||
result ⇒ showResult(result).foreach(_.logTo(log))
|
||||
}
|
||||
}
|
||||
|
||||
case class LogEntry(obj: Any, level: LogLevel = DebugLevel) {
|
||||
def logTo(log: LoggingAdapter): Unit = {
|
||||
log.log(level, obj.toString)
|
||||
}
|
||||
}
|
||||
|
||||
object LogEntry {
|
||||
def apply(obj: Any, marker: String, level: LogLevel): LogEntry =
|
||||
LogEntry(if (marker.isEmpty) obj else marker + ": " + obj, level)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue