How can I get my hands on client addresses for logging using Grizzly / Jersey?

家住魔仙堡 提交于 2019-12-07 15:17:07

问题


I'm using Grizzly to serve a Jersey application, while using Logback for my logging needs. Please not that there are no Servlets involved here, I fire up everything "by hand" using a piece of code like this:

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();

Now I would like to use Logback's MDC feature to make the socket address of the clients visible in the log records. For this purpose I would need some place to hook up a listener to the HTTP processing which gets notified about incoming requests (where I can put the address into the MDC) and when a request is done (so I can clean up the MDC). One approach I followed is to hook up a Container*Filter instance with Jersey, which looked like this:

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;
    }

}

Unfortunately, a Jersey ContainerRequest does not provide information about the connected client (which cam as a real surprise).

I suspect a similar interface should exist with Grizzly itself, but I was unable to dig it out.


回答1:


For Grizzly, the relevant API is called HttpServerProbe. Using this, it comes down to something like this:

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();

Note that there are more events which might be relevant, like suspend, resume and cancel. These should probably be handled as well, especially if long-polling (aka Comet, aka whatnot) is used. But basically this is the place to hook into.




回答2:


In your MdcFilter, try to inject the HttpServletRequest into your class and use that as you would normally to call getRemoteAddr() or any other such function as in:

class MdcFilter implements
    ContainerRequestFilter, ContainerResponseFilter {

    @Context
    protected HttpServletRequest r;

    @Override
    public ContainerRequest filter(ContainerRequest request) {
        MDC.put("http-client", "foo" r.getRemoteAddr());
        return request;
    }

    @Override
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
        MDC.remove("http-client");
        return response;
    }
}

I tested this out using a similar approach to "firing things up by hand" and it worked out for me in that case. I assume it would work for you as well.



来源:https://stackoverflow.com/questions/17233960/how-can-i-get-my-hands-on-client-addresses-for-logging-using-grizzly-jersey

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!