How can I access client logging addresses using Grizzly / Jersey?

I use Grizzly to apply for a Jersey, using Logback for my registration needs. Please, not that there is no Servlet , I run everything "manually" using a piece of code:

 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 the Logback MDC function to make the client socket address visible in the log entries. To do this, I need a place to connect the listener to HTTP processing, which receives notification of incoming requests (where I can put the address in the MDC) and when the request is completed (so that I can clear the MDC). One of my approaches is to connect an instance of Container*Filter to a Jersey that looks 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, Jersey ContainerRequest does not provide information about the connected client (which cam is like a real surprise).

I suspect that such an interface should exist with the grizzly himself, but I could not dig it out.

+3
source share
2 answers

For Grizzly, the corresponding API is called HttpServerProbe . Using this, it comes down to the following:

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

Please note that there are more events that may be relevant, such as pause, resume, and cancel. Probably, this also needs to be processed, especially if a long survey is used (it is also a comet, aka something that is not so). But basically this is a place where you can catch.

+4
source

In MdcFilter try introducing an HttpServletRequest into your class and use it as usual to call getRemoteAddr() or any other function like 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 it using a similar approach to "shooting from hands", and in this case it worked for me. I guess this will work for you too.

-1
source

All Articles