ID de correlación de EJB3
-
27-10-2019 - |
Pregunta
Ahora mis colegas trabajan en el subsistema de registro y quieren unir operaciones separadas, que se iniciaron a partir de algún método comercial. Por ejemplo, si el método de Bean A llama a algún método en Bean B y luego en Bean C, será genial saber que los métodos comerciales en Bean B y Bean C hacen algún personal para el método de Bean A. Especialmente será genial. Sepa que los métodos de B y C hicieron alguna unidad de trabajo para la llamada de concreto de Bean A.
Entonces, ¿la pregunta es cómo vincular estas unidades de trabajo en algo total? ¡Obviamente, no es hermoso usar argumentos de método para vinculación!
Y también creo que es hora de hacer otra pregunta, que está lo suficientemente cerca de la anterior. ¿Qué pasa si quiero propagar alguna información de contexto de Bean A a otros frijoles, que se llaman desde A? ¿Algo como las credenciales de seguridad y el director de seguridad? ¿Que puedo hacer? ¿Pueden ser preguntas que hice es una especie de mala práctica?
Solución
Parece un buen caso de uso para MDC, disponible en ambos Volver a iniciar sesión y Log4j. Esencialmente, está adjuntando algún valor personalizado a un hilo y todos los mensajes de registro que se encuentran desde ese hilo pueden adjuntar ese valor al mensaje.
Creo que la mejor manera de implementar esto en EJB será un interceptador:
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");
}
}
}
Ahora todo lo que tienes que hacer es agregar:
%X{user}
a su patrón de registro (logback.xml
o log4j.xml
).
Ver también
Otros consejos
Para información de contexto de propósito general, puede usar Transacciones ycronizationregistry. Podría parecer algo así:
@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);
...
}
}
Creo que generalmente se implementa usando Hilo Variables como normalmente cada transacción se asigna a un hilo Sigle en los servidores de aplicaciones. Entonces, si TransactionsyncronizationRegistry no se implementa en su AS (como por ejemplo, en JBoss 4.2.3) o si necesita una herramienta de nivel inferior, puede usar las variables de ThreadLocal directamente.
Por cierto, supongo que los servicios públicos de MDC usan lo mismo debajo de las portadas.