2017-08-11 42 views
1

我想在使用Finagle客戶端時將被叫遠程主機記錄到STDOUT。但據我所知,這是不可能通過com.twitter.finagle.http.filter.LoggingFilter;其#format(例如見下文)方法無法訪問實際的主機:在Finagle中記錄遠程主機

  • request.remoteHost()返回0.0.0.0
  • request.remoteAddress()返回其基本上含有上述IP
  • request.host()返回None對象

對象我的第一個猜測是,訪問主機是不可能的,因爲Finagle的客戶端負載平衡發生在堆棧

這是測試代碼我使用:

LoggingFilter<Request> loggingFilter = new LoggingFilter<>(
      new Logger(this.getClass().getSimpleName(), java.util.logging.Logger.getLogger(this.getClass().getSimpleName())), 

      new LogFormatter<Request, Response>() { 
       @Override 
       public String format(Request request, Response reply, Duration replyTime) { 
        return null; 
       } 

       @Override 
       public String formatException(Request request, Throwable throwable, Duration replyTime) { 
        return null; 
       } 
      }); 

    Service<Request, Response> service = Http.client().newService("localhost:8090,localhost:8091"); 
    Future<Response> response = loggingFilter.andThen(service).apply(Request.apply("/profiles/me")); 

回答

3

到該請求被髮送的實際終點在負載平衡器被確定。所以實際上只能在負載平衡模塊之後才能完成遠程主機的日誌記錄。

負載平衡器模塊使參數Transporter.EndpointAddr可用。該參數包含實際地址。爲了使用這個參數,你應該在負載均衡模塊後面添加一個模塊到HTTP客戶端堆棧。

Scala中的一個例子:

創建日誌過濾器:

class MyLoggingFilter(addr: Address) extends SimpleFilter[Request, Response] { 
    override def apply(request: Request, service: Service[Request, Response]) = { 
    println(s"Sending request to $addr") 
    service(request) 
    } 
} 

定義新的模塊

def endpointLoggerModule: Stackable[ServiceFactory[Request, Response]] = 
    new Stack.Module1[Transporter.EndpointAddr, ServiceFactory[Request, Response]] { 
    val role: Role = Role("EndpointLogger") 
    val description = "Log remote address" 
    def make(_addr: Transporter.EndpointAddr, 
      next: ServiceFactory[Request, Response]) = { 
     val Transporter.EndpointAddr(addr) = _addr 
     new MyLoggingFilter(addr).andThen(next) 
    } 
    } 

創建該模塊在堆棧中一個新的HTTP客戶端:

val stackWithLogging = Http.client.stack 
    .insertAfter(LoadBalancerFactory.role, endpointLoggerModule) 
val service = Http.client.copy(stack = stackWithLogging) 
    .newService("localhost:8090,localhost:8091") 

該創建的服務應該記錄發送請求的實際地址。

有關模塊組成的更多信息,請訪問:https://twitter.github.io/finagle/guide/Clients.html?highlight=module#module-composition