Я написал огромное веб-приложение и "забыл" включить ведение журнала (я печатаю только ошибки со стандартным методом e.printStackTrace()).
Мой вопрос в том, есть ли какой-либо метод автоматического журнала (getLogger.LOG(SEVERE, "...")) любое заброшенное исключение?
возможно, с настраиваемой фабрикой исключений, например, в exceptionFactory JSF?
Я хочу регистрировать каждое брошенное исключение с помощью моего регистратора, например, прежде чем программа войдет в блок catch, исключение должно быть уже зарегистрировано:
try{
...
} catch(Exception1 e){
//Exception must have been already logged here (without adding getLogger().LOG(...) every time)
System.out.println(e.printStackTrace());
} catch(Exception2 e){
//Exception must have been already logged here (without adding getLogger().LOG(...) every time)
System.out.println(e.printStackTrace());
}
Взгляните на аспектно-ориентированное программирование, которое может вставить код регистрации во время выполнения для вашей любимой структуры ведения журнала. JDK включает пакет java.lang.instrument, который может вставлять байт-коды во время загрузки классов для выполнения регистрации.
В противном случае вы можете установить сервлет- фильтр как самый верхний фильтр в цепочке вызовов, который будет захватывать большинство ваших исключений.
public class LogFilter implements javax.servlet.Filter {
private static final String CLASS_NAME = LogFilter.class.getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
logger.entering(CLASS_NAME, "doFilter", new Object[]{request, response});
try {
chain.doFilter(request, response);
} catch (IOException | ServletException | RuntimeException | Error ioe) {
logger.log(Level.SEVERE, "", ioe);
throw ioe; //Keep forwarding.
} catch (Throwable t) {
logger.log(Level.SEVERE, "", t);
throw new ServletException(t);
}
logger.exiting(CLASS_NAME, "doFilter");
}
@Override
public void destroy() {
}
}
Теперь я также перед новым крупным проектом и заинтересован в устранении ненужного кода, который будет выпущен. Сначала я хотел зарегистрировать каждую запись и выйти из метода, включая входные и выходные данные. В моем случае архитектуры, управляемой событиями, я подталкиваю эти данные к эластичности и постоянно анализирую тайм-ауты обработки методов, то есть много строк кода. Поэтому я обработал это с помощью AspectJ. Очень хороший пример: http://www.baeldung.com/spring-performance-logging
То же самое применяется для автоматического регистрации ошибок, вот фиктивный пример, который я буду распространять на работу с slf4j, но это подробности:
public aspect ExceptionLoggingAspect {
private Log log = LogFactory.getLog(this.getClass());
private Map loggedThrowables = new WeakHashMap();
public pointcut scope(): within(nl.boplicity..*);
after() throwing(Throwable t): scope() {
logThrowable(t, thisJoinPointStaticPart,
thisEnclosingJoinPointStaticPart);
}
before (Throwable t): handler(Exception+) && args(t) && scope() {
logThrowable(t, thisJoinPointStaticPart,
thisEnclosingJoinPointStaticPart);
}
protected synchronized void logThrowable(Throwable t, StaticPart location,
StaticPart enclosing) {
if (!loggedThrowables.containsKey(t)) {
loggedThrowables.put(t, null);
Signature signature = location.getSignature();
String source = signature.getDeclaringTypeName() + ":" +
(enclosing.getSourceLocation().getLine());
log.error("(a) " + source + " - " + t.toString(), t);
}
}
}
Я был бы рад услышать, что еще один хороший пример сокращения котельного таблиц. Я, конечно, использую Loombok, который выполняет превосходную задачу...
ПРИМЕЧАНИЕ: не изобретайте колесо, поэтому смотрите здесь, как другие люди собрали полезный AOP для повторного использования в вашем проекте из коробки :-)) с открытым исходным кодом - отличное сообщество: https://github.com/jcabi/jcabi-aspects
Вы можете установить обработчик обработанных исключений для основного потока и каждого другого, созданного с помощью метода Thread.setUncaughtExceptionHandler(), и выполнить все необходимые записи.