在 Finagle 中记录远程主机
Logging the remote host in Finagle
我想在使用 Finagle Client 时将调用的远程主机记录到 STDOUT。但据我所知,这是不可能通过 com.twitter.finagle.http.filter.LoggingFilter
;它的#format
(示例见下文)方法无法访问实际主机:
request.remoteHost()
returns 0.0.0.0
request.remoteAddress()
returns 基本上包含上述IP的对象
request.host()
returns一个None
对象
我的第一个猜测 is/was 访问主机是不可能的,因为 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"));
请求发送到的实际端点在负载平衡器中决定。所以确实登录远程主机只能在负载均衡模块之后完成。
负载平衡器模块使参数 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")
此创建的服务应记录请求发送到的实际地址。
请参阅 more information on module composition 的官方 Finagle 文档。
我想在使用 Finagle Client 时将调用的远程主机记录到 STDOUT。但据我所知,这是不可能通过 com.twitter.finagle.http.filter.LoggingFilter
;它的#format
(示例见下文)方法无法访问实际主机:
request.remoteHost()
returns0.0.0.0
request.remoteAddress()
returns 基本上包含上述IP的对象request.host()
returns一个None
对象
我的第一个猜测 is/was 访问主机是不可能的,因为 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"));
请求发送到的实际端点在负载平衡器中决定。所以确实登录远程主机只能在负载均衡模块之后完成。
负载平衡器模块使参数 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")
此创建的服务应记录请求发送到的实际地址。
请参阅 more information on module composition 的官方 Finagle 文档。