PerformanceMetricsResource.java

  1. /*
  2.  * Copyright (c) 2007-2017 MetaSolutions AB
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *     http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */

  16. package org.entrystore.rest.resources;

  17. import static java.util.concurrent.TimeUnit.MILLISECONDS;

  18. import io.micrometer.core.instrument.Meter;
  19. import io.micrometer.core.instrument.MeterRegistry;
  20. import io.micrometer.core.instrument.Metrics;
  21. import io.micrometer.core.instrument.Timer;
  22. import io.micrometer.core.instrument.distribution.HistogramSnapshot;
  23. import io.micrometer.core.instrument.distribution.ValueAtPercentile;
  24. import java.net.URI;
  25. import org.entrystore.AuthorizationException;
  26. import org.entrystore.PrincipalManager;
  27. import org.json.JSONObject;
  28. import org.restlet.data.Status;
  29. import org.restlet.ext.json.JsonRepresentation;
  30. import org.restlet.representation.EmptyRepresentation;
  31. import org.restlet.representation.Representation;
  32. import org.restlet.resource.Get;
  33. import org.slf4j.Logger;
  34. import org.slf4j.LoggerFactory;


  35. /**
  36.  * Provides methods to retrieve performance metrics.
  37.  *
  38.  */
  39. public class PerformanceMetricsResource extends BaseResource {

  40.     static Logger log = LoggerFactory.getLogger(PerformanceMetricsResource.class);

  41.     /**
  42.      * <pre>
  43.      * GET {baseURI}/metrics
  44.      * </pre>
  45.      *
  46.      * @return performance metrics
  47.      */
  48.     @Get
  49.     public Representation represent() {
  50.         try {
  51.             MeterRegistry registry = Metrics.globalRegistry;
  52.             PrincipalManager pm = getRM().getPrincipalManager();
  53.             URI currentUser = pm.getAuthenticatedUserURI();

  54.             if (!pm.getAdminUser().getURI().equals(currentUser) &&
  55.                     !pm.getAdminGroup().isMember(pm.getUser(currentUser))) {
  56.                 getResponse().setStatus(Status.CLIENT_ERROR_FORBIDDEN);
  57.                 return new EmptyRepresentation();
  58.             }

  59.             JSONObject result = new JSONObject();
  60.             for (Meter meter : registry.getMeters()) {
  61.                 // We only expose the request timers for now
  62.                 if (meter instanceof Timer timer) {
  63.                     String timerName = timer.getId().getName();
  64.                     HistogramSnapshot histogramSnapshot = timer.takeSnapshot();
  65.                     JSONObject timerData = new JSONObject();
  66.                     timerData.put("requests", histogramSnapshot.count());
  67.                     timerData.put("mean", Math.round(histogramSnapshot.mean(MILLISECONDS)));
  68.                     timerData.put("max", Math.round(histogramSnapshot.max(MILLISECONDS)));
  69.                     for (ValueAtPercentile valueAtPercentile : histogramSnapshot.percentileValues()) {
  70.                         timerData.put("percentile-" + valueAtPercentile.percentile(),
  71.                                 Math.round(valueAtPercentile.value(MILLISECONDS)));
  72.                     }
  73.                     result.put(timerName, timerData);
  74.                 }
  75.             }
  76.             return new JsonRepresentation(result.toString(2));
  77.         } catch (AuthorizationException e) {
  78.             return unauthorizedGET();
  79.         } catch (Throwable e) {  //Includes JSONException
  80.             log.error(e.getMessage());
  81.             getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
  82.             return new EmptyRepresentation();
  83.         }
  84.     }
  85. }