Skip to content

Instantly share code, notes, and snippets.

@soujiro32167
Created March 22, 2021 17:34
Show Gist options
  • Save soujiro32167/7dd43d11484b56d65555e3f2ddf8d392 to your computer and use it in GitHub Desktop.
Save soujiro32167/7dd43d11484b56d65555e3f2ddf8d392 to your computer and use it in GitHub Desktop.
Conditional logging in http4s
package com.byond.infinity.sda
import cats.data.{ Kleisli, OptionT }
import cats.effect.{ Resource, Sync }
import org.http4s.{ HttpRoutes, Response }
import cats.syntax.flatMap._
import org.http4s.client.Client
object logging {
val log = org.log4s.getLogger
def logOnError[F[_]]: Response[F] => Boolean = res => !res.status.isSuccess && res.status.code != 404
def conditionalServerResponseLogger[F[_]](logHeaders: Boolean, logBodyWhen: Response[F] => Boolean = logOnError[F])(
http: HttpRoutes[F]
)(implicit F: Sync[F]): HttpRoutes[F] = {
val logAction: String => F[Unit] = s => F.delay(log.info(s))
Kleisli { req =>
http(req).flatTap { res =>
val logBody = logBodyWhen(res)
OptionT.liftF(
org.http4s.internal.Logger
.logMessage[F, Response[F]](res)(logHeaders, logBody)(logAction)
)
}
}
}
def conditionalClientResponseLogger[F[_]](logHeaders: Boolean, logBodyWhen: Response[F] => Boolean = logOnError[F])(
client: Client[F]
)(implicit F: Sync[F]): Client[F] = {
val logAction: String => F[Unit] = s => F.delay(log.info(s))
Client { req =>
client.run(req).flatTap { res =>
val logBody = logBodyWhen(res)
Resource.liftF(
org.http4s.internal.Logger
.logMessage[F, Response[F]](res)(logHeaders, logBody)(logAction)
)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment