URL-адрес журнала, вызвавший ошибку 404 в приложении DropWizard или Jetty

Мы запускаем DropWizard и пытаемся отключить регистрацию URL-адресов, которые вызывают появление ответов 404.

У нас есть универсальный преобразователь исключений, который получает NotFoundException. К сожалению, это исключение не содержит контекста того, какой URL-адрес вызвал его создание.

Пример приложения здесь: https://github.com/pauldambra/not.found.example

Мы используем ExceptionMapper

public class NotFoundLogger implements ExceptionMapper<NotFoundException> {

    ExampleLogger logger = new ExampleLogger();

    @Override
    public Response toResponse(final NotFoundException exception) {
        logger.error(urlFrom(exception), exception);
        return Response.status(404).build();
    }

    private String urlFrom(final NotFoundException exception) {
        return "why is this not a property on the exception?!";
    }

    private class ExampleLogger {
        void error(final String notFoundUrl, final NotFoundException exception) {
            System.out.println("someone tried to load " + notFoundUrl);
            System.out.println(exception.getMessage());
        }
    }
}

Если мы посмотрим на журналы приложений, когда кто-то запрашивает URL-адрес, который приложение не обслуживает, мы увидим, что приложение может регистрировать, что оно возвращает 404 для пути, но наш пользовательский регистратор не имеет доступа к URL-адресу.

someone tried to load why is this not a property on the exception?!
HTTP 404 Not Found
127.0.0.1 - - [08/May/2019:09:53:47 +0000] "GET /ping/pong HTTP/1.1" 404 

Является ли ExceptionMapper неправильным способом сделать это?

Можете ли вы получить доступ к HttpServletRequest, вызвавшему исключение во время toResponse()? за stackoverflow.com/q/17766072/775715

Joakim Erdfelt 08.05.2019 12:01

Или используйте UriInfo за stackoverflow.com/a/43610403/775715

Joakim Erdfelt 08.05.2019 12:02

О, этот контекстный механизм выглядит многообещающе! Хотя я ненавижу эту необнаружимую магию! (почему это не просто перегрузка метода: D)

Paul D'Ambra 08.05.2019 12:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
296
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оказывается, есть два пути

один использует сопоставитель исключений:

public class NotFoundLogger implements ExceptionMapper<NotFoundException> {

    // magically inject a thing
    // remember that magic is for evil wizards
    @Context
    private HttpServletRequest request;

    private ExampleLogger logger = new ExampleLogger();

    @Override
    public Response toResponse(final NotFoundException exception) {
        final StringBuffer absolutePath = HttpUtils.getRequestURL(request);
        logger.error("exception mapper: " + absolutePath, exception);
        return Response.status(404).build();
    }
}

Это работает, но не очень заметно.

Вы также можете добавить фильтр ответов

public class NotFoundLoggingFilter implements ContainerResponseFilter {
    private ExampleLogger logger = new ExampleLogger();

    @Override
    public void filter(ContainerRequestContext requestContext,
                       ContainerResponseContext responseContext) {
        if (responseContext.getStatus() != 404) {
            return;
        }

        final URI absolutePath = requestContext.getUriInfo().getAbsolutePath();
        logger.error("filter: " + absolutePath, new NotFoundException());
    }
}

Это не требует никакой магии, так что мне подходит, но вы можете выбрать свой яд.

На самом деле путь должен быть на NotFoundException - если бы у меня было больше времени, я бы предложил изменить код, чтобы добавить его.

Другие вопросы по теме