Эффективный доступ к HttpServletRequest для отладочных отпечатков

Для отладки неудачных запросов я хотел бы распечатать всю информацию, поступающую из HttpServletRequest.

Теперь возможно, что запрос будет частично потерпеть неудачу (например, несколько совпадений успешны, но одно не удалось), и в этом случае я хотел бы отловить исключение во внутреннем методе, который не удалось, вывести ошибку + ServletUtil.toStringHttpServletRequest() и продолжить предоставление услуг (ухудшено, но все еще полезно против полного отказа запроса).

Наша текущая реализация либо перехватывает исключение и печатает тупую информацию ("getRules failed"), либо выдает исключение полностью вплоть до doGet() (фактически отменяя сервис для пользователя), где, как и в doGet (), у меня есть доступ к HttpServletRequest, где я могу печатать в соответствующей отладочной информации (заголовки, параметры...).

Передача HttpServletRequest каждой функции, вызываемой во время запроса, который может потерпеть неудачу, кажется немного уродливой, я сделаю это, если не появится другое элегантное решение.

Создание переднего заголовка ServletUtil.toStringHttpServletRequest() и сохранение его в карте ThreadLocal будет расточительным как в памяти, так и во время процессора. По какой-то причине неправильно хранить объект HttpServletRequest в ThreadLocal (исправьте, если я ошибаюсь).

Отладочная информация записывается как в журнал локального компьютера, так и по электронной почте непосредственно разработчикам (отличная работа log4j TLSSMTPAppender), поэтому регистрация в нескольких местах не будет практичной (потребуется собрать несколько писем, чтобы понять, что происходит) и ssh'ing в сервер старости:) (у нас все облачно... сервер может не существовать к тому времени, когда я увижу эту ошибку)

Итак, мое решение - получить доступ к "PrintErrorUtility" (TODO: лучше назвать его). Это получит (String errorMsg, Throwable t, HttpServletRequest), который напечатает ошибку вместе, получит всю необходимую информацию... Это будет вызвано из внутренних блоков try {} catch, которые уведомят об ошибке, но не отменит запрос, потому что этого

Очевидно, я говорю о серверах, работающих в производстве.

Комментарии? Пожалуйста, порекомендуйте.

Спасибо, Максим.

1 ответ

Решение

Выполните эту задачу в Filter после FilterChain#doFilter() вызов. ServletRequest объект уже есть. В бизнес-коде, где это исключение должно быть изящно подавлено, сохраните исключение как атрибут запроса и просто дайте Filter проверьте / возьмите это из запроса.


Обновление: согласно комментариям, вот пример:

public class Context { 
    private static ThreadLocal<Context> instance = new ThreadLocal<Context>();
    private HttpServletRequest request;
    private List<Exception> exceptions = new ArrayList<Exception>();

    private Context(HttpServletRequest request) {
        this.request = request;
        this.request.setAttribute("exceptions", exceptions);
    }

    public static Context getCurrentInstance() {
        return instance.get();
    }

    public static Context newInstance(HttpServletRequest request) {
        Context context = new Context(request);
        instance.set(context);
        return context;
    }

    public void release() {
        instance.remove();
    }

    public void addException(Exception exception) {
        exceptions.add(exception);
    }
}

А вот как использовать его в вашем сервлете контроллера:

Context context = Context.newInstance(request);
try {
    executeBusinessCode();
} finally {
    context.release();
}

А вот как вы можете использовать его в исполняемом бизнес-коде:

} catch (Exception e) {
    Context.getCurrentInstance().addException(e);
}
Другие вопросы по тегам