Apache Geode CHANGELOG

Configuration and Publishing

Meter configuration

Out of the box Geode is instrumented and can emit meters with a properly created Meter Registry.

However, any meters that are timers based on the system clock time, similar to the time statistics, they will obey the existing enable-time-statistics geode.properties setting, see Setting up Statistics.

Publishing metrics using a meter registry

In order to emit metrics to an Application Performance Monitor (APM) or other such tool that can store or display metrics, a meter registry is required. Micrometer implements many different meter registries as project imports, a list can be found here: https://micrometer.io/docs.

As a simple example, below describes how you might create a publishing service utilizing the MetricsSession and MetricsPublishingService interface in Geode.

Here is a example class that would enable Prometheus metrics to be emitted:

public class SimpleMetricsPublishingService implements MetricsPublishingService {

  private static final String PORT_PROPERTY = "prometheus.metrics.port";
  private static final int DEFAULT_PORT = 0; // If no port specified, use any port
  private static final String HOSTNAME = "localhost";
  private static final int PORT = getInteger(PORT_PROPERTY, DEFAULT_PORT);

  private static Logger LOG = getLogger(SimpleMetricsPublishingService.class);

  private final int port;
  private PrometheusMeterRegistry registry;
  private HttpServer server;

  public SimpleMetricsPublishingService() {
    this(PORT);
  }

  public SimpleMetricsPublishingService(int port) {
    this.port = port;
  }

  @Override
  public void start(MetricsSession session) {
    registry = new PrometheusMeterRegistry(DEFAULT);
    session.addSubregistry(registry);

    InetSocketAddress address = new InetSocketAddress(HOSTNAME, port);
    server = null;
    try {
      server = HttpServer.create(address, 0);
    } catch (IOException thrown) {
      LOG.error("Exception while starting " + getClass().getSimpleName(), thrown);
    }
    HttpContext context = server.createContext("/");
    context.setHandler(this::requestHandler);
    server.start();

    int boundPort = server.getAddress().getPort();
    LOG.info("Started {} http://{}:{}/", getClass().getSimpleName(), HOSTNAME, boundPort);
  }

  private void requestHandler(HttpExchange httpExchange) throws IOException {
    final byte[] scrapeBytes = registry.scrape().getBytes();
    httpExchange.sendResponseHeaders(200, scrapeBytes.length);
    final OutputStream responseBody = httpExchange.getResponseBody();
    responseBody.write(scrapeBytes);
    responseBody.close();
  }

  @Override
  public void stop(MetricsSession session) {
    session.removeSubregistry(registry);
    registry = null;
    server.stop(0);
  }
}

To make your service discoverable, add the following provider-configuration file in the resource directory of your publishing service jar file:

META-INF/services/org.apache.geode.metrics.MetricsPublishingService

Add a line inside the file indicating the fully qualified class name of your implementation:

my.domain.SimpleMetricsPublishingService

Add Your jar File to the classpath When You Start a Server or Locator

To add your metrics publishing service to a server or locator, add your jar file to the classpath when you start the server or locator via GFSH and specify the prometheus.metrics.port listed in SimpleMetricsPublishingService:

gfsh>create locator --name my-locator --classpath=<path-to-my-jar-file>/my.jar --J=-Dprometheus.metrics.port=9914

gfsh>create server --name my-server --classpath=<path-to-my-jar-file>/my.jar --J=-Dprometheus.metrics.port=9915

Alternatively, you can add your jar file to the extensions directory in your Geode installation and only specify the prometheus.metrics.port. Then GFSH will add your jar file to the classpath whenever it creates a server or locator.