2017-11-24 2 views
0

Was ich versuche zu tun, ist folgendes: Ändern Sie das Logbuch, um die Benutzer-ID und Request-ID auf den Protokollzeilen zu schreiben. z.B. Wie ermittelt man, ob die Anfrage NICHT die erste Anfrage in einem Filter ist?

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... 

bemerken, dass die requestId die gleiche bleibt, wie sie alle Teil einer Anfrage an das System durch den Endverbraucher vorgenommen wird.

Ich habe einen Filter basierend auf mehreren Beispielen erstellt, in dem gezeigt wird, wie Werte im MDC festgelegt werden. z (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() { 
    } 
} 
... 

Wenn ich eine Anfrage an einen Rest Service machen führt es eine Zeit ohne dass das System andere Wünsche an sich selbst, um Informationen zu machen. Dies ist, was ich erwartet hatte und ich kann die Protokolleinträge sehen, wo sie alle die gleiche requestId enthalten. Wenn ich eine Browser-Seitenanforderung an eine unserer Swagger-Seiten anmelde, macht die Webseite mehrere interne Anfragen nach zusätzlichen Informationen, die auf der Seite erscheinen. Die Protokollierung erfasst ungefähr 20 Anforderungen, die durch das Laden der Webseitenanforderung aufgrund aller zusätzlichen Informationsanforderungen gestellt werden, die von der Seite gerendert werden müssen. Wenn dies der Fall ist, endet die X-Anzahl der Protokolleinträge, wobei jede der internen Anforderungen eine eindeutige Anforderung generiert und requestId für jede von ihnen protokolliert wird. Das war nicht meine Absicht.

WIE bestimmt ich mit einer Anfrage an das System den initiierenden Teil über die internen Anforderungsaufrufe, die erstellt werden?

Ich muss die MDC-Werte für die RequestId nicht immer wieder festlegen. Ich muss es nur einmal pro Anruf einstellen, basierend auf der ersten Anfrage, die vom externen Benutzer gestellt wird.

Nicht einmal sicher, was Sie diese andere als Lebenszyklus einer Anfrage nennen würde, aber ich finde nicht die Antwort.

Alle Hinweise zu schätzen wissen. Vielen Dank.

EDIT: Link zu einer anderen Frage habe ich da draußen, die nur mit der Identifizierung der original user request befasst ist.

+1

Was meinen Sie mit "Sub-Anruf"? Meinst du, dass eine bestimmte Anfrage mehrmals weitergeleitet wird und dass der Filter bei jeder Weiterleitung aufgerufen wird? Wenn dies der Fall ist, können Sie einfach ein Attribut in der Anforderung speichern und vermeiden, zu filtern, wenn das Attribut bereits festgelegt ist. Sie können auch die Dispatcher-Typen Ihres Filters festlegen (https://docs.oracle.com/javaee/7/api/javax/servlet/annotation/WebFilter.html#dispatcherTypes--). Wenn Sie das nicht mit "Sub-Call" meinen, dann erklären Sie es. –

+0

Durch Unteraufrufe, ja das System macht viele andere Anrufe an sich selbst, die den Filter auslösen. Ich überprüfte den Dispatcher-Typ, die alle als REQUEST angezeigt werden. Ich werde in die Einstellung des Attributs schauen und das hört sich so an, als wäre es die einfache Lösung, die ich brauche. – Elijah

+0

Es ist immer noch sehr unklar, was Sie mit "das System" und "Anrufe" meinen. Wenn Sie ein Frontend haben, das viele Anfragen an Ihren Server sendet, dann gibt es keinen "Unteranruf".Dies sind nur Anfragen, unabhängig voneinander. –

Antwort

1

Eine Möglichkeit, dies zu beheben, besteht darin, RequestFilter dem URL-Muster Ihrer Dienste zuzuordnen, die Sie protokollieren möchten, und nicht "/ *".

EDIT: Eine andere Idee wäre, den Filter auf "/ *" zuzuordnen, aber in Ihrer doFilter Methode, MDC keine Anfragen, die "Swagger" in der URL enthalten. Möglicherweise müssen Sie experimentieren und möglicherweise alle URLs einbeziehen, die von der Swagger-Seite generiert werden, da manche das Wort "swagger" nicht enthalten.

@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

Ich habe versucht, dies zu vermeiden, da ich das System und alle Endpunkte oder Seiten, die geladen werden können, nicht kenne, aber es sieht so aus, als müsste ich dies tun, wenn ich nicht generischer sein kann . Danke für die Eingabe. – Elijah

Verwandte Themen