org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/Agencia].[action] [2007-02-28 09:30:12,529] ERROR - Servlet.service() for servlet action threw exception
javax.servlet.ServletException: A URL do menu é inválida
at br.com.xxxx.agencia.controle.AutorizacaoFilter.doFilter(AutorizacaoFilter.java:127)
O log4j só está registrando via JDBCAppender a mensagem
O que não ajuda em nada a identificar o erro. E até pode ser descartado.
Gostaria de saber se há como tratar melhor as mensagens que vão para o banco de dados?
Eu adotei uma solução diferente.
Criei uma classe estendendo JDBCAppender e sobreescrevi o metodo getLogStatement(LoggingEvent evt)
através do parametro evt eu consigo todas as informações para serem postas na mensagem.
Também gostaria de postar minha sugestão com log4j.
Fiz uma alteração no smtpAppender que aceita autenticação do Ceki Gulcu.
package br.com.drogaraia.recweb.service.util;
import java.util.Date;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.MultiPartEmail;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.CyclicBuffer;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.TriggeringEventEvaluator;
/**
* Send an e-mail when a specific logging event occurs, typically on errors or
* fatal errors.
*
* <p>
* The number of logging events delivered in this e-mail depend on the value of
* <b>BufferSize</b> option. The <code>SMTPAppender</code> keeps only the
* last <code>BufferSize</code> logging events in its cyclic buffer. This
* keeps memory requirements at a reasonable level while still delivering useful
* application context.
*
* @author Ceki Gülcü
* @since 1.0
*/
public class SMTPAppender extends AppenderSkeleton {
private String to;
private String cc;
private String from;
private String subject;
private String smtpHost;
private int bufferSize = 512;
private boolean locationInfo = false;
private String user;
private String password;
private String mustAuthentication;
protected CyclicBuffer cb = new CyclicBuffer(bufferSize);
// protected Message msg;
private MultiPartEmail email = new MultiPartEmail();
protected TriggeringEventEvaluator evaluator;
/**
* The default constructor will instantiate the appender with a
* {@link TriggeringEventEvaluator} that will trigger on events with level
* ERROR or higher.
*/
public SMTPAppender() {
this(new DefaultEvaluator());
}
/**
* Use <code>evaluator</code> passed as parameter as the {@link
* TriggeringEventEvaluator} for this SMTPAppender.
*/
public SMTPAppender(TriggeringEventEvaluator evaluator) {
this.evaluator = evaluator;
}
/**
* Activate the specified options, such as the smtp host, the recipient,
* from, etc.
*/
public void activateOptions() {
email.setCharset(Email.ISO_8859_1);
if (smtpHost != null){
email.setHostName(smtpHost);
}
if (needAuthentication()){
email.setAuthentication(user, password);
}
try {
if (from != null){
email.setFrom(from);
}
else{
email.setFrom("algum@lugar.com.br");
}
email.addTo(to);
if (cc != null) {
email.addTo(cc);
}
if (subject != null){
email.setSubject(subject);
} else {
email.setSubject("Qual é o seu problema?");
}
} catch (EmailException e) {
LogLog.error("Could not activate SMTPAppender options.", e);
}
}
private boolean needAuthentication() {
if (mustAuthentication != null){
String upperCase = mustAuthentication.toUpperCase();
return upperCase.equals("TRUE");
}
return false;
}
/**
* Perform SMTPAppender specific appending actions, mainly adding the event
* to a cyclic buffer and checking if the event triggers an e-mail to be
* sent.
*/
public void append(LoggingEvent event) {
if (!checkEntryConditions()) {
return;
}
event.getThreadName();
event.getNDC();
if (locationInfo) {
event.getLocationInformation();
}
cb.add(event);
if (evaluator.isTriggeringEvent(event)) {
sendBuffer();
}
}
/**
* This method determines if there is a sense in attempting to append.
*
* <p>
* It checks whether there is a set output target and also if there is a set
* layout. If these checks fail, then the boolean value <code>false</code>
* is returned.
*/
protected boolean checkEntryConditions() {
/* if (this.msg == null) {
errorHandler.error("Message object not configured.");
return false;
}*/
if (this.evaluator == null) {
errorHandler.error("No TriggeringEventEvaluator is set for appender [" + name + "].");
return false;
}
if (this.layout == null) {
errorHandler.error("No layout set for appender named [" + name + "].");
return false;
}
return true;
}
synchronized public void close() {
this.closed = true;
}
/**
* Returns value of the <b>To</b> option.
*/
public String getTo() {
return to;
}
/**
* The <code>SMTPAppender</code> requires a {@link org.apache.log4j.Layout
* layout}.
*/
public boolean requiresLayout() {
return true;
}
/**
* Send the contents of the cyclic buffer as an e-mail message.
*/
protected void sendBuffer() {
try {
StringBuffer sbuf = new StringBuffer();
String t = layout.getHeader();
if (t != null)
sbuf.append(t);
int len = cb.length();
for (int i = 0; i < len; i++) {
// sbuf.append(MimeUtility.encodeText(layout.format(cb.get())));
LoggingEvent event = cb.get();
sbuf.append(layout.format(event));
if (layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
for (int j = 0; j < s.length; j++) {
sbuf.append(s[j]);
}
}
}
}
t = layout.getFooter();
if (t != null)
sbuf.append(t);
email.setSentDate(new Date());
email.setMsg(sbuf.toString());
email.buildMimeMessage();
//msg.setSentDate(new Date());
email.send();
} catch (Exception e) {
LogLog.error("Error occured while sending e-mail notification.", e);
}
}
/**
* Returns value of the <b>EvaluatorClass</b> option.
*/
public String getEvaluatorClass() {
return evaluator == null ? null : evaluator.getClass().getName();
}
/**
* Returns value of the <b>From</b> option.
*/
public String getFrom() {
return from;
}
/**
* Returns value of the <b>Subject</b> option.
*/
public String getSubject() {
return subject;
}
/**
* The <b>From</b> option takes a string value which should be a e-mail
* address of the sender.
*/
public void setFrom(String from) {
this.from = from;
}
/**
* The <b>Subject</b> option takes a string value which should be a the
* subject of the e-mail message.
*/
public void setSubject(String subject) {
this.subject = subject;
}
/**
* The <b>BufferSize</b> option takes a positive integer representing the
* maximum number of logging events to collect in a cyclic buffer. When the
* <code>BufferSize</code> is reached, oldest events are deleted as new
* events are added to the buffer. By default the size of the cyclic buffer
* is 512 events.
*/
public void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
cb.resize(bufferSize);
}
/**
* The <b>SMTPHost</b> option takes a string value which should be a the
* host name of the SMTP server that will send the e-mail message.
*/
public void setSMTPHost(String smtpHost) {
this.smtpHost = smtpHost;
}
/**
* Returns value of the <b>SMTPHost</b> option.
*/
public String getSMTPHost() {
return smtpHost;
}
/**
* The <b>To</b> option takes a string value which should be a comma
* separated list of e-mail address of the recipients.
*/
public void setTo(String to) {
this.to = to;
}
/**
* Returns value of the <b>BufferSize</b> option.
*/
public int getBufferSize() {
return bufferSize;
}
/**
* The <b>EvaluatorClass</b> option takes a string value representing the
* name of the class implementing the {@link TriggeringEventEvaluator}
* interface. A corresponding object will be instantiated and assigned as
* the triggering event evaluator for the SMTPAppender.
*/
public void setEvaluatorClass(String value) {
evaluator = (TriggeringEventEvaluator) OptionConverter.instantiateByClassName(value,
TriggeringEventEvaluator.class, evaluator);
}
/**
* The <b>LocationInfo</b> option takes a boolean value. By default, it is
* set to false which means there will be no effort to extract the location
* information related to the event. As a result, the layout that formats
* the events as they are sent out in an e-mail is likely to place the wrong
* location information (if present in the format).
*
* <p>
* Location information extraction is comparatively very slow and should be
* avoided unless performance is not a concern.
*/
public void setLocationInfo(boolean locationInfo) {
this.locationInfo = locationInfo;
}
/**
* Returns value of the <b>LocationInfo</b> option.
*/
public boolean getLocationInfo() {
return locationInfo;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getMustAuthentication() {
return mustAuthentication;
}
public void setMustAuthentication(String mustAuthentication) {
this.mustAuthentication = mustAuthentication;
}
public String getCc() {
return cc;
}
public void setCc(String cc) {
this.cc = cc;
}
}
class DefaultEvaluator implements TriggeringEventEvaluator {
/**
* Is this <code>event</code> the e-mail triggering event?
*
* <p>
* This method returns <code>true</code>, if the event level has ERROR
* level or higher. Otherwise it returns <code>false</code>.
*/
public boolean isTriggeringEvent(LoggingEvent event) {
return event.getLevel().isGreaterOrEqual(Level.ERROR);
}
}