/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
*
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.jdbc.metrics;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import net.sf.json.JSONObject;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStreamWriter;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Simple endpoint to expose JDBC request metrics.
* <p>
* This class utilizes a cache of request metric values, keyed by request id. The cache
* entries are short lived as it is assumed that client code requesting metrics will do
* shortly after the original request. That said the cache expiry time is configurable
* with a default value of 1 minute.
* </p>
*/
public class RequestMetricsController extends AbstractController {
static Cache<String,Map<String,Object>> METRICS = CacheBuilder.newBuilder()
.expireAfterWrite(Long.getLong("jdbc-metrics.cacheExpiry", 1), TimeUnit.MINUTES)
.maximumSize(Long.getLong("jdbc-metrics.cacheMaxSize", 2000))
.build();
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
String[] split = req.getPathInfo().split("/");
String reqId = StringUtils.stripEnd(StringUtils.stripStart(split[split.length-1], "/"), "/");
JSONObject obj = new JSONObject();
obj.put("request", reqId);
Map<String,Object> m = METRICS.getIfPresent(reqId);
if (m != null) {
obj.put("metrics", m);
rsp.setStatus(HttpServletResponse.SC_OK);
}
else {
rsp.setStatus(HttpServletResponse.SC_NOT_FOUND);
obj.put("message", "metrics unavailable");
}
rsp.setContentType(MediaType.APPLICATION_JSON_VALUE);
try (OutputStreamWriter w = new OutputStreamWriter(rsp.getOutputStream(), Charsets.UTF_8)) {
obj.write(w);
w.flush();
}
return null;
}
}