2017-11-24 5 views
0

私がしようとしていることは、次のとおりです。 ログの行にユーザーIDと要求IDを書き出すようにログバックを変更します。例: リクエストがフィルタの最初のリクエストではないかどうかを判断するにはどうすればよいですか?

2017-11-24 [userid:abcd123 - requestId:12345679] [ClassA:MethodA1] message... 
2017-11-24 [userid:abcd123 - requestId:12345679] [ClassA:MethodA2] message... 
2017-11-24 [userid:abcd123 - requestId:12345679] [ClassB:MethodB1] message... 

requestIdは、エンドユーザーがシステムに対して行った1つの要求のすべての部分と同じままです。

MDCに値を設定する方法を示すいくつかの例に基づいてフィルタを作成しました。例えば(https://logback.qos.ch/manual/mdc.html1

... 
@Component 
public class RequestFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     try { 
      String mdcData = String.format("[userId:%s | requestId:%s] ", user(), requestId()); 
      MDC.put("mdcData", mdcData); //Referenced from logging configuration. 
      chain.doFilter(request, response); 
     } finally { 
      MDC.clear(); 
     } 
    } 

    private String requestId() { 
     return UUID.randomUUID().toString(); 
    } 

    private String user() { 
     return "tux"; 
    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    } 

    @Override 
    public void destroy() { 
    } 
} 
... 

私はそれが情報のために自身への追加要求を行うシステムなしで1時間を実行し、残りのサービスへの要求を行う場合。これは私が期待していたものであり、すべてが同じrequestIdを含むログエントリを見ることができます。 私がSwaggerページの1つにブラウザのページリクエストを行うと、Webページはそのページに表示される追加の情報を複数回内部リクエストします。ロギングは、ページがレンダリングする必要がある情報に対する追加の要求のすべてが原因で、Webページ要求のロードによって行われた約20の要求を取得します。これが起こると、内部リクエストのそれぞれが一意のリクエストを生成し、それぞれに対してrequestIdが記録されるX個のログエントリが生成されます。これは私の意図ではありませんでした。

どのようにして、作成された内部要求呼び出しに対して開始部分がシステムに要求されるかを判断しますか?

私は、requestIdのMDC値を何度も設定する必要はありません。私は、外部ユーザーからの最初の要求に基づいてコールごとに1回だけ設定する必要があります。

リクエストのライフサイクル以外に何を呼び出すのか分からないが、私は答えを見つけていない。

ガイダンスを参考にしてください。ありがとう。

EDIT:original user requestを特定することしか扱っていない別の質問にリンクします。

+1

「サブコール」とはどういう意味ですか?特定のリクエストが何度も転送されていることを意味します。また、フィルタはすべての転送で呼び出されますか?その場合は、リクエストに属性を格納して、属性がすでに設定されている場合はフィルタリングしないでください。フィルタのディスパッチャタイプ(https://docs.oracle.com/javaee/7/api/javax/servlet/annotation/WebFilter.html#dispatcherTypes--)を設定することもできます。それがあなたが "サブコール"を意味するものでないならば、説明してください。 –

+0

サブコールでは、システムはフィルタをトリガしている他の多くの呼び出しを自身に対して行っています。私はすべてがREQUESTとして表示されるディスパッチャのタイプをチェックしました。アトリビュートの設定を調べて、それが必要な簡単な修正であるように思えます。 – Elijah

+0

"システム"と "コール"が意味することはまだまだ不明です。フロントエンドがあなたのサーバに多くのリクエストを送信している場合、「サブコール」はありません。これらはお互いから独立した要求なのです。 –

答えて

1

これに対処する方法の1つは、RequestFilterを、「/ *」ではなくログに記録するサービスのURLパターンにマップすることです。

EDIT:フィルタを「/ *」にマッピングすることもできますが、doFilterメソッドでは、URLに「swagger」が含まれているリクエストをMDCで実行しないでください。実験をして、Swaggerページから生成されるすべてのURLを含めることが必要な場合があります。その中には、「swagger」という単語が含まれていないものがあります。

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 

    if (isRequestSwaggerUrl(request)) { 
     chain.doFilter(request, response); 
     return; 
    } 

    try { 
     String mdcData = String.format("[userId:%s | requestId:%s] ", user(), requestId()); 
     MDC.put("mdcData", mdcData); //Referenced from logging configuration. 
     chain.doFilter(request, response); 
    } finally { 
     MDC.clear(); 
    } 
} 
+0

システムを知りませんし、エンドポイントやページを読み込むことができないので、私はそれをやめようとしていましたが、もっと一般的にすることができない場合、これをしなければならないようです。入力いただきありがとうございます。 – Elijah

関連する問題