Frage

Jetzt arbeiten meine Kollegen am Protokollierungssubsystem und möchten separate Vorgänge binden, die von einer Geschäftsmethode initiiert wurden.Wenn beispielsweise eine Methode von Bean A eine Methode in Bean B und dann in Bean C aufruft, ist es gut zu wissen, welche Geschäftsmethoden in Bean B vorhanden sind und Bean C einige Mitarbeiter für die Methode von Bean A übernimmt.Insbesondere wird es großartig sein zu wissen, dass die Methoden von B und C einige Arbeitseinheiten für den konkreten Aufruf von Bean A geleistet haben.

Die Frage ist also, wie man diese Arbeitseinheiten zu etwas Gesamtem zusammenfügt.Offensichtlich ist es nicht schön, Methodenargumente zum Binden zu verwenden!

Und ich denke auch, dass es an der Zeit ist, eine weitere Frage zu stellen, die der vorherigen nahe genug kommt.Was passiert, wenn ich einige Kontextinformationen von Bean A an andere Beans weitergeben möchte, die von A aufgerufen werden?Etwas wie Sicherheitsanmeldeinformationen und Sicherheitsprinzipal?Was kann ich machen?Vielleicht sind die Fragen, die ich gestellt habe, eine Art schlechte Praxis?

War es hilfreich?

Lösung

Sieht nach einem guten Gebrauchsfall für aus , erhältlich in beiden Wieder anmelden und Log4j. Im Wesentlichen fügen Sie einen benutzerdefinierten Wert an einen Thread hinzu, und alle aus diesem Thread entnommenen Protokollierungsnachrichten können diesen Wert an die Nachricht anhängen.

Ich denke, der beste Weg, dies in EJB umzusetzen Interceptor:

public class MdcInterceptor {

    @AroundInvoke
    public Object addMdcValue(InvocationContext context) throws Exception {
        MDC.put("cid", RandomStringUtils.randomAlphanumeric(16));
        try {
            return context.proceed();
        } finaly {
            MDC.remove("cid");
        }
    }
}

Jetzt müssen Sie nur noch hinzufügen:

%X{user}

zu Ihrem Protokollierungsmuster (logback.xml oder log4j.xml).

Siehe auch

Andere Tipps

Für allgemeine Kontextinformationen, die Sie verwenden können TransactionSynchronizationRegistry.Es könnte etwa so aussehen:

@Stateless
public class MyBean {

    @Resource
    TransactionSynchronizationRegistry registry;

    @AroundInvoke
    public Object setEntryName(InvocationContext ic) throws Exception {
        registry.putResource(NAME, "MyBean");
        return ic.proceed();
    }
}

@Stateless
public class MyBean2 {

    @Resource
    TransactionSynchronizationRegistry registry;

    public void doJob() {
        String entryName = (String)registry.getResource(NAME);
        ...
    }
}

Ich glaube, dass es normalerweise mit implementiert wird ThreadLocal Variablen, da normalerweise jede Transaktion einem einzelnen Thread in Anwendungsservern zugeordnet ist.Wenn also TransactionSynchronizationRegistry nicht in Ihrem AS implementiert ist (wie z. B.in JBoss 4.2.3) oder Sie ein Tool auf niedrigerer Ebene benötigen, können Sie ThreadLocal-Variablen direkt verwenden.

Übrigens vermute ich, dass MDC-Versorgungsunternehmen unter der Decke dasselbe verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top