I am trying to add a unique request id to logs for each request that is made to a rest api. For that I want to pass implicitly a MarkerContext to each logger method called. Currently the NoMarker context is provided by default. Can I turn this off so that I get a compilation error when trying to log without providing an implicit MarkerContext to the method.
My current approach is:
Define a MarkerContextWrapper:
class MarkerContextWrapper(markerContext: MarkerContext) {
def getMarkerContext: MarkerContext = markerContext
}
Define MarkerLogger:
class MarkerLogger(clazz: Class[_]){
private val logger = Logger(clazz)
def debug(message: => String)(implicit markerContextWrapper: MarkerContextWrapper): Unit = {
logger.debug(message)(markerContextWrapper.getMarkerContext)
}
def debug(message: => String, error: => Throwable)(implicit markerContextWrapper: MarkerContextWrapper): Unit = {
logger.debug(message, error)(markerContextWrapper.getMarkerContext)
}
....
....
}
In the each method use the MarkerLogger instead of the play.api.Logger
private val logger = Logger(this.getClass)
private val logger = MarkerLogger(this.getClass)
Add (implicit markerContextWrapper: MarkerContextWrapper) to every method that logs something.
Instantiate a new MarkerContext wrapper inside my Custom Controller actions:
case class DeviceRequest[A](
device: Device,
request: Request[A],
markerContextWrapper: MarkerContextWrapper
) extends WrappedRequest[A](request)
object DeviceAction extends ActionBuilder[DeviceRequest, AnyContent] {
private val logger = MarkerLogger(this.getClass)
override def executionContext = ec
override def parser = p
override def invokeBlock[A](request: Request[A], block: (DeviceRequest[A]) => Future[Result]) = {
implicit val markerContextWrapper = requestHeaderToMarkerContextWrapper(request)
....
....
block(DeviceRequest(device, request, markerContextWrapper))
}
This approach doesn’t stop anyone form still using the Logger and not the wrapper in which case the default NoMarker might be passed. Is there a way to disable this and make the developer have to provide the MarkerContext every time a Logger method is used?
Or is there a completely different approach to provide a unique request id accross multiple threads, without so much refactoring?