aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlad <vlad@driver.xyz>2017-05-19 17:26:33 -0700
committervlad <vlad@driver.xyz>2017-05-19 17:26:33 -0700
commitad33ff15ff642b29e21a82c3e8625feb12567aa7 (patch)
tree44c876b95d22d03c311a7588188f23f740526444
parent6427b9dc1a60b670c70aca05f419e3fc3313cf6a (diff)
downloaddriver-core-ad33ff15ff642b29e21a82c3e8625feb12567aa7.tar.gz
driver-core-ad33ff15ff642b29e21a82c3e8625feb12567aa7.tar.bz2
driver-core-ad33ff15ff642b29e21a82c3e8625feb12567aa7.zip
Http stacktracing using headers to see which hosts this request was passing
-rw-r--r--src/main/scala/xyz/driver/core/app.scala35
-rw-r--r--src/main/scala/xyz/driver/core/file/S3Storage.scala12
-rw-r--r--src/main/scala/xyz/driver/core/rest.scala21
3 files changed, 49 insertions, 19 deletions
diff --git a/src/main/scala/xyz/driver/core/app.scala b/src/main/scala/xyz/driver/core/app.scala
index e35c300..5a6dbbc 100644
--- a/src/main/scala/xyz/driver/core/app.scala
+++ b/src/main/scala/xyz/driver/core/app.scala
@@ -31,7 +31,8 @@ import scalaz.syntax.equal._
object app {
- class DriverApp(version: String,
+ class DriverApp(appName: String,
+ version: String,
gitHash: String,
modules: Seq[Module],
time: TimeProvider = new SystemTimeProvider(),
@@ -78,14 +79,11 @@ object app {
{ ctx =>
val trackingId = rest.extractTrackingId(ctx.request)
MDC.put("trackingId", trackingId)
- MDC.put("origin", origin)
- MDC.put("xForwardedFor",
- extractHeader(ctx.request)("x-forwarded-for")
- .orElse(extractHeader(ctx.request)("x_forwarded_for"))
- .getOrElse("unknown"))
- MDC.put("remoteAddress", extractHeader(ctx.request)("remote-address").getOrElse("unknown"))
- MDC.put("userAgent", extractHeader(ctx.request)("user-agent").getOrElse("unknown"))
- MDC.put("ip", ip.toOption.map(_.getHostAddress).getOrElse("unknown"))
+
+ val updatedStacktrace = (rest.extractStacktrace(ctx.request) ++ Array(appName)).mkString("->")
+ MDC.put("stack", updatedStacktrace)
+
+ storeRequestContextToMdc(ctx.request, origin, ip)
def requestLogging: Future[Unit] = Future {
log.info(
@@ -93,7 +91,10 @@ object app {
}
val contextWithTrackingId =
- ctx.withRequest(ctx.request.addHeader(RawHeader(ContextHeaders.TrackingIdHeader, trackingId)))
+ ctx.withRequest(
+ ctx.request
+ .addHeader(RawHeader(ContextHeaders.TrackingIdHeader, trackingId))
+ .addHeader(RawHeader(ContextHeaders.StacktraceHeader, updatedStacktrace)))
handleExceptions(ExceptionHandler(exceptionHandler))({ c =>
requestLogging.flatMap { _ =>
@@ -111,6 +112,20 @@ object app {
}
}
+ private def storeRequestContextToMdc(request: HttpRequest, origin: String, ip: RemoteAddress) = {
+
+ MDC.put("origin", origin)
+ MDC.put("ip", ip.toOption.map(_.getHostAddress).getOrElse("unknown"))
+ MDC.put("remoteHost", ip.toOption.map(_.getHostName).getOrElse("unknown"))
+
+ MDC.put("xForwardedFor",
+ extractHeader(request)("x-forwarded-for")
+ .orElse(extractHeader(request)("x_forwarded_for"))
+ .getOrElse("unknown"))
+ MDC.put("remoteAddress", extractHeader(request)("remote-address").getOrElse("unknown"))
+ MDC.put("userAgent", extractHeader(request)("user-agent").getOrElse("unknown"))
+ }
+
/**
* Override me for custom exception handling
*
diff --git a/src/main/scala/xyz/driver/core/file/S3Storage.scala b/src/main/scala/xyz/driver/core/file/S3Storage.scala
index 50bfe85..933b01a 100644
--- a/src/main/scala/xyz/driver/core/file/S3Storage.scala
+++ b/src/main/scala/xyz/driver/core/file/S3Storage.scala
@@ -53,11 +53,13 @@ class S3Storage(s3: AmazonS3, bucket: Name[Bucket], executionContext: ExecutionC
result.isTruncated
} flatMap { result =>
result.getObjectSummaries.asScala.toList.map { summary =>
- FileLink(Name[File](summary.getKey),
- Paths.get(path.toString + "/" + summary.getKey),
- Revision[File](summary.getETag),
- Time(summary.getLastModified.getTime),
- summary.getSize)
+ FileLink(
+ Name[File](summary.getKey),
+ Paths.get(path.toString + "/" + summary.getKey),
+ Revision[File](summary.getETag),
+ Time(summary.getLastModified.getTime),
+ summary.getSize
+ )
} filterNot isInSubFolder(path)
} toList
})
diff --git a/src/main/scala/xyz/driver/core/rest.scala b/src/main/scala/xyz/driver/core/rest.scala
index f1eab45..7e6c800 100644
--- a/src/main/scala/xyz/driver/core/rest.scala
+++ b/src/main/scala/xyz/driver/core/rest.scala
@@ -18,6 +18,7 @@ import com.typesafe.config.Config
import io.swagger.models.Scheme
import xyz.driver.core.auth._
import xyz.driver.core.time.provider.TimeProvider
+import org.slf4j.MDC
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}
@@ -41,9 +42,14 @@ package rest {
.fold(java.util.UUID.randomUUID.toString)(_.value())
}
+ def extractStacktrace(request: HttpRequest): Array[String] =
+ request.headers.find(_.name == ContextHeaders.StacktraceHeader).fold("")(_.value()).split("->")
+
def extractContextHeaders(request: HttpRequest): Map[String, String] = {
request.headers.filter { h =>
- h.name === ContextHeaders.AuthenticationTokenHeader || h.name === ContextHeaders.TrackingIdHeader
+ h.name === ContextHeaders.AuthenticationTokenHeader ||
+ h.name === ContextHeaders.TrackingIdHeader ||
+ h.name === ContextHeaders.StacktraceHeader
} map { header =>
if (header.name === ContextHeaders.AuthenticationTokenHeader) {
header.name -> header.value.stripPrefix(ContextHeaders.AuthenticationHeaderPrefix).trim
@@ -106,6 +112,7 @@ package rest {
val PermissionsTokenHeader = "Permissions"
val AuthenticationHeaderPrefix = "Bearer"
val TrackingIdHeader = "X-Trace"
+ val StacktraceHeader = "X-Stacktrace"
}
object AuthProvider {
@@ -265,9 +272,15 @@ package rest {
val requestTime = time.currentTime()
val request = requestStub
- .withHeaders(RawHeader(ContextHeaders.TrackingIdHeader, context.trackingId))
- .withHeaders(context.contextHeaders.toSeq.map { h =>
- RawHeader(h._1, h._2): HttpHeader
+ .withHeaders(context.contextHeaders.toSeq.map {
+ case (ContextHeaders.TrackingIdHeader, headerValue) =>
+ RawHeader(ContextHeaders.TrackingIdHeader, context.trackingId)
+ case (ContextHeaders.StacktraceHeader, headerValue) =>
+ RawHeader(ContextHeaders.StacktraceHeader,
+ Option(MDC.get("stack"))
+ .orElse(context.contextHeaders.get(ContextHeaders.StacktraceHeader))
+ .getOrElse(""))
+ case (header, headerValue) => RawHeader(header, headerValue)
}: _*)
log.info(s"Sending request to ${request.method} ${request.uri}")