Based on a request parameter in a servlet context
Recently I had the task to report active accounts based on http requests. Here I’m going to show you my solution with Dropwizard Metrics.
Basically I am using a servlet filter togehter with an counter.
[code]
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
try {
chain.doFilter(request, response);
} catch (IOException | ServletException e) {
LOG.error("unexpected exception occurred", e);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "unexpected exception occurred");
} finally {
String accountNumber = request.getParameter("account");
countRequestForAccount(accountNumber);
}
}
private void countRequestForAccount(int account) {
if(activeAccounts.containsKey(account))
{
activeAccounts.get(account).inc();
} else if(activeAccounts.size() <= MAX_SIZE) {
metricsRegistry.counter(Integer.toString(account)).inc();
}
}
[/code]
Each account has its own counter. So I have a ConcurrentHashMap activeAccounts with account and counter. If there is a parameter „account“ in the request, I increase the counter for that account.
The second requirement was to save the active accounts with counter in a csv file.
[code]
@Override
public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters,
SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers) {
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
for (Entry<String, Counter> entry : counters.entrySet()) {
Counter value = entry.getValue();
writer.write(String.format("%s;%d%n", entry.getKey(), value.getCount()));
}
} catch (IOException e) {
LOG.error("couldn’t write report file " + path, e);
}
}
[/code]
I extended a ScheduledReporter as shown above. The csv file has the format
account;counter
And at last, I putted together all the pieces in my servlet class.
[code]
…
public void init() throws ServletException {
…
MetricRegistry metricsRegistry = (MetricRegistry) getServletContext().getAttribute(MetricsServlet.METRICS_REGISTRY);
Path path = Paths.get("/tmp/activeAccounts.cvs"));
…
reporter = new ActiveAccountsReporter(metricsRegistry, path);
reporter.start(ACTIVE_ACCOUNTS_REPORT_PERIOD_SEC, TimeUnit.SECONDS);
}
}
[/code]
That’s it. I hope you like my article.
On GistGitHub you can read the whole example.