giovedì 1 ottobre 2009

Log4J e il JMSAppender

In questi giorni sono alle prese con Log4J. Veniamo subito al punto.

Ho la necessità di salvare dei messaggi di testo in una coda JMS in base a determinate circostanze critiche, tipicamente delle eccezioni, che rappresentano problemi significativi per il mio middleware. Il broker JMS è Apache ActiveMQ e gira all'interno del mio application server tramite file RAR (Resource Adapter). Il contesto di esecuzione una WebApplication.

Bene, per far funzionare correttamente il JMSAppender serve prima configurarlo all'interno del log4j.properties:

log4j.appender.jms=org.apache.log4j.net.JMSAppender
log4j.appender.jms.InitialContextFactoryName=org.apache.activemq.jndi.ActiveMQInitialContextFactory
log4j.appender.jms.ProviderURL=tcp://localhost:61616
log4j.appender.jms.TopicBindingName=sampleTopic
log4j.appender.jms.TopicConnectionFactoryBindingName=TCF

log4j.logger.it.lucia.test.logging.JMSLogger=fatal,jms

Ok, perfetto. Diciamo che se avete questa esigenza particolare, posso immaginare che siate abbastanza confidenti con il log4j.properties e non starò quindi a spiegarvi il senso della configurazione.
Unico appunto, con l'ultima riga, imposto il logger "jms" a livello predefinito "fatal" per la mia classe it.lucia.test.logging.JMSLogger. Questo significa che quando andremo ad utilizzare il metodo "log.fatal" all'interno di quella particolare classe, non andremo a scrivere sul solito file di log bensì scateneremo un operazione di accodamento utilizzando in maniera trasparente le API JMS.


Naturalmente non basta solo questo.
ActiveMQ richiede che gli oggetti definiti in precedenza nel log4j.properties, siano definiti anche all'interno del file jndi.properties, sebbene gli stessi oggetti sono già esposti su jndi e raggiungibili dalla web application usando un normale oggetto InitialContext.
Di norma, andremo a definire le risorse jndi all'interno del nostro application server ma per semplicità diciamo che possiamo anche sorvolare e utilizzare un semplice file di proprietà.

Andiamo quindi a definire la ConnectionFactory e il Topic sul quale volete loggare i messaggi.  Ecco cosa vi serve inserire all'interno del file jndi.properties:


java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url = vm://localhost
connectionFactoryNames = TCF
topic.sampleTopic = sampleTopic

Ricordate che il jndi.properties deve essere all'interno del vostro classpath quindi un buon posto dove metterlo è la root dei vostri package in modo poi da trovarlo nella cartella classes una volta che queste verranno compilate.


E' fatta. A questo punto vi basta invocare dal vostro codice:


Logger log = Logger.getLogger(this.getClass.getName());
....
log.fatal("Questo testo verrà caricato come messaggio nel Topic sampleTopic");

Attenti che la chiamata "log.fatal" agirà sul JMSAppender solo quando facciamo la chiamata da dentro la classe JMSLogger, le invocazioni "log.fatal" effettuate da altre classi andranno a loggare sull'appender di default (tipicamente il file di log e il terminale) o sugli appender impostati attraverso il log4j.properties.

Per il momento è tutto. Alla prossima.   

Nessun commento:

Posta un commento