Skip to content

Commit

Permalink
Merge pull request #5 from davenverse/standardizeNamespacing
Browse files Browse the repository at this point in the history
Centralize Context Namespacing
  • Loading branch information
ChristopherDavenport authored Jul 12, 2023
2 parents 8009aa6 + 60ad617 commit d20c32b
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ object ClientMiddleware {
responseCtx = response(respBodyFinal.fold(pureResp)(body => pureResp.withBodyStream(Stream.chunk(body))), respHeaders, responseAdditionalContext)
responseBodyCtx = respBodyS.map(body => Map("http.response.body" -> body)).getOrElse(Map.empty)
outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](respBodyFinal.fold(pureResp)(body => pureResp.withBodyStream(Stream.chunk(body))).some)
outcomeCtx = outcomeContext(outcome)
outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
finalCtx = reqContext ++ responseCtx + outcomeCtx + headersDuration + bodyDuration ++ requestBodyCtx ++ responseBodyCtx
_ <- logLevelAware(logger, finalCtx, bodyPureReq, outcome, start, removedContextKeys, logLevel, logMessage)
} yield ()
Expand All @@ -249,7 +249,7 @@ object ClientMiddleware {
Resource.eval(Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.canceled[Option, Throwable, Response[Pure]]
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val reqContext = request(pureReq, reqHeaders, routeClassifier, requestIncludeUrl, requestAdditionalContext) +
HttpStructuredContext.Common.accessTime(start)
val finalCtx = reqContext + outcomeCtx + duration
Expand All @@ -259,7 +259,7 @@ object ClientMiddleware {
Resource.eval(Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.errored[Option, Throwable, Response[Pure]](e)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val reqContext = request(pureReq, reqHeaders, routeClassifier, requestIncludeUrl, requestAdditionalContext) +
HttpStructuredContext.Common.accessTime(start)
val finalCtx = reqContext + outcomeCtx + duration
Expand Down Expand Up @@ -304,15 +304,15 @@ object ClientMiddleware {
Resource.eval(Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.canceled[Option, Throwable, Response[Pure]]
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
})
case Outcome.Errored(e) =>
Resource.eval(Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.errored[Option, Throwable, Response[Pure]](e)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
})
Expand All @@ -323,7 +323,7 @@ object ClientMiddleware {
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val responseCtx = response(pureResp, respHeaders, responseAdditionalContext)
val outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](pureResp.some)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext ++ responseCtx + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
})
Expand Down Expand Up @@ -361,21 +361,19 @@ object ClientMiddleware {
routeClassifier(request).foreach(s =>
builder += HttpStructuredContext.Server.route(s)
)


builder += HttpStructuredContext.Common.flavor(request.httpVersion)

request.remote.foreach{sa =>
builder +=
HttpStructuredContext.Common.peerIp(sa.host)

builder +=
HttpStructuredContext.Common.peerPort(sa.port)
}
// Special Server
request.from.foreach(ip =>
builder += HttpStructuredContext.Server.clientIp(ip)
)
HttpStructuredContext.Client.peerName(request.uri).foreach { ctx =>
builder += ctx
}
builder ++=
HttpStructuredContext.Headers.request(request.headers, headers)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,40 @@ import org.http4s.headers._
import cats.syntax.all._
import com.comcast.ip4s._
import scala.concurrent.duration.FiniteDuration
import cats.effect.Outcome


object HttpStructuredContext {

object Common {
def method(m: Method): (String, String) = ("http.method", m.name)
def url(url: Uri): (String, String)= ("http.url", url.renderString)
def target(url: Uri): (String, String) = ("http.target", url.copy(scheme = None, authority = None).renderString)
def host(host: org.http4s.headers.Host): (String, String) = ("http.host", org.http4s.headers.Host.headerInstance.value(host))
def scheme(scheme: Uri.Scheme): (String, String) = ("http.scheme", scheme.value)
def method(m: Method): (String, String) = ("http.request.method", m.name)
def url(url: Uri): (String, String)= ("http.request.url", url.renderString)
def target(url: Uri): (String, String) = ("http.request.target", url.copy(scheme = None, authority = None).renderString)
def host(host: org.http4s.headers.Host): (String, String) = ("http.request.host", org.http4s.headers.Host.headerInstance.value(host))
def scheme(scheme: Uri.Scheme): (String, String) = ("http.request.scheme", scheme.value)

def status(status: Status): (String, String) = ("http.status_code", status.code.show)
def status(status: Status): (String, String) = ("http.response.status_code", status.code.show)
// Need to check both request and response in case negotiation happens
def flavor(httpVersion: HttpVersion): (String, String) = ("http.flavor", httpVersion.major.toString() ++ "." ++ httpVersion.minor.toString())
def userAgent(userAgent: `User-Agent`): (String, String) = ("http.user_agent", `User-Agent`.headerInstance.value(userAgent))
def requestContentLength(cl: Long): (String, String) = ("http.request_content_length", cl.show)
def responseContentLength(cl: Long): (String, String) = ("http.response_content_length", cl.show)
def userAgent(userAgent: `User-Agent`): (String, String) = ("http.request.user_agent", `User-Agent`.headerInstance.value(userAgent))
def requestContentLength(cl: Long): (String, String) = ("http.request.content_length", cl.show)
def responseContentLength(cl: Long): (String, String) = ("http.response.content_length", cl.show)
def retryCount(i: Int): (String, String)= ("http.retry_count", i.show)
def peerIp(ip: IpAddress): (String, String) = ("net.peer.ip", ip.toString()) // TODO: Check that this is the right way
def peerPort(port: Port): (String, String) = ("net.peer.port", port.value.show)

def logKind(logKind: String) = ("contextlog.kind", logKind)
def logKind(logKind: String) = ("http.kind", logKind)
def accessTime(duration: FiniteDuration) = ("http.access_time", duration.toMillis.toString)
def headersDuration(duration: FiniteDuration) = ("http.duration_ms", duration.toMillis.toString())
def bodyDuration(duration: FiniteDuration) = ("http.duration_body_ms", duration.toMillis.toString())
def outcome[F[_], E, A](outcome: Outcome[F, E, A]): (String, String) = {
outcome match {
case Outcome.Canceled() => "http.exit_case" -> "canceled"
case Outcome.Errored(_) => "http.exit_case" -> "errored"
case Outcome.Succeeded(_) => "http.exit_case" -> "succeeded"
}
}

}

object Client {
Expand Down Expand Up @@ -61,7 +70,7 @@ object HttpStructuredContext {
headers.headers.filter(h => s.contains(h.name))
.groupBy(r => (r.name))
.map{
case (name, list) => ("http." ++ messageType ++ ".header." ++ name.toString.toLowerCase, list.map(_.value).mkString(", "))
case (name, list) => ("http." ++ messageType ++ ".headers." ++ name.toString.toLowerCase, list.map(_.value).mkString(", "))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ object ServerMiddleware {
responseCtx = response(respBodyFinal.fold(pureResp)(body => pureResp.withBodyStream(Stream.chunk(body))), respHeaders, responseAdditionalContext)
responseBodyCtx = respBodyS.map(body => Map("http.response.body" -> body)).getOrElse(Map.empty)
outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](respBodyFinal.fold(pureResp)(body => pureResp.withBodyStream(Stream.chunk(body))).some)
outcomeCtx = outcomeContext(outcome)
outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
finalCtx = reqContext ++ responseCtx + outcomeCtx + headersDuration + bodyDuration ++ requestBodyCtx ++ responseBodyCtx
_ <- logLevelAware(logger, finalCtx, bodyPureReq, outcome, start, removedContextKeys, logLevel, logMessage)
} yield ()
Expand All @@ -252,7 +252,7 @@ object ServerMiddleware {
Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.canceled[Option, Throwable, Response[Pure]]
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val reqContext = request(pureReq, reqHeaders, routeClassifier, requestIncludeUrl, requestAdditionalContext) +
HttpStructuredContext.Common.accessTime(start)
val finalCtx = reqContext + outcomeCtx + duration
Expand All @@ -262,7 +262,7 @@ object ServerMiddleware {
Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.errored[Option, Throwable, Response[Pure]](e)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val reqContext = request(pureReq, reqHeaders, routeClassifier, requestIncludeUrl, requestAdditionalContext) +
HttpStructuredContext.Common.accessTime(start)
val finalCtx = reqContext + outcomeCtx + duration
Expand Down Expand Up @@ -348,7 +348,7 @@ object ServerMiddleware {
responseCtx = response(respBodyFinal.fold(pureResp)(body => pureResp.withBodyStream(Stream.chunk(body))), respHeaders, responseAdditionalContext)
responseBodyCtx = respBodyS.map(body => Map("http.response.body" -> body)).getOrElse(Map.empty)
outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](respBodyFinal.fold(pureResp)(body => pureResp.withBodyStream(Stream.chunk(body))).some)
outcomeCtx = outcomeContext(outcome)
outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
finalCtx = reqContext ++ responseCtx + outcomeCtx + headersDuration + bodyDuration ++ requestBodyCtx ++ responseBodyCtx
_ <- logLevelAware(logger, finalCtx, newPureReq, outcome, start, removedContextKeys, logLevel, logMessage)
} yield ()
Expand All @@ -364,7 +364,7 @@ object ServerMiddleware {
bodyDuration = HttpStructuredContext.Common.bodyDuration(bodyEnd.minus(start))
requestBodyCtx = reqBodyS.map(body => Map("http.request.body" -> body)).getOrElse(Map.empty)
outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](None)
outcomeCtx = outcomeContext(outcome)
outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
finalCtx = reqContext + outcomeCtx + headersDuration + bodyDuration ++ requestBodyCtx
_ <- logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
} yield ()
Expand All @@ -377,7 +377,7 @@ object ServerMiddleware {
OptionT.liftF(Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.canceled[Option, Throwable, Response[Pure]]
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val reqContext = request(pureReq, reqHeaders, routeClassifier, requestIncludeUrl, requestAdditionalContext) +
HttpStructuredContext.Common.accessTime(start)
val finalCtx = reqContext + outcomeCtx + duration
Expand All @@ -387,7 +387,7 @@ object ServerMiddleware {
OptionT.liftF(Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.errored[Option, Throwable, Response[Pure]](e)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val reqContext = request(pureReq, reqHeaders, routeClassifier, requestIncludeUrl, requestAdditionalContext) +
HttpStructuredContext.Common.accessTime(start)
val finalCtx = reqContext + outcomeCtx + duration
Expand Down Expand Up @@ -433,15 +433,15 @@ object ServerMiddleware {
Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.canceled[Option, Throwable, Response[Pure]]
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
}
case Outcome.Errored(e) =>
Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.errored[Option, Throwable, Response[Pure]](e)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
}
Expand All @@ -452,7 +452,7 @@ object ServerMiddleware {
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val responseCtx = response(pureResp, respHeaders, responseAdditionalContext)
val outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](pureResp.some)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext ++ responseCtx + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
}
Expand Down Expand Up @@ -498,7 +498,7 @@ object ServerMiddleware {
Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.canceled[Option, Throwable, Response[Pure]]
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
}
Expand All @@ -509,7 +509,7 @@ object ServerMiddleware {
Clock[F].realTime.flatMap{ end =>
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val outcome = Outcome.errored[Option, Throwable, Response[Pure]](e)
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext+ outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
}
Expand All @@ -520,7 +520,7 @@ object ServerMiddleware {
val duration = HttpStructuredContext.Common.headersDuration(end.minus(start))
val responseCtx = option.map(resp => response(pureResponse(resp), respHeaders, responseAdditionalContext)).getOrElse(Map.empty)
val outcome = Outcome.succeeded[Option, Throwable, Response[Pure]](option.map(pureResponse))
val outcomeCtx = outcomeContext(outcome)
val outcomeCtx = HttpStructuredContext.Common.outcome(outcome)
val finalCtx = reqContext ++ responseCtx + outcomeCtx + duration
logLevelAware(logger, finalCtx, pureReq, outcome, start, removedContextKeys, logLevel, logMessage)
}
Expand Down Expand Up @@ -552,7 +552,7 @@ object ServerMiddleware {
builder += HttpStructuredContext.Common.userAgent(ua)
)

request.contentLength.foreach(l =>
request.contentLength.foreach(l =>
builder += HttpStructuredContext.Common.requestContentLength(l)
)
routeClassifier(request).foreach(s =>
Expand All @@ -564,7 +564,7 @@ object ServerMiddleware {
request.remote.foreach{sa =>
builder +=
HttpStructuredContext.Common.peerIp(sa.host)

builder +=
HttpStructuredContext.Common.peerPort(sa.port)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ private[contextlog] object SharedStructuredLogging {
private[contextlog] def pureRequest[F[_]](req: Request[F]): Request[Pure] = Request(req.method, req.uri, req.httpVersion, req.headers, Stream.empty, req.attributes)
private[contextlog] def pureResponse[F[_]](resp: Response[F]): Response[Pure] = Response(resp.status, resp.httpVersion, resp.headers, Stream.empty, resp.attributes)

private[contextlog] def outcomeContext[F[_], E, A](outcome: Outcome[F, E, A]): (String, String) = {
outcome match {
case Outcome.Canceled() => "exit.case" -> "canceled"
case Outcome.Errored(_) => "exit.case" -> "errored"
case Outcome.Succeeded(_) => "exit.case" -> "succeeded"
}
}


private[contextlog] def logLevelAware[F[_]: Applicative](
logger: StructuredLogger[F],
ctx: Map[String, String],
Expand Down
Loading

0 comments on commit d20c32b

Please sign in to comment.