From 0dc9f24cef4ea4e58afa59fab565e36796c0cb1d Mon Sep 17 00:00:00 2001 From: vlad Date: Fri, 31 Mar 2017 21:39:42 -0700 Subject: Logging clean up, Monadic execution utils --- src/main/scala/xyz/driver/core/app.scala | 8 ++--- src/main/scala/xyz/driver/core/execution.scala | 45 ++++++++++++++++++++++++++ src/main/scala/xyz/driver/core/rest.scala | 7 ++-- 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 src/main/scala/xyz/driver/core/execution.scala (limited to 'src') diff --git a/src/main/scala/xyz/driver/core/app.scala b/src/main/scala/xyz/driver/core/app.scala index 4966b9d..4b81897 100644 --- a/src/main/scala/xyz/driver/core/app.scala +++ b/src/main/scala/xyz/driver/core/app.scala @@ -99,26 +99,26 @@ object app { case is: IllegalStateException => ctx => MDC.put("trackingId", rest.extractTrackingId(ctx.request)) - log.error(s"Request is not allowed to ${ctx.request.uri}", is) + log.error(s"Request is not allowed to ${ctx.request.method} ${ctx.request.uri}", is) complete(HttpResponse(BadRequest, entity = is.getMessage))(ctx) case cm: ConcurrentModificationException => ctx => MDC.put("trackingId", rest.extractTrackingId(ctx.request)) - log.error(s"Concurrent modification of the resource ${ctx.request.uri}", cm) + log.error(s"Concurrent modification of the resource ${ctx.request.method} ${ctx.request.uri}", cm) complete( HttpResponse(Conflict, entity = "Resource was changed concurrently, try requesting a newer version"))(ctx) case sex: SQLException => ctx => MDC.put("trackingId", rest.extractTrackingId(ctx.request)) - log.error(s"Database exception for the resource ${ctx.request.uri}", sex) + log.error(s"Database exception for the resource ${ctx.request.method} ${ctx.request.uri}", sex) complete(HttpResponse(InternalServerError, entity = "Data access error"))(ctx) case t: Throwable => ctx => MDC.put("trackingId", rest.extractTrackingId(ctx.request)) - log.error(s"Request to ${ctx.request.uri} could not be handled normally", t) + log.error(s"Request to ${ctx.request.method} ${ctx.request.uri} could not be handled normally", t) complete(HttpResponse(InternalServerError, entity = t.getMessage))(ctx) } diff --git a/src/main/scala/xyz/driver/core/execution.scala b/src/main/scala/xyz/driver/core/execution.scala new file mode 100644 index 0000000..f27b905 --- /dev/null +++ b/src/main/scala/xyz/driver/core/execution.scala @@ -0,0 +1,45 @@ +package xyz.driver.core + +import scala.concurrent.{ExecutionContext, Future} +import scalaz.OptionT + +object execution { + + implicit class FutureOptionTExtensions[T](future: Future[T])(implicit executionContext: ExecutionContext) { + + def toOptionT: OptionT[Future, T] = + OptionT.optionT[Future](future.map(value => Option(value))) + + def returnUnit: Future[Unit] = + future.map(_ => Option(())) + + def returnUnitOpt: OptionT[Future, Unit] = + OptionT.optionT[Future](future.map(_ => Option(()))) + + def andEffect[E](effect: Future[E]): Future[T] = + for { + result <- future + _ <- effect + } yield result + + def andEffect[E](effect: OptionT[Future, E]): Future[T] = + andEffect(effect.run) + } + + def illegalState[T](message: String) = + failure(new IllegalStateException(message)) + + def illegalArgument[T](message: String) = + failure(new IllegalArgumentException(message)) + + def failure[T](throwable: Throwable) = + OptionT.optionT(Future.failed[Option[T]](throwable)) + + def collectOrNone[T, R](value: T)(f: PartialFunction[T, OptionT[Future, R]]): OptionT[Future, R] = + f.lift(value).getOrElse(OptionT.optionT(Future.successful(Option.empty[R]))) + + def collectOrDoNothing[T](value: T)(f: PartialFunction[T, OptionT[Future, Unit]]): OptionT[Future, Unit] = + f.lift(value).getOrElse(doNothing) + + val doNothing = OptionT.optionT(Future.successful(Option(()))) +} diff --git a/src/main/scala/xyz/driver/core/rest.scala b/src/main/scala/xyz/driver/core/rest.scala index aa2a75e..39f2cab 100644 --- a/src/main/scala/xyz/driver/core/rest.scala +++ b/src/main/scala/xyz/driver/core/rest.scala @@ -269,7 +269,7 @@ package rest { RawHeader(h._1, h._2): HttpHeader }: _*) - log.audit(s"Sending to ${request.uri} request $request with tracking id ${context.trackingId}") + log.audit(s"Sending request to ${request.method} ${request.uri}") val response = Http()(actorSystem).singleRequest(request)(materializer) @@ -281,8 +281,7 @@ package rest { case Failure(t: Throwable) => val responseTime = time.currentTime() - log.audit(s"Failed to receive response from ${request.uri} to request $requestStub", t) - log.error(s"Failed to receive response from ${request.uri} to request $requestStub", t) + log.error(s"Failed to receive response to ${request.method} ${request.uri}", t) stats.recordStats(Seq("request", request.uri.toString, "fail"), TimeRange(requestTime, responseTime), 1) }(executionContext) @@ -295,7 +294,7 @@ package rest { if (response.status == StatusCodes.NotFound) { Unmarshal(HttpEntity.Empty: ResponseEntity) } else if (response.status.isFailure()) { - throw new Exception(s"Http status is failure ${response.status}") + throw new Exception(s"Http status is failure ${response.status} for ${requestStub.method} ${requestStub.uri}") } else { Unmarshal(response.entity) } -- cgit v1.2.3