Jboss logger clear MDC during thread lifecycle - multithreading

I need to improve logging in a JavaEE application running on wildfly using jboss logger & logstash, I'm using MDC to store userID but as I'm new with thread usage I'm not figuring out how to clear the MDC before a thread is recycled
I have found different ways to clear the MDC but I think I am missing some pieces of knowledge regarding threads ... :
I've tried to extend Thread :
public class MdcThread extends Thread {
LoggingTools loggingTools = new LoggingTools(MdcThread.class);
#Override
public void run() {
loggingTools.info("MdcThread");
MDC.clear();
}
}
I've tried to extend ThreadPoolExecutor :
public class MdcThreadPoolExecutor extends ThreadPoolExecutor {
static LoggingTools loggingTools = new LoggingTools(MdcThreadPoolExecutor.class);
...constructors...
#Override
public void execute(Runnable command) {
super.execute(wrap(command));
}
public static Runnable wrap(final Runnable runnable) {
return new Runnable() {
#Override
public void run() {
try {
runnable.run();
} finally {
loggingTools.info("Mdc clear");
MDC.clear();
}
}
};
}
}
But none of these are called ... So I assume ThreadPoolExecutor is a way of using thread but not necessarily used? how can I reach the lifecycle of the threads?
EDIT :
Here is the filter I've used :
#WebFilter("/*")
public class MdcFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (request != null) {
//add what I want in MDC
}
chain.doFilter(request, response);
}
#Override
public void destroy() {
MDC.clear();
}
}

If you're using logback then WildFly or JBoss Log Manager will not be managing MDC. Most implementations of MDC, and I assume you're using org.slf4j.MDC since you're using logback, are thread locals so MDC.clear() will only clear the map on that threads MDC map. Have a look at slf4j's MDC manual.
If you want to clear the message diagnostic context you need to do it in the same thread that adds that adds the data you want cleared.

Related

HazelCast max-idle-seconds :evict listener is not working

hazelcast configuration for the map is
<map name="test">
<max-idle-seconds>120</max-idle-seconds>
<entry-listeners>
<entry-listener include-value="true" local="false">com.test.listener.SessionListener</entry-listener>
</entry-listeners>
</map>
I have a listener configured for the evict action.
Listener is not able to catch the evict action consistently .
Hazelcast Version : 3.6.5
Listener Class Implemetation:
public class SessionListener implements EntryListener<String, Object> {
#Override
public void entryEvicted(EntryEvent<String, Object> evictData) {
try {
Session sessionObjValue = (Session) evictData.getOldValue();
String sessionId = sessionObjValue.getSessionId();
String userName = sessionObjValue.getUsername();
JSONObject inputJSON = new JSONObject();
inputJSON.put(Constants.SESSIONID, sessionId);
inputJSON.put(Constants.USER_NAME, userName);
//Operations to be performed based on the JSON Value
} catch (Exception exception) {
LOGGER.logDebug(Constants.ERROR, methodName, exception.toString());
}
}
Below are the recommendations:
Include Eviction policy configurations in your map config. Right now eviction is happening only based on max-idle-seconds.
Implement all the methods from EntryListener interface which inturn extends other interfaces.
Implement EntryExpiredListener listener also, to catch the expiry events explicitly though evict event also will be called during expiry.
Sample code:
public class MapEntryListernerTest implements EntryListener, EntryExpiredListener {
#Override
public void entryAdded(EntryEvent event) {
}
#Override
public void entryEvicted(EntryEvent event) {
}
#Override
public void entryRemoved(EntryEvent event) {
}
#Override
public void entryUpdated(EntryEvent event) {
}
#Override
public void mapCleared(MapEvent event) {
}
#Override
public void mapEvicted(MapEvent event) {
}
#Override
public void entryExpired(EntryEvent event) {
}
}

How to thread-safely share an attribute between the beforePhase() and the afterPhase() methods of a PhaseListener?

I need to share an attribute between the beforePhase() and the afterPhase() methods of my PhaseListener, for a same JSF request.
Is the following snippet thread-safe?
public class MyPhaseListener implements PhaseListener {
private MyObject o = null;
#Override
public void beforePhase(PhaseEvent event) {
if (condition) {
o = new MyObject();
}
}
#Override
public void afterPhase(PhaseEvent event) {
if (o != null) {
o.process();
o = null;
}
}
#Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
If not, what are other solutions?
This is definitely not threadsafe. There's only one phase listener instance applicationwide which is shared across multiple requests. Basically, a phase listener is like an #ApplicationScoped managed bean.
Just set it as a context attribute.
public class MyPhaseListener implements PhaseListener {
#Override
public void beforePhase(PhaseEvent event) {
if (condition) {
event.getFacesContext().setAttribute("o", new MyObject());
}
}
#Override
public void afterPhase(PhaseEvent event) {
MyObject o = (MyObject) event.getFacesContext().getAttribute("o");
if (o != null) {
o.process();
}
}
#Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
You could use ThreadLocal for this, but it tends to have issues in environments having different classloaders, to name it: memory leak. Be sure to check for that in the given environment...
Also, you should make it sure that if the processing can be interrupted (e.g. exception...) between the beforePhase() and afterPhase() methods, the ThreadLocal should be handled appropriately...
This is what it would look like:
public class MyPhaseListener implements PhaseListener {
//if null is a valid value, no initial setting is needed
private ThreadLocal<Object> myStateObject = new ThreadLocal<Object> ();
#Override
public void beforePhase(PhaseEvent event) {
//might be needed, to guarrantee no residue from an aborted processing is in there
myState.set(null);
if (condition) {
myState.set(<Object representing the state>);
}
}
#Override
public void afterPhase(PhaseEvent event) {
try {
Object stateObject = myState.get();
if (stateObejct!=null) {
//do what you have to
}
} finally {
//to be sure
myState.remove();
}
}
}
In this article the author uses ThreadLocal too...
Also, this article is also a great eye-opener, explaining why not to share mutable instance-level information:
One thing to remember though, is that PhaseListener instances are application-wide Singletons that are referenced by the JSF Lifecycle, which itself is an application-wide Singleton.
EDIT just saw Boolean got updated to Object, adjusted example

Interceptor in JSF

I want to know if there is an interceptor in JSF (like we use in Spring), and how to do we implement it?
You could implement a PhaseListener for this. You could program them to listen on a specific JSF phase which you specify in the overridden getPhaseId() method. You can intercept on the before and after phase events by beforePhase() and afterPhase() methods.
The below example listens on the render response phase:
public class RequestInterceptor implements PhaseListener {
#Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
#Override
public void beforePhase(PhaseEvent event) {
// Do your job here which should run before the render response phase.
}
#Override
public void afterPhase(PhaseEvent event) {
// Do your job here which should run after the render response phase.
}
}
To get it to run, you need to register it as a <phase-listener> in the <life-cycle> section of the faces-config.xml file. You can have multiple <phase-listener>s.
<lifecycle>
<phase-listener>com.example.RequestInterceptor</phase-listener>
</lifecycle>
You can specify PhaseId.ANY_PHASE in getPhaseId() to let the phase listener run on every single JSF phase (note that not necessarily all of them will always be executed, that depends on the request type). You can if necessary get the current phase ID in the before and after phase methods by PhaseEvent#getPhaseId().
public class PhaseDebugger implements PhaseListener {
#Override
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
#Override
public void beforePhase(PhaseEvent event) {
System.out.println("Before phase " + event.getPhaseId());
}
#Override
public void afterPhase(PhaseEvent event) {
System.out.println("After phase " + event.getPhaseId());
}
}
Alternatively, a Filter should work equally good if you want a more global hook (and thus you're not exactly interested in JSF requests/responses and you do not need anything from the FacesContext).
#WebFilter("/*")
public class RequestInterceptor implements Filter {
#Override
public void init(FilterConfig config) {
// Initialize global variables if necessary.
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
// Do your job here which should run before the request processing.
chain.doFilter(request, response);
// Do your job here which should run after the request processing.
}
#Override
public void destroy() {
// Cleanup global variables if necessary.
}
}

How to intercept methods of EntityManager with Seam 3?

I'm trying to intercept the method persist and update of javax.persistence.EntityManager in a Seam 3 project.
In a previous version (Seam 2) of the micro-framework I'm trying to make, I did this using an implementation of org.hibernate.Interceptor and declaring it in the persistence.xml.
But I want something more "CDI-like" now we are in a JEE6 environment.
I want that just before entering in a EntityManager.persist call, an event #BeforeTrackablePersist is thrown. The same way, I want an event #BeforeTrackableUpdate to be thrown before entering in a EntityManager.merge call. Trackable is an interface which some of my Entitys could implement in order to be intercepted before persist or merge.
I'm using Seam 3 (3.1.0.Beta3) Extended Persistence Manager :
public class EntityManagerHandler {
#SuppressWarnings("unused")
#ExtensionManaged
#Produces
#PersistenceUnit
private EntityManagerFactory entityManagerFactory;
}
So I've made a javax.enterprise.inject.spi.Extension, and tryied many ways to do that :
public class TrackableExtension implements Extension {
#Inject #BeforeTrackablePersisted
private Event<Trackable> beforeTrackablePersistedEvent;
#Inject #BeforeTrackableMerged
private Event<Trackable> beforeTrackableMergedEvent;
#SuppressWarnings("unchecked")
public void processEntityManagerTarget(#Observes final ProcessInjectionTarget<EntityManager> event) {
final InjectionTarget<EntityManager> injectionTarget = event.getInjectionTarget();
final InjectionTarget<EntityManager> injectionTargetProxy = (InjectionTarget<EntityManager>) Proxy.newProxyInstance(event.getClass().getClassLoader(), new Class[] {InjectionTarget.class}, new InvocationHandler() {
#Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if ("produce".equals(method.getName())) {
final CreationalContext<EntityManager> ctx = (CreationalContext<EntityManager>) args[0];
final EntityManager entityManager = decorateEntityManager(injectionTarget, ctx);
return entityManager;
} else {
return method.invoke(injectionTarget, args);
}
}
});
event.setInjectionTarget(injectionTargetProxy);
}
public void processEntityManagerType(#Observes final ProcessAnnotatedType<EntityManager> event) {
final AnnotatedType<EntityManager> type = event.getAnnotatedType();
final AnnotatedTypeBuilder<EntityManager> builder = new AnnotatedTypeBuilder<EntityManager>().readFromType(type);
for (final AnnotatedMethod<? super EntityManager> method : type.getMethods()) {
final String name = method.getJavaMember().getName();
if (StringUtils.equals(name, "persist") || StringUtils.equals(name, "merge")) {
builder.addToMethod(method, TrackableInterceptorBindingLiteral.INSTANCE);
}
}
event.setAnnotatedType(builder.create());
}
public void processEntityManagerBean(#Observes final ProcessBean<EntityManager> event) {
final AnnotatedType<EntityManager> annotatedType = (AnnotatedType<EntityManager>)event.getAnnotated();
// not even called
}
public void processEntityManager(#Observes final ProcessProducer<?, EntityManager> processProducer) {
processProducer.setProducer(decorate(processProducer.getProducer()));
}
private Producer<EntityManager> decorate(final Producer<EntityManager> producer) {
return new Producer<EntityManager>() {
#Override
public EntityManager produce(final CreationalContext<EntityManager> ctx) {
return decorateEntityManager(producer, ctx);
}
#Override
public Set<InjectionPoint> getInjectionPoints() {
return producer.getInjectionPoints();
}
#Override
public void dispose(final EntityManager instance) {
producer.dispose(instance);
}
};
}
private EntityManager decorateEntityManager(final Producer<EntityManager> producer, final CreationalContext<EntityManager> ctx) {
final EntityManager entityManager = producer.produce(ctx);
return (EntityManager) Proxy.newProxyInstance(entityManager.getClass().getClassLoader(), new Class[] {EntityManager.class}, new InvocationHandler() {
#Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
final String methodName = method.getName();
if (StringUtils.equals(methodName, "persist")) {
fireEventIfTrackable(beforeTrackablePersistedEvent, args[0]);
} else if (StringUtils.equals(methodName, "merge")) {
fireEventIfTrackable(beforeTrackableMergedEvent, args[0]);
}
return method.invoke(entityManager, args);
}
private void fireEventIfTrackable(final Event<Trackable> event, final Object entity) {
if (entity instanceof Trackable) {
event.fire(Reflections.<Trackable>cast(entity));
}
}
});
}
}
In all those observer methods, only the second one (processEntityManagerType(#Observes ProcessAnnotatedType<EntityManager>)) is called ! And even with that binding addition to methods persist and merge, my Interceptor is never called (I've of course enabled it with the correct lines in beans.xml, and enabled my extension with the services/javax.enterprise.inject.spi.Extension file).
Something I've thought simple with CDI seems to be actually really hard at last... or perhaps Seam 3 does something which prevent this code from executing correctly...
Does someone know how to handle that ?
I think you're making this a little harder than what it needs to be. Firstly though, JPA and CDI integration isn't very good in Java EE 6, we're very much hoping that changes in Java EE 7 and JPA 2.1.
What you'll want to do is create your own producer for the EntityManager that will delegate to an actual instance of an EntityManager, but also fire your own events when you call the methods you're interested in. Take a look at the Seam Persistence source to see one way this can be done.
As finally my little patch for Seam Persistence was applied in SEAMPERSIST-75, it will be possible in theory to do that by extending org.jboss.seam.persistence.HibernatePersistenceProvider and override the method proxyEntityManager(EntityManager).

How to intercept request ends?

Hi in JSF i need to perform some action when each request of the user ends. I need some kind of interceptor but i don't know how to do it. I need help with this please. Thanks
I recommend BalusC's blog: http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
This article shows you how to intercept the JSF lifecycle and debug the information. This will also make it available for you to find out where your request ends.
If you posted some code here it could also help us find out where the true problem lies.
Here is an excerpt of the code that you need to implement to debug the lifecycle:
package mypackage;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class LifeCycleListener implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
public void beforePhase(PhaseEvent event) {
System.out.println("START PHASE " + event.getPhaseId());
}
public void afterPhase(PhaseEvent event) {
System.out.println("END PHASE " + event.getPhaseId());
}
}
If you want to have the FacesContext available, then the best place is the afterPhase of PhaseID.RENDER_RESPONSE inside a PhaseListener. For example:
public class MyPhaseListener implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
public void beforePhase(PhaseEvent event) {
// No operation here.
}
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
// Do your thing here with the FacesContext.
}
}
If you don't need the FacesContext, then the best place is after the line chain.doFilter(request, response) inside a Filter. For example:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
chain.doFilter(request, response);
// Do your thing here.
}

Resources