Рубрики
Без рубрики

Протоколирование HTTP-запросов с помощью трассировки HTTP привода Spring Boot

Узнайте, как отслеживать HTTP-вызовы с помощью привода Spring Boot.

Автор оригинала: Marcos Lopez Gonzalez.

1. введение

Когда мы работаем с микросервисами или веб-сервисами в целом, очень полезно знать, как наши пользователи взаимодействуют с нашими сервисами. Это может быть достигнуто путем отслеживания всех запросов, поступающих в наши службы, и сбора этой информации для последующего анализа.

Есть некоторые доступные системы, которые могут помочь нам в этом и могут быть легко интегрированы с Spring, например Zipkin . Однако привод Spring Boot имеет эту встроенную функцию и может использоваться через конечную точку http Trace , которая отслеживает все HTTP-запросы. В этом уроке мы покажем, как его использовать и как настроить, чтобы он лучше соответствовал нашим требованиям.

2. Настройка Конечной Точки Трассировки Http

Для этого урока мы будем использовать проект Maven Spring Boot .

Первое, что нам нужно сделать, это добавить зависимость привода пружинной загрузки в наш проект:


  org.springframework.boot
  spring-boot-starter-actuator

После этого нам нужно будет включить конечную точку http Trace в нашем приложении.

Для этого нам просто нужно изменить наш файл application.properties , чтобы включить http-трассировку конечную точку :

management.endpoints.web.exposure.include=httptrace

В случае, если нам нужно больше конечных точек, мы можем просто объединить их, разделив запятыми, или мы можем включить их все, используя подстановочный знак * .

Теперь наша конечная точка httpTrace должна появиться в списке конечных точек привода нашего приложения:

{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "httptrace": {
      "href": "http://localhost:8080/actuator/httptrace",
      "templated": false
    }
  }
}

Обратите внимание, что мы можем перечислить все включенные конечные точки привода, перейдя в конечную точку /привода нашей веб-службы.

3. Анализ следов

Давайте теперь проанализируем следы, которые возвращает конечная точка http Trace actuator.

Давайте сделаем несколько запросов к нашей службе, вызовем //http-трассировку конечную точку и возьмем одну из возвращенных трассировок:

{
  "traces": [
    {
      "timestamp": "2019-08-05T19:28:36.353Z",
      "principal": null,
      "session": null,
      "request": {
        "method": "GET",
        "uri": "http://localhost:8080/echo?msg=test",
        "headers": {
          "accept-language": [
            "en-GB,en-US;q=0.9,en;q=0.8"
          ],
          "upgrade-insecure-requests": [
            "1"
          ],
          "host": [
            "localhost:8080"
          ],
          "connection": [
            "keep-alive"
          ],
          "accept-encoding": [
            "gzip, deflate, br"
          ],
          "accept": [
            "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
          ],
          "user-agent": [
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 OPR/62.0.3331.66"
          ]
        },
        "remoteAddress": null
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Length": [
            "12"
          ],
          "Date": [
            "Mon, 05 Aug 2019 19:28:36 GMT"
          ],
          "Content-Type": [
            "text/html;charset=UTF-8"
          ]
        }
      },
      "timeTaken": 82
    }
  ]
}

Как мы видим, ответ разделен на несколько узлов:

  • метка времени : время получения запроса
  • принципал : аутентифицированный пользователь, который сделал запрос, если это применимо
  • сеанс : любой сеанс, связанный с запросом
  • запрос : информация о запросе, такая как метод, полный URI или заголовки
  • ответ : информация об ответе, такая как статус или заголовки
  • затраченное время : время, затраченное на обработку запроса

Мы можем адаптировать этот ответ к нашим потребностям, если чувствуем, что он слишком многословен. Мы можем сообщить Spring, какие поля мы хотим вернуть, указав их в management.trace.http.include property нашего application.properties :

management.trace.http.include=RESPONSE_HEADERS

В этом случае мы указали, что нам нужны только заголовки ответов. Следовательно, мы можем видеть, что поля, которые были включены раньше, такие как заголовки запроса или затраченное время, сейчас отсутствуют в ответе:

{
  "traces": [
    {
      "timestamp": "2019-08-05T20:23:01.397Z",
      "principal": null,
      "session": null,
      "request": {
        "method": "GET",
        "uri": "http://localhost:8080/echo?msg=test",
        "headers": {},
        "remoteAddress": null
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Length": [
            "12"
          ],
          "Date": [
            "Mon, 05 Aug 2019 20:23:01 GMT"
          ],
          "Content-Type": [
            "text/html;charset=UTF-8"
          ]
        }
      },
      "timeTaken": null
    }
  ]
}

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

4. Настройка репозитория трассировки Http

По умолчанию конечная точка http Trace возвращает только последние 100 запросов и сохраняет их в памяти . Хорошей новостью является то, что мы также можем настроить это, создав свой собственный репозиторий трассировки Http//.

Теперь давайте создадим наш репозиторий. Интерфейс Http Trace Repository очень прост, и нам нужно реализовать только два метода: findAll() для извлечения всех трассировок и add() для добавления трассировки в репозиторий.

Для простоты наш репозиторий также будет хранить следы в памяти, и мы будем хранить только последний запрос GET, который попадает в наш сервис:

@Repository
public class CustomTraceRepository implements HttpTraceRepository {

    AtomicReference lastTrace = new AtomicReference<>();

    @Override
    public List findAll() {
        return Collections.singletonList(lastTrace.get());
    }

    @Override
    public void add(HttpTrace trace) {
        if ("GET".equals(trace.getRequest().getMethod())) {
            lastTrace.set(trace);
        }
    }

}

Несмотря на то, что этот простой пример может показаться не очень полезным, мы видим, насколько мощным он может стать и как мы можем хранить наши журналы в любом месте.

5. Фильтрация путей для трассировки

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

Если мы немного поиграем с конечной точкой http Trace после выполнения некоторых запросов к нашему сервису, мы увидим, что мы также получаем трассировки для запросов привода:

{
  "traces": [
    {
      "timestamp": "2019-07-28T13:56:36.998Z",
      "principal": null,
      "session": null,
      "request": {
        "method": "GET",
        "uri": "http://localhost:8080/actuator/",
         // ...
}

Мы можем не найти эти следы полезными для нас, и мы предпочли бы исключить их. В этом случае нам просто нужно создать свой собственный Http-фильтр трассировки и указать, какие пути мы хотим игнорировать в методе shouldNotFilter :

@Component
public class TraceRequestFilter extends HttpTraceFilter {

  public TraceRequestFilter(HttpTraceRepository repository, HttpExchangeTracer tracer) {
      super(repository, tracer);
  }

  @Override
  protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
      return request.getServletPath().contains("actuator");
  }
}

Обратите внимание, что фильтр трассировки Http -это обычный фильтр Spring, но с некоторыми функциями, специфичными для трассировки.

6. Заключение

В этом уроке мы представили конечную точку http Trace Spring Boot Actuator и показали ее основные функции. Мы также копнули немного глубже и объяснили, как изменить некоторые модели поведения по умолчанию, чтобы лучше соответствовать нашим конкретным потребностям.

Как всегда, полный исходный код примеров доступен на GitHub .