问题描述
我正在使用Grizzly来提供Jersey应用程序,同时使用Logback来满足我的日志记录需求。请注意,此处不涉及 Servlet
,我使用一段代码手动启动所有内容:
I'm using Grizzly to serve a Jersey application, while using Logback for my logging needs. Please not that there are no Servlet
s 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();
现在我想使用Logback的功能,使客户端的套接字地址在日志记录中可见。为此,我需要一些地方来连接一个HTTP处理的监听器,它会收到有关传入请求的通知(我可以将地址放入MDC)以及请求完成时(这样我就可以清理MDC)。我遵循的一种方法是使用Jersey连接 Container * Filter
实例,如下所示:
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;
}
}
不幸的是,泽西岛 ContainerRequest
不提供有关连接客户端的信息(这真是一个惊喜)。
Unfortunately, a Jersey ContainerRequest
does not provide information about the connected client (which cam as a real surprise).
我怀疑应该存在类似的界面与Grizzly本身,但我无法挖出来。
I suspect a similar interface should exist with Grizzly itself, but I was unable to dig it out.
推荐答案
对于Grizzly,相关的API被称为。使用它,它归结为这样:
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();
请注意,还有更多可能相关的事件,例如暂停,恢复和取消。这些应该也可以处理,特别是如果使用长轮询(又名Comet,又名 whatnot )。但基本上这是可以挂钩的地方。
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.
这篇关于如何使用Grizzly / Jersey获取客户端地址以进行日志记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!