Как бы вы разобрали и зарегистрировали время выполнения различных частей вашего приложения?

StackOverflow https://stackoverflow.com/questions/1026009

  •  06-07-2019
  •  | 
  •  

Вопрос

Мы создали веб-приложение, которое принимает сообщения SOAP, выполняет некоторую обработку, вызывает другой веб-сервис, обрабатывает ответ и отправляет его обратно исходному вызывающему абоненту.

Мы хотели бы записать в одной строке разное время выполнения для этих разных шагов.Мы используем log4j со стеком JBossWS.Другими словами, нам бы хотелось, чтобы вывод журнала выглядел примерно так:

2009-06-10T16:19:31.487 3336/2449/861

где 3336 мс — общее время, затраченное на обработку запроса, 2449 мс — время, потраченное на ожидание ответа веб-службы, а 861 мс — время, затраченное на внутреннюю обработку данных.

Эти разные вычисления происходят в разных местах нашего кода, и мы не можем просто рассчитать время каждого из них и вызвать регистратор в конце одного метода.Один из нас предложил использовать для этого MDC log4j в качестве набора глобальных переменных для бедняков, чтобы отслеживать различное время выполнения.

Итак, мои вопросы следующие:

  1. Является ли это ужасным злоупотреблением основной целью MDC?
  2. Если да, то как бы вы это сделали иначе?
Это было полезно?

Решение

Пожалуйста, ознакомьтесь с профилировщиком SLF4J . Достаточно интересно tt был разработан, чтобы отвечать точно такой же потребности, то есть измерять и улучшать производительность вызовов SOAP.

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

Похоже на работу для Perf4J .

Я бы сделал следующее:

  1. создайте класс PerformanceTimer, который предоставляет:
    • RecordWaitedForWebServerReponse (идентификатор операции, время);
    • RecordMassagedData (идентификатор операции, время);
    • другие методы при необходимости
  2. внедрите этот класс там, где это необходимо;
  3. заставить PerformanceTimer поддерживать параллельную карту OperationId -> OperationTimingData;
  4. при вызове метода, который, как известно, является последним, вызовите Log4j с желаемым результатом.

Хотя это, безусловно, сработает, я тоже съеживаюсь от этой мысли. Я бы предложил создать класс синхронизации именно для этой цели, который использует ThreadLocal для создания переменной для каждого запроса.

Когда приходит запрос, вы создаете переменную ( long со временем запуска). Когда переменная уже существует, вы оставляете ее в покое. Когда результат отправляется обратно клиенту, вы рассчитываете продолжительность и записываете ее.

Я бы использовал Spring и аспектно-ориентированное программирование, чтобы сделать это. Приятно, что я однажды написал логику и применил ее декларативно везде, где мне было нужно.

Один простой способ - использовать System.currentTimeMillis () , который возвращает время в миллисекундах. Разница между миллисекундами в начале метода и миллисекундами в конце метода даст миллисекунды, затраченные на выполнение этого конкретного метода. Надеюсь, System.currentTimeMillis () поможет вам.

Мы просто используем это в нашем первом фильтре запросов:

logger.trace("Init");
long start = System.currentTimeMillis();

//do stuff here 

long stop = System.currentTimeMillis();
String time = Util.getTimeDifferenceInSec(start, stop);
logger.trace("Complete in " + time + " sec");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top