From 8692ca17d13eda036b5ef996ec8e8706e7707d80 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 20 Jan 2014 21:58:39 -0500 Subject: [PATCH] Log4j2 logging context for things. This should help add context when things go wrong in mods. --- .../cpw/mods/fml/common/LoadController.java | 3 ++ .../common/eventhandler/ASMEventHandler.java | 41 ++++++++++++------- .../fml/common/eventhandler/EventBus.java | 14 +++++-- src/main/resources/log4j2.xml | 2 +- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/main/java/cpw/mods/fml/common/LoadController.java b/src/main/java/cpw/mods/fml/common/LoadController.java index 3fdf5d9553..e7807525cc 100644 --- a/src/main/java/cpw/mods/fml/common/LoadController.java +++ b/src/main/java/cpw/mods/fml/common/LoadController.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map.Entry; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.ThreadContext; import com.google.common.base.Joiner; import com.google.common.collect.ArrayListMultimap; @@ -201,9 +202,11 @@ public class LoadController } activeContainer = mc; stateEvent.applyModContainer(activeContainer()); + ThreadContext.put("mod", modId); FMLLog.log(modId, Level.TRACE, "Sending event %s to mod %s", stateEvent.getEventType(), modId); eventChannels.get(modId).post(stateEvent); FMLLog.log(modId, Level.TRACE, "Sent event %s to mod %s", stateEvent.getEventType(), modId); + ThreadContext.put("mod", ""); activeContainer = null; if (stateEvent instanceof FMLStateEvent) { diff --git a/src/main/java/cpw/mods/fml/common/eventhandler/ASMEventHandler.java b/src/main/java/cpw/mods/fml/common/eventhandler/ASMEventHandler.java index 02bb037268..4c59a05c2d 100644 --- a/src/main/java/cpw/mods/fml/common/eventhandler/ASMEventHandler.java +++ b/src/main/java/cpw/mods/fml/common/eventhandler/ASMEventHandler.java @@ -6,25 +6,29 @@ import java.lang.reflect.Method; import java.util.HashMap; +import org.apache.logging.log4j.ThreadContext; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; import com.google.common.collect.Maps; +import cpw.mods.fml.common.ModContainer; public class ASMEventHandler implements IEventListener { private static int IDs = 0; private static final String HANDLER_DESC = Type.getInternalName(IEventListener.class); - private static final String HANDLER_FUNC_DESC = Type.getMethodDescriptor(IEventListener.class.getDeclaredMethods()[0]); + private static final String HANDLER_FUNC_DESC = Type.getMethodDescriptor(IEventListener.class.getDeclaredMethods()[0]); private static final ASMClassLoader LOADER = new ASMClassLoader(); private static final HashMap> cache = Maps.newHashMap(); - + private final IEventListener handler; private final SubscribeEvent subInfo; - public ASMEventHandler(Object target, Method method) throws Exception + private ModContainer owner; + public ASMEventHandler(Object target, Method method, ModContainer owner) throws Exception { + this.owner = owner; handler = (IEventListener)createWrapper(method).getConstructor(Object.class).newInstance(target); subInfo = method.getAnnotation(SubscribeEvent.class); } @@ -32,6 +36,14 @@ public class ASMEventHandler implements IEventListener @Override public void invoke(Event event) { + if (owner != null) + { + ThreadContext.put("mod", owner.getName()); + } + else + { + ThreadContext.put("mod", ""); + } if (handler != null) { if (!event.isCancelable() || !event.isCanceled() || subInfo.receiveCanceled()) @@ -39,13 +51,14 @@ public class ASMEventHandler implements IEventListener handler.invoke(event); } } + ThreadContext.remove("mod"); } - + public EventPriority getPriority() { return subInfo.priority(); } - + public Class createWrapper(Method callback) { if (cache.containsKey(callback)) @@ -55,12 +68,12 @@ public class ASMEventHandler implements IEventListener ClassWriter cw = new ClassWriter(0); MethodVisitor mv; - + String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); String eventType = Type.getInternalName(callback.getParameterTypes()[0]); - + /* System.out.println("Name: " + name); System.out.println("Desc: " + desc); @@ -68,7 +81,7 @@ public class ASMEventHandler implements IEventListener System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback)); System.out.println("Event: " + eventType); */ - + cw.visit(V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[]{ HANDLER_DESC }); cw.visitSource(".dynamic", null); @@ -105,22 +118,22 @@ public class ASMEventHandler implements IEventListener cache.put(callback, ret); return ret; } - + private String getUniqueName(Method callback) { - return String.format("%s_%d_%s_%s_%s", getClass().getName(), IDs++, - callback.getDeclaringClass().getSimpleName(), - callback.getName(), + return String.format("%s_%d_%s_%s_%s", getClass().getName(), IDs++, + callback.getDeclaringClass().getSimpleName(), + callback.getName(), callback.getParameterTypes()[0].getSimpleName()); } - + private static class ASMClassLoader extends ClassLoader { private ASMClassLoader() { super(ASMClassLoader.class.getClassLoader()); } - + public Class define(String name, byte[] data) { return defineClass(name, data, 0, data.length); diff --git a/src/main/java/cpw/mods/fml/common/eventhandler/EventBus.java b/src/main/java/cpw/mods/fml/common/eventhandler/EventBus.java index aa6640d585..3dfe411222 100644 --- a/src/main/java/cpw/mods/fml/common/eventhandler/EventBus.java +++ b/src/main/java/cpw/mods/fml/common/eventhandler/EventBus.java @@ -3,18 +3,23 @@ package cpw.mods.fml.common.eventhandler; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import com.google.common.collect.MapMaker; import com.google.common.reflect.TypeToken; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; public class EventBus { private static int maxID = 0; private ConcurrentHashMap> listeners = new ConcurrentHashMap>(); + private Map listenerOwners = new MapMaker().weakKeys().weakValues().makeMap(); private final int busID = maxID++; public EventBus() @@ -29,6 +34,7 @@ public class EventBus return; } + listenerOwners.put(target, Loader.instance().activeModContainer()); Set> supers = TypeToken.of(target.getClass()).getTypes().rawTypes(); for (Method method : target.getClass().getMethods()) { @@ -52,10 +58,10 @@ public class EventBus if (!Event.class.isAssignableFrom(eventType)) { - throw new IllegalArgumentException("Method " + method + " has @SubscribeEvent annotation, but takes a argument that is not a Event " + eventType); + throw new IllegalArgumentException("Method " + method + " has @SubscribeEvent annotation, but takes a argument that is not an Event " + eventType); } - register(eventType, target, method); + register(eventType, target, method, Loader.instance().activeModContainer()); break; } } @@ -67,14 +73,14 @@ public class EventBus } } - private void register(Class eventType, Object target, Method method) + private void register(Class eventType, Object target, Method method, ModContainer owner) { try { Constructor ctr = eventType.getConstructor(); ctr.setAccessible(true); Event event = (Event)ctr.newInstance(); - ASMEventHandler listener = new ASMEventHandler(target, method); + ASMEventHandler listener = new ASMEventHandler(target, method, owner); event.getListenerList().register(busID, listener.getPriority(), listener); ArrayList others = listeners.get(target); diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 18eab39a0f..3f9cb3b88a 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -21,7 +21,7 @@ - +