java-如何获得使用Grizzly / Jersey进行记录的客户端地址?

我正在使用Grizzly服务Jersey应用程序,而使用Logback满足我的日志记录需求.请不要在这里不涉及任何Servlet,我使用如下代码“手动”启动所有内容:

final URI uri = /* this is a configuration option */        
this.server = new HttpServer();
final NetworkListener nl = new NetworkListener(
    "grizzly", uri.getHost(), uri.getPort());
server.addListener(nl);

final GuiceComponentProviderFactory gcpf =
    new GuiceComponentProviderFactory(rc, inj);
final HttpHandler processor = ContainerFactory.createContainer(
    HttpHandler.class, rc, gcpf);
this.server.getServerConfiguration().addHttpHandler(
    processor, uri.getPath());
server.start();

现在,我想使用Logback的MDC功能使客户端的套接字地址在日志记录中可见.为此,我需要在某个地方挂起一个侦听HTTP处理的侦听器,该侦听器会收到有关传入请求的通知(可以在其中将地址放入MDC)以及完成请求的时间(以便可以清理MDC).我遵循的一种方法是用Jersey连接一个Container * Filter实例,如下所示:

class MdcFilter implements
        ContainerRequestFilter, ContainerResponseFilter {

    @Override
    public ContainerRequest filter(ContainerRequest request) {
        MDC.put("http-client", "foo" /* no way to get the address here */);
        return request;
    }

    @Override
    public ContainerResponse filter(
            ContainerRequest request,
            ContainerResponse response) {

        MDC.remove("http-client");
        return response;
    }

}

不幸的是,Jersey ContainerRequest不提供有关已连接客户端的信息(这确实令人惊讶).

我怀疑Grizzly本身也应该存在类似的界面,但是我无法将其挖掘出来.

解决方法:

对于Grizzly,相关的API称为HttpServerProbe.使用它,可以归结为以下内容:

final HttpServer server = new org.glassfish.grizzly.http.server.HttpServer();
server.addListener(new NetworkListener("grizzly", "localhost", 8080));
server.getServerConfiguration().addHttpHandler(
    new StaticHttpHandler("/var/www/"), "/");

server.getServerConfiguration().getMonitoringConfig().getWebServerConfig()
  .addProbes(new HttpServerProbe.Adapter() {

    @Override
    public void onRequestReceiveEvent(
        HttpServerFilter filter,
        Connection connection,
        Request request) {

      System.out.println(request.getRemoteAddr());
      MDC.put("http-client", request.getRemoteAddr());
    }

    @Override
    public void onRequestCompleteEvent(
        HttpServerFilter filter,
        Connection connection,
        Response response) {

      MDC.remove("http-client");
    }
}

server.start();

请注意,还有更多可能相关的事件,例如暂停,恢复和取消.这些也应该处理,特别是如果使用长轮询(aka Comet,aka whatnot).但基本上,这是一个值得入迷的地方.

上一篇:hadoop数据压缩及涉及的相关算法和(MapReduce)代码示例演示


下一篇:Hadoop实战之workcount