Log4j2 logging context for things. This should help add context when things go wrong in mods.

This commit is contained in:
Christian 2014-01-20 21:58:39 -05:00
parent 60abcb6341
commit 5898d2a1f8
4 changed files with 41 additions and 19 deletions

View file

@ -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", "<NONE>");
activeContainer = null;
if (stateEvent instanceof FMLStateEvent)
{

View file

@ -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<Method, Class<?>> 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", "<NONE>");
}
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);

View file

@ -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<Object, ArrayList<IEventListener>> listeners = new ConcurrentHashMap<Object, ArrayList<IEventListener>>();
private Map<Object,ModContainer> 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<? extends Class<?>> 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<IEventListener> others = listeners.get(target);

View file

@ -21,7 +21,7 @@
<Routes pattern="$${ctx:side}">
<Route>
<RollingRandomAccessFile name="FmlFile" fileName="logs/fml-${ctx:side}-latest.log" filePattern="logs/fml-${ctx:side}-%i.log">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n" />
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger/%X{mod}]: %msg%n" />
<DefaultRolloverStrategy max="3" fileIndex="max" />
<Policies>
<OnStartupTriggeringPolicy />