Как бы вы разобрали и зарегистрировали время выполнения различных частей вашего приложения?
Вопрос
Мы создали веб-приложение, которое принимает сообщения SOAP, выполняет некоторую обработку, вызывает другой веб-сервис, обрабатывает ответ и отправляет его обратно исходному вызывающему абоненту.
Мы хотели бы записать в одной строке разное время выполнения для этих разных шагов.Мы используем log4j со стеком JBossWS.Другими словами, нам бы хотелось, чтобы вывод журнала выглядел примерно так:
2009-06-10T16:19:31.487 3336/2449/861
где 3336 мс — общее время, затраченное на обработку запроса, 2449 мс — время, потраченное на ожидание ответа веб-службы, а 861 мс — время, затраченное на внутреннюю обработку данных.
Эти разные вычисления происходят в разных местах нашего кода, и мы не можем просто рассчитать время каждого из них и вызвать регистратор в конце одного метода.Один из нас предложил использовать для этого MDC log4j в качестве набора глобальных переменных для бедняков, чтобы отслеживать различное время выполнения.
Итак, мои вопросы следующие:
- Является ли это ужасным злоупотреблением основной целью MDC?
- Если да, то как бы вы это сделали иначе?
Решение
Пожалуйста, ознакомьтесь с профилировщиком SLF4J . Достаточно интересно tt был разработан, чтобы отвечать точно такой же потребности, то есть измерять и улучшать производительность вызовов SOAP.
Другие советы
Похоже на работу для Perf4J .
Я бы сделал следующее:
- создайте класс PerformanceTimer, который предоставляет:
- RecordWaitedForWebServerReponse (идентификатор операции, время);
- RecordMassagedData (идентификатор операции, время);
- другие методы при необходимости
- внедрите этот класс там, где это необходимо;
- заставить PerformanceTimer поддерживать параллельную карту OperationId -> OperationTimingData;
- при вызове метода, который, как известно, является последним, вызовите 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");