В нашем коде мы создаем множество "конвейеров finagle", например, так:
val f1 = new Filter[A,B,C,D](...)
val f2 = new SimpleFilter[C,D](...)
val f3 = new Filter[C,D,E,F](...)
val s = new Service[E,F](...)
val pipeline: Service[A,B] = f1 andThen f2 andThen f3 andThen s
Теперь мне бы хотелось иметь возможность "вставлять" логгеры в любое место в такую цепочку.Регистратор регистрирует только тот факт, что запрос поступил и ответ получен.Примерно так:
class LoggerFilter[Req, Resp](customLog: String) extends SimpleFilter[Req, Resp] with LazyLogging{
override def apply(request: Req, service: Service[Req, Resp]): Future[Resp] = {
logger.info(s"$customLog => Request: ${request.getClass.getName} -> ${service.toString}")
service(request).map{resp =>
logger.info(s"$customLog => Response: ${resp.getClass.getName} -> ${request.getClass.getName}")
resp
}
}
}
При таком подходе мы должны постоянно объявлять несколько регистраторов, чтобы типы могли правильно совмещаться, а затем вставлять в «правильном месте».
val logger1 = new LoggerFilter[A,B]("A->B Logger")
val logger2 = new LoggerFilter[C,D]("C->D Logger")
val logger3 = new LoggerFilter[E,F]("E->F Logger")
val pipeline = logger1 andThen f1 andThen f2 andThen logger2 andThen f3 andThen logger3 andThen s
Есть ли способ, которого можно избежать?Можно ли просто иметь один регистратор, который может автоматически выводить Req/Resp
типы и быть «вставляемым куда угодно» в цепочке?
Например:
val logger = getTypeAgnosticLogger // What's the implementation?
val pipeline = logger andThen f1 andThen f2 andThen logger andThen f3 andThen logger andThen s
// Is this possible - params for logger to print?
val pipeline = logger("f1") andThen f1 andThen f2 andThen logger("f3") andThen f3 andThen logger("s") andThen s