3

ロギングのニーズに Logback を使用しながら、Grizzly を使用して Jersey アプリケーションを提供しています。ここには s が含まれていないことに注意してください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機能を使用して、クライアントのソケット アドレスをログ レコードに表示したいと考えています。この目的のために、着信リクエスト (MDC にアドレスを入れることができる場所) とリクエストが完了したとき (MDC をクリーンアップできるようにするため) について通知を受ける HTTP 処理にリスナーを接続する場所が必要です。私が従ったアプローチの 1 つは、次のContainer*Filterように、Jersey でインスタンスを接続することです。

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

}

残念ながら、JerseyContainerRequestは接続されたクライアントに関する情報を提供しません (これには本当に驚きました)。

Grizzly 自体にも同様のインターフェイスが存在するはずですが、掘り出すことができませんでした。

4

2 に答える 2

4

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

中断、再開、キャンセルなど、関連する可能性のあるイベントが他にもあることに注意してください。特にロングポーリング (別名 Comet、別名whatnot ) が使用されている場合は特に、これらも同様に処理する必要があります。しかし、基本的にこれはフックする場所です。

于 2013-06-24T15:56:18.913 に答える