diff --git a/pom.xml b/pom.xml index a132b52..231c295 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ ru.simplex_software web-statistics - 1.0 + 1.1 jar web-statistics diff --git a/src/java/ru/simplex_software/web_statistics/service/RequestStatisticService.java b/src/java/ru/simplex_software/web_statistics/service/RequestStatisticService.java deleted file mode 100644 index 25477a5..0000000 --- a/src/java/ru/simplex_software/web_statistics/service/RequestStatisticService.java +++ /dev/null @@ -1,115 +0,0 @@ -package ru.simplex_software.web_statistics.service; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * Сервис для хранения статистики по запросам. - */ -public class RequestStatisticService { - private static Map statistic = new HashMap<>(); - - /** - * Добавление данных о запросе в статистику. - * - * @param url адрес запроса. - * @param executionTime время выполнения запроса. - */ - public static void addRequestData(String url, long executionTime) { - RequestStatisticRecord record = statistic.getOrDefault(url, new RequestStatisticRecord()); - record.setUrl(url); - record.setCount(record.getCount() + 1); - record.setTotal(record.getTotal() + executionTime); - - if (executionTime < record.getMin() || record.getMin() == 0) { - record.setMin(executionTime); - } - if (executionTime > record.getMax()) { - record.setMax(executionTime); - } - statistic.put(url, record); - } - - /** - * Получение статистики по запросам. - * - * @return статистика по запросам. - */ - public static Map getStatistic() { - Map result = new LinkedHashMap<>(); - statistic.values() - .forEach(r -> r.setAverage((float) r.getTotal() / r.getCount())); - statistic.entrySet().stream() - .sorted((e1, e2) -> Float.compare(e2.getValue().getAverage(), e1.getValue().getAverage())) - .forEachOrdered(e -> result.put(e.getKey(), e.getValue())); - return result; - } - - /** - * Сброс статистики. - */ - public static void resetStatistic() { - statistic.clear(); - } - - /** - * Запись о статистике по запросу. - */ - public static class RequestStatisticRecord { - private String url; - private long count; - private long max; - private long min; - private long total; - private float average; - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public long getCount() { - return count; - } - - public void setCount(long count) { - this.count = count; - } - - public long getMax() { - return max; - } - - public void setMax(long max) { - this.max = max; - } - - public long getMin() { - return min; - } - - public void setMin(long min) { - this.min = min; - } - - public long getTotal() { - return total; - } - - public void setTotal(long total) { - this.total = total; - } - - public float getAverage() { - return average; - } - - public void setAverage(float average) { - this.average = average; - } - } -} \ No newline at end of file diff --git a/src/java/ru/simplex_software/web_statistics/web/filters/StatisticFilter.java b/src/java/ru/simplex_software/web_statistics/web/filters/StatisticFilter.java deleted file mode 100644 index 9c7d0de..0000000 --- a/src/java/ru/simplex_software/web_statistics/web/filters/StatisticFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.simplex_software.web_statistics.web.filters; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import ru.simplex_software.web_statistics.service.RequestStatisticService; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; - -/** - * Фильтр для замера времени выполнения запросов. - */ -public class StatisticFilter implements Filter { - private static final Logger LOG = LoggerFactory.getLogger(StatisticFilter.class); - - @Override - public void init(FilterConfig filterConfig) { - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - long startTime = System.nanoTime(); - chain.doFilter(request, response); - - long endTime = System.nanoTime(); - String url = ((HttpServletRequest) request).getRequestURI(); - long elapsed = (endTime - startTime) / 1000_000; - - RequestStatisticService.addRequestData(url, elapsed); - LOG.debug("Request to url {} executed in {} ms.", url, elapsed); - } -} \ No newline at end of file diff --git a/src/java/ru/simplex_software/web_statistics/web/servlets/RequestStatisticServlet.java b/src/java/ru/simplex_software/web_statistics/web/servlets/RequestStatisticServlet.java deleted file mode 100644 index 8ec15e6..0000000 --- a/src/java/ru/simplex_software/web_statistics/web/servlets/RequestStatisticServlet.java +++ /dev/null @@ -1,78 +0,0 @@ -package ru.simplex_software.web_statistics.web.servlets; - -import ru.simplex_software.web_statistics.service.RequestStatisticService; - -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Map; - -/** - * Сервлет, отдающий статистику. - */ -public class RequestStatisticServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - // Сброс статистики. - if ("reset=true".equals(request.getQueryString())) { - RequestStatisticService.resetStatistic(); - response.sendRedirect(getRequestPath(request)); - } - - // Получение статистики. - Map statistic = RequestStatisticService.getStatistic(); - - // Запись статистики в ответ. - response.setContentType("text/html; charset=UTF-8"); - response.setCharacterEncoding("UTF-8"); - response.getWriter().print(createStatisticPage(statistic, getRequestPath(request))); - } - - /** - * Создание строки страницы статистики. - * - * @param statistic статистика. - * @param requestPath путь запроса. - * @return страица статистики. - */ - private String createStatisticPage(Map statistic, String requestPath) { - StringBuilder builder = new StringBuilder(); - builder.append(""); - builder.append(""); - builder.append("Статистика по запросам"); - builder.append(""); - builder.append(""); - builder.append("Reset"); - builder.append(""); - builder.append(""); - - for (String key : statistic.keySet()) { - builder.append(""); - RequestStatisticService.RequestStatisticRecord record = statistic.get(key); - String average = String.format("%.2f", record.getAverage()); - - builder.append(""); - builder.append(""); - builder.append(""); - builder.append(""); - builder.append(""); - builder.append(""); - } - - builder.append("
UrlCountMinMaxAverage
").append(key).append("").append(record.getCount()).append("").append(record.getMin()).append(" ms").append(record.getMax()).append(" ms").append(average).append(" ms
"); - builder.append(""); - return builder.toString(); - } - - /** - * Получение пути запроса без параметров. - * - * @param request запрос. - * @return путь запроса. - */ - private String getRequestPath(HttpServletRequest request) { - return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getServletPath(); - } -} \ No newline at end of file diff --git a/src/main/java/ru/simplex_software/web_statistics/service/RequestStatisticService.java b/src/main/java/ru/simplex_software/web_statistics/service/RequestStatisticService.java new file mode 100644 index 0000000..25477a5 --- /dev/null +++ b/src/main/java/ru/simplex_software/web_statistics/service/RequestStatisticService.java @@ -0,0 +1,115 @@ +package ru.simplex_software.web_statistics.service; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Сервис для хранения статистики по запросам. + */ +public class RequestStatisticService { + private static Map statistic = new HashMap<>(); + + /** + * Добавление данных о запросе в статистику. + * + * @param url адрес запроса. + * @param executionTime время выполнения запроса. + */ + public static void addRequestData(String url, long executionTime) { + RequestStatisticRecord record = statistic.getOrDefault(url, new RequestStatisticRecord()); + record.setUrl(url); + record.setCount(record.getCount() + 1); + record.setTotal(record.getTotal() + executionTime); + + if (executionTime < record.getMin() || record.getMin() == 0) { + record.setMin(executionTime); + } + if (executionTime > record.getMax()) { + record.setMax(executionTime); + } + statistic.put(url, record); + } + + /** + * Получение статистики по запросам. + * + * @return статистика по запросам. + */ + public static Map getStatistic() { + Map result = new LinkedHashMap<>(); + statistic.values() + .forEach(r -> r.setAverage((float) r.getTotal() / r.getCount())); + statistic.entrySet().stream() + .sorted((e1, e2) -> Float.compare(e2.getValue().getAverage(), e1.getValue().getAverage())) + .forEachOrdered(e -> result.put(e.getKey(), e.getValue())); + return result; + } + + /** + * Сброс статистики. + */ + public static void resetStatistic() { + statistic.clear(); + } + + /** + * Запись о статистике по запросу. + */ + public static class RequestStatisticRecord { + private String url; + private long count; + private long max; + private long min; + private long total; + private float average; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + + public long getMax() { + return max; + } + + public void setMax(long max) { + this.max = max; + } + + public long getMin() { + return min; + } + + public void setMin(long min) { + this.min = min; + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public float getAverage() { + return average; + } + + public void setAverage(float average) { + this.average = average; + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/simplex_software/web_statistics/web/filters/StatisticFilter.java b/src/main/java/ru/simplex_software/web_statistics/web/filters/StatisticFilter.java new file mode 100644 index 0000000..9c7d0de --- /dev/null +++ b/src/main/java/ru/simplex_software/web_statistics/web/filters/StatisticFilter.java @@ -0,0 +1,38 @@ +package ru.simplex_software.web_statistics.web.filters; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.simplex_software.web_statistics.service.RequestStatisticService; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * Фильтр для замера времени выполнения запросов. + */ +public class StatisticFilter implements Filter { + private static final Logger LOG = LoggerFactory.getLogger(StatisticFilter.class); + + @Override + public void init(FilterConfig filterConfig) { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + long startTime = System.nanoTime(); + chain.doFilter(request, response); + + long endTime = System.nanoTime(); + String url = ((HttpServletRequest) request).getRequestURI(); + long elapsed = (endTime - startTime) / 1000_000; + + RequestStatisticService.addRequestData(url, elapsed); + LOG.debug("Request to url {} executed in {} ms.", url, elapsed); + } +} \ No newline at end of file diff --git a/src/main/java/ru/simplex_software/web_statistics/web/servlets/RequestStatisticServlet.java b/src/main/java/ru/simplex_software/web_statistics/web/servlets/RequestStatisticServlet.java new file mode 100644 index 0000000..8ec15e6 --- /dev/null +++ b/src/main/java/ru/simplex_software/web_statistics/web/servlets/RequestStatisticServlet.java @@ -0,0 +1,78 @@ +package ru.simplex_software.web_statistics.web.servlets; + +import ru.simplex_software.web_statistics.service.RequestStatisticService; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Map; + +/** + * Сервлет, отдающий статистику. + */ +public class RequestStatisticServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + // Сброс статистики. + if ("reset=true".equals(request.getQueryString())) { + RequestStatisticService.resetStatistic(); + response.sendRedirect(getRequestPath(request)); + } + + // Получение статистики. + Map statistic = RequestStatisticService.getStatistic(); + + // Запись статистики в ответ. + response.setContentType("text/html; charset=UTF-8"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().print(createStatisticPage(statistic, getRequestPath(request))); + } + + /** + * Создание строки страницы статистики. + * + * @param statistic статистика. + * @param requestPath путь запроса. + * @return страица статистики. + */ + private String createStatisticPage(Map statistic, String requestPath) { + StringBuilder builder = new StringBuilder(); + builder.append(""); + builder.append(""); + builder.append("Статистика по запросам"); + builder.append(""); + builder.append(""); + builder.append("Reset"); + builder.append(""); + builder.append(""); + + for (String key : statistic.keySet()) { + builder.append(""); + RequestStatisticService.RequestStatisticRecord record = statistic.get(key); + String average = String.format("%.2f", record.getAverage()); + + builder.append(""); + builder.append(""); + builder.append(""); + builder.append(""); + builder.append(""); + builder.append(""); + } + + builder.append("
UrlCountMinMaxAverage
").append(key).append("").append(record.getCount()).append("").append(record.getMin()).append(" ms").append(record.getMax()).append(" ms").append(average).append(" ms
"); + builder.append(""); + return builder.toString(); + } + + /** + * Получение пути запроса без параметров. + * + * @param request запрос. + * @return путь запроса. + */ + private String getRequestPath(HttpServletRequest request) { + return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getServletPath(); + } +} \ No newline at end of file