diff --git a/akka-docs/rst/java/code/docs/http/javadsl/server/directives/DebuggingDirectivesExamplesTest.java b/akka-docs/rst/java/code/docs/http/javadsl/server/directives/DebuggingDirectivesExamplesTest.java index 3910d1f8fe..51dc4e0421 100644 --- a/akka-docs/rst/java/code/docs/http/javadsl/server/directives/DebuggingDirectivesExamplesTest.java +++ b/akka-docs/rst/java/code/docs/http/javadsl/server/directives/DebuggingDirectivesExamplesTest.java @@ -16,9 +16,11 @@ import akka.http.javadsl.model.headers.Host; import akka.http.javadsl.server.Route; import akka.http.javadsl.server.RequestContext; import akka.http.javadsl.testkit.JUnitRouteTest; + import java.util.function.Function; import java.util.function.BiFunction; import java.util.function.Consumer; + import akka.http.javadsl.model.Uri; import akka.http.javadsl.model.headers.Location; import akka.http.javadsl.server.directives.DebuggingDirectives; @@ -26,10 +28,13 @@ import akka.http.javadsl.server.directives.RouteDirectives; import akka.event.Logging; import akka.event.Logging.LogLevel; import akka.http.javadsl.server.directives.LogEntry; + import java.util.List; + import akka.http.scaladsl.server.Rejection; import static akka.event.Logging.InfoLevel; + import java.util.stream.Collectors; import java.util.Optional; @@ -39,18 +44,18 @@ public class DebuggingDirectivesExamplesTest extends JUnitRouteTest { public void testLogRequest() { //#logRequest // logs request with "get-user" - final Route routeBasicLogRequest = get(() -> + final Route routeBasicLogRequest = get(() -> logRequest("get-user", () -> complete("logged"))); - + // logs request with "get-user" as Info - final Route routeBasicLogRequestAsInfo = get(() -> + final Route routeBasicLogRequestAsInfo = get(() -> logRequest("get-user", InfoLevel(), () -> complete("logged"))); // logs just the request method at info level - Function requestMethodAsInfo = (request) -> + Function requestMethodAsInfo = (request) -> LogEntry.create(request.method().name(), InfoLevel()); - final Route routeUsingFunction = get(() -> + final Route routeUsingFunction = get(() -> logRequest(requestMethodAsInfo, () -> complete("logged"))); // tests: @@ -63,32 +68,31 @@ public class DebuggingDirectivesExamplesTest extends JUnitRouteTest { public void testLogRequestResult() { //#logRequestResult // using logRequestResult - // handle request to optionally generate a log entry - BiFunction> requestMethodAsInfo = + BiFunction> requestMethodAsInfo = (request, response) -> - (response.status().isSuccess()) ? - Optional.of( - LogEntry.create( - request.method().name() + ":" + response.status().intValue(), - InfoLevel())) + (response.status().isSuccess()) ? + Optional.of( + LogEntry.create( + request.method().name() + ":" + response.status().intValue(), + InfoLevel())) : Optional.empty(); // not a successful response // handle rejections to optionally generate a log entry - BiFunction, Optional> rejectionsAsInfo = + BiFunction, Optional> rejectionsAsInfo = (request, rejections) -> - (!rejections.isEmpty()) ? + (!rejections.isEmpty()) ? Optional.of( LogEntry.create( rejections .stream() .map(Rejection::toString) - .collect(Collectors.joining(", ")), + .collect(Collectors.joining(", ")), InfoLevel())) : Optional.empty(); // no rejections final Route route = get(() -> logRequestResultOptional( - requestMethodAsInfo, + requestMethodAsInfo, rejectionsAsInfo, () -> complete("logged"))); // tests: @@ -109,16 +113,16 @@ public class DebuggingDirectivesExamplesTest extends JUnitRouteTest { // logs the result and the rejections as LogEntry Function showSuccessAsInfo = (response) -> - LogEntry.create(String.format("Response code '%d'", response.status().intValue()), + LogEntry.create(String.format("Response code '%d'", response.status().intValue()), InfoLevel()); Function, LogEntry> showRejectionAsInfo = (rejections) -> LogEntry.create( rejections - .stream() - .map(rejection -> rejection.toString()) - .collect(Collectors.joining(", ")), - InfoLevel()); + .stream() + .map(rejection -> rejection.toString()) + .collect(Collectors.joining(", ")), + InfoLevel()); final Route routeUsingFunction = get(() -> logResult(showSuccessAsInfo, showRejectionAsInfo, () -> complete("logged"))); @@ -128,4 +132,50 @@ public class DebuggingDirectivesExamplesTest extends JUnitRouteTest { //#logResult } -} \ No newline at end of file + @Test + public void testLogRequestResultWithResponseTime() { + //#logRequestResultWithResponseTime + // using logRequestResultOptional for generating Response Time + // handle request to optionally generate a log entry + + BiFunction> requestMethodAsInfo = + (request, response) -> { + Long requestTime = System.nanoTime(); + return printResponseTime(request, response, requestTime); + }; + + // handle rejections to optionally generate a log entry + BiFunction, Optional> rejectionsAsInfo = + (request, rejections) -> + (!rejections.isEmpty()) ? + Optional.of( + LogEntry.create( + rejections + .stream() + .map(Rejection::toString) + .collect(Collectors.joining(", ")), + InfoLevel())) + : Optional.empty(); // no rejections + + final Route route = get(() -> logRequestResultOptional( + requestMethodAsInfo, + rejectionsAsInfo, + () -> complete("logged"))); + // tests: + testRoute(route).run(HttpRequest.GET("/")).assertEntity("logged"); + //#logRequestResult + } + + // A function for the logging of Time + public static Optional printResponseTime(HttpRequest request, HttpResponse response, Long requestTime) { + if (response.status().isSuccess()) { + Long elapsedTime = (requestTime - System.nanoTime()) / 1000000; + return Optional.of( + LogEntry.create( + "Logged Request:" + request.method().name() + ":" + request.getUri() + ":" + response.status() + ":" + elapsedTime, + InfoLevel())); + } else { + return Optional.empty(); //not a successfull response + } + } +} diff --git a/akka-docs/rst/java/http/routing-dsl/directives/debugging-directives/logRequestResult.rst b/akka-docs/rst/java/http/routing-dsl/directives/debugging-directives/logRequestResult.rst index 079935e653..a71b4f2a14 100644 --- a/akka-docs/rst/java/http/routing-dsl/directives/debugging-directives/logRequestResult.rst +++ b/akka-docs/rst/java/http/routing-dsl/directives/debugging-directives/logRequestResult.rst @@ -14,3 +14,10 @@ See :ref:`-logRequest-java-` for the general description how these directives wo Example ------- .. includecode:: ../../../../code/docs/http/javadsl/server/directives/DebuggingDirectivesExamplesTest.java#logRequestResult + +Longer Example +-------------- + +This example shows how to log the response time of the request using the Debugging Directive + +.. includecode:: ../../../../code/docs/http/javadsl/server/directives/DebuggingDirectivesExamplesTest.java#logRequestResultWithResponseTime diff --git a/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/DebuggingDirectivesExamplesSpec.scala b/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/DebuggingDirectivesExamplesSpec.scala index 37239609a5..18ff2eae4b 100644 --- a/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/DebuggingDirectivesExamplesSpec.scala +++ b/akka-docs/rst/scala/code/docs/http/scaladsl/server/directives/DebuggingDirectivesExamplesSpec.scala @@ -4,9 +4,11 @@ package docs.http.scaladsl.server.directives -import akka.event.Logging +import akka.event.{LoggingAdapter, Logging} +import akka.event.Logging.LogLevel import akka.http.scaladsl.model.{ HttpRequest, HttpResponse } import akka.http.scaladsl.server.RouteResult +import akka.http.scaladsl.server.RouteResult.{Rejected, Complete} import akka.http.scaladsl.server.directives.{ DebuggingDirectives, LogEntry, LoggingMagnet } import docs.http.scaladsl.server.RoutingSpec @@ -95,4 +97,31 @@ class DebuggingDirectivesExamplesSpec extends RoutingSpec { responseAs[String] shouldEqual "logged" } } + "logRequestResultWithResponseTime" in { + + def akkaResponseTimeLoggingFunction(loggingAdapter: LoggingAdapter, + requestTimestamp: Long, + level: LogLevel = Logging.InfoLevel)(req: HttpRequest)(res: Any): Unit = { + val entry = res match { + case Complete(resp) => + val responseTimestamp: Long = System.nanoTime + val elapsedTime: Long = (responseTimestamp - requestTimestamp) / 1000000 + val loggingString = s"""Logged Request:${req.method}:${req.uri}:${resp.status}:${elapsedTime}""" + LogEntry(loggingString, level) + case Rejected(reason) => + LogEntry(s"Rejected Reason: ${reason.mkString(",")}", level) + } + entry.logTo(loggingAdapter) + } + def printResponseTime(log: LoggingAdapter) = { + val requestTimestamp = System.nanoTime + akkaResponseTimeLoggingFunction(log, requestTimestamp)(_) + } + + val logResponseTime = DebuggingDirectives.logRequestResult(LoggingMagnet(printResponseTime(_))) + + Get("/") ~> logResponseTime(complete("logged")) ~> check { + responseAs[String] shouldEqual "logged" + } + } } diff --git a/akka-docs/rst/scala/http/routing-dsl/directives/debugging-directives/logRequestResult.rst b/akka-docs/rst/scala/http/routing-dsl/directives/debugging-directives/logRequestResult.rst index 23c2f42e04..7bc199dc36 100644 --- a/akka-docs/rst/scala/http/routing-dsl/directives/debugging-directives/logRequestResult.rst +++ b/akka-docs/rst/scala/http/routing-dsl/directives/debugging-directives/logRequestResult.rst @@ -30,3 +30,13 @@ Example .. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/DebuggingDirectivesExamplesSpec.scala :snippet: logRequestResult + + +Building Advanced Directives +---------------------------- + +This example will showcase the advanced logging using the ``DebuggingDirectives``. +The built `logResponseTime ` directive will log the request time (or rejection reason): + +.. includecode2:: ../../../../code/docs/http/scaladsl/server/directives/DebuggingDirectivesExamplesSpec.scala + :snippet: logRequestResultWithResponseTime