Last active
January 1, 2018 18:41
-
-
Save elbosso/822c573d8670601dd630fa869f591cb0 to your computer and use it in GitHub Desktop.
This is a Log4J 1.x Appender that sends every log message out over JMX - the actual log event is transformed into an ComplexType structure so that the JMX client can use its individual fields for fancy stuff - for example for filtering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.elbosso.util; | |
//This is by no means production-ready code! | |
/*Copyright (c) 2012-2018. | |
Juergen Key. Alle Rechte vorbehalten. | |
Weiterverbreitung und Verwendung in nichtkompilierter oder kompilierter Form, | |
mit oder ohne Veraenderung, sind unter den folgenden Bedingungen zulaessig: | |
1. Weiterverbreitete nichtkompilierte Exemplare muessen das obige Copyright, | |
die Liste der Bedingungen und den folgenden Haftungsausschluss im Quelltext | |
enthalten. | |
2. Weiterverbreitete kompilierte Exemplare muessen das obige Copyright, | |
die Liste der Bedingungen und den folgenden Haftungsausschluss in der | |
Dokumentation und/oder anderen Materialien, die mit dem Exemplar verbreitet | |
werden, enthalten. | |
3. Weder der Name des Autors noch die Namen der Beitragsleistenden | |
duerfen zum Kennzeichnen oder Bewerben von Produkten, die von dieser Software | |
abgeleitet wurden, ohne spezielle vorherige schriftliche Genehmigung verwendet | |
werden. | |
DIESE SOFTWARE WIRD VOM AUTOR UND DEN BEITRAGSLEISTENDEN OHNE | |
JEGLICHE SPEZIELLE ODER IMPLIZIERTE GARANTIEN ZUR VERFUEGUNG GESTELLT, DIE | |
UNTER ANDEREM EINSCHLIESSEN: DIE IMPLIZIERTE GARANTIE DER VERWENDBARKEIT DER | |
SOFTWARE FUER EINEN BESTIMMTEN ZWECK. AUF KEINEN FALL IST DER AUTOR | |
ODER DIE BEITRAGSLEISTENDEN FUER IRGENDWELCHE DIREKTEN, INDIREKTEN, | |
ZUFAELLIGEN, SPEZIELLEN, BEISPIELHAFTEN ODER FOLGENDEN SCHAEDEN (UNTER ANDEREM | |
VERSCHAFFEN VON ERSATZGUETERN ODER -DIENSTLEISTUNGEN; EINSCHRAENKUNG DER | |
NUTZUNGSFAEHIGKEIT; VERLUST VON NUTZUNGSFAEHIGKEIT; DATEN; PROFIT ODER | |
GESCHAEFTSUNTERBRECHUNG), WIE AUCH IMMER VERURSACHT UND UNTER WELCHER | |
VERPFLICHTUNG AUCH IMMER, OB IN VERTRAG, STRIKTER VERPFLICHTUNG ODER | |
UNERLAUBTE HANDLUNG (INKLUSIVE FAHRLAESSIGKEIT) VERANTWORTLICH, AUF WELCHEM | |
WEG SIE AUCH IMMER DURCH DIE BENUTZUNG DIESER SOFTWARE ENTSTANDEN SIND, SOGAR, | |
WENN SIE AUF DIE MOEGLICHKEIT EINES SOLCHEN SCHADENS HINGEWIESEN WORDEN SIND. | |
*/ | |
import org.apache.log4j.AppenderSkeleton; | |
import org.apache.log4j.Level; | |
import org.apache.log4j.spi.LoggingEvent; | |
import javax.management.*; | |
import javax.management.openmbean.ArrayType; | |
import javax.management.openmbean.OpenDataException; | |
import javax.management.openmbean.SimpleType; | |
import javax.swing.text.BadLocationException; | |
/** | |
* | |
* @author elbosso | |
*/ | |
public class JMXAppender extends AppenderSkeleton implements javax.management.NotificationBroadcaster, | |
JMXAppenderMBean | |
/* This interface actually only needs to exist and can be empty - for example: | |
public interface JMXAppenderMBean | |
{ | |
} | |
*/ | |
{ | |
private static final java.lang.String[] ITEMNAMES=new java.lang.String[]{"level", | |
"timeStamp", | |
"fqnOfCategoryClass", | |
"loggerName", | |
"ndc", | |
"threadName", | |
"throwableStrRep", | |
"message"}; | |
private static final java.lang.String[] ITEMDESCRIPTIONS=new java.lang.String[]{"level - may be TRACE, DEBUG, INFO, WARN, ERROR, FATAL", | |
"timeStamp - the timestamp of the logging event", | |
"fqnOfCategoryClass", | |
"loggerName - the nema of the logger", | |
"ndc", | |
"threadName - name of the thread the logging was done from", | |
"throwableStrRep - array of strings that represent a stacktrace to the location of the log event", | |
"message - the actual layouted message formatted by the given layout"}; | |
private static javax.management.openmbean.OpenType[] ITEMTYPES; | |
private static javax.management.openmbean.CompositeType TYPE; | |
static | |
{ | |
try | |
{ | |
ITEMTYPES=new javax.management.openmbean.OpenType[]{SimpleType.STRING, | |
SimpleType.LONG, | |
SimpleType.STRING, | |
SimpleType.STRING, | |
SimpleType.STRING, | |
SimpleType.STRING, | |
new ArrayType(1,SimpleType.STRING), | |
SimpleType.STRING}; | |
TYPE = new javax.management.openmbean.CompositeType("Log event data type", | |
"data type to mirror a log4j log event", | |
ITEMNAMES, | |
ITEMDESCRIPTIONS, | |
ITEMTYPES); | |
} | |
catch(java.lang.Throwable t) | |
{ | |
t.printStackTrace(); | |
} | |
} | |
private javax.management.NotificationBroadcasterSupport notificationBroadcasterSupport; | |
private long notificationSequence = 0; | |
private boolean initialized; | |
public JMXAppender() | |
{ | |
super(); | |
notificationBroadcasterSupport=new javax.management.NotificationBroadcasterSupport(); | |
} | |
private void checkInitialization() | |
{ | |
if(initialized==false) | |
{ | |
try | |
{ | |
javax.management.MBeanServer mbs = java.lang.management.ManagementFactory.getPlatformMBeanServer(); | |
javax.management.ObjectName name = new javax.management.ObjectName("jmxlogger:type=LogEmitter"); | |
mbs.registerMBean(this, name); | |
initialized = true; | |
} | |
catch(java.lang.Exception t) | |
{ | |
t.printStackTrace(); | |
getErrorHandler().error(t.getMessage(),t, Level.FATAL_INT); | |
} | |
} | |
} | |
@Override | |
public boolean requiresLayout() | |
{ | |
return true; | |
} | |
@Override | |
public void close() | |
{ | |
} | |
@Override | |
protected void append(LoggingEvent le) | |
{ | |
checkInitialization(); | |
java.lang.String msg=getLayout().format(le); | |
Notification notif=new Notification( | |
"Log."+le.getLevel().toString(), // type | |
this, // source | |
++notificationSequence, // seq. number | |
msg | |
); | |
// notif.setUserData(le); | |
Object[] itemValues = new Object[]{le.getLevel().toString(), | |
le.timeStamp, | |
le.fqnOfCategoryClass, | |
le.getLoggerName(), | |
le.getNDC(), | |
le.getThreadName(), | |
le.getThrowableStrRep(), | |
msg}; | |
try | |
{ | |
javax.management.openmbean.CompositeDataSupport support = new javax.management.openmbean.CompositeDataSupport(TYPE,ITEMNAMES,itemValues); | |
notif.setUserData(support); | |
} catch (OpenDataException e) | |
{ | |
getErrorHandler().error(e.getMessage(),e,Level.FATAL_INT); | |
} | |
notificationBroadcasterSupport.sendNotification(notif); | |
} | |
@Override | |
public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException | |
{ | |
notificationBroadcasterSupport.addNotificationListener(listener,filter,handback); | |
} | |
@Override | |
public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException | |
{ | |
notificationBroadcasterSupport.removeNotificationListener(listener); | |
} | |
@Override | |
public MBeanNotificationInfo[] getNotificationInfo() | |
{ | |
return new MBeanNotificationInfo[]{ | |
new MBeanNotificationInfo( | |
new String[] | |
{"Log.TRACE","Log.DEBUG","Log.INFO","Log.WARN","Log.ERROR","Log.FATAL"}, // notif. types | |
Notification.class.getName(), // notif. class | |
"Log4j Log Appender" // description | |
) | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment