001package io.prometheus.metrics.exporter.httpserver;
002
003import com.sun.net.httpserver.HttpExchange;
004import com.sun.net.httpserver.HttpHandler;
005import java.io.IOException;
006import java.nio.charset.StandardCharsets;
007
008/** Handler for the / endpoint */
009public class DefaultHandler implements HttpHandler {
010
011  private final byte[] responseBytes;
012  private final String contentType;
013
014  public DefaultHandler() {
015    String responseString =
016        ""
017            + "<html>\n"
018            + "<head><title>Prometheus Java Client</title></head>\n"
019            + "<body>\n"
020            + "<h1>Prometheus Java Client</h1>\n"
021            + "<h2>Metrics Path</h2>\n"
022            + "The metrics path is <a href=\"metrics\">/metrics</a>.\n"
023            + "<h2>Name Filter</h2>\n"
024            + "If you want to scrape only specific metrics, "
025            + "use the <tt>name[]</tt> parameter like this:\n"
026            + "<ul>\n"
027            + "<li><a href=\"metrics?name[]=my_metric\">/metrics?name[]=my_metric</a></li>\n"
028            + "</ul>\n"
029            + "You can also use multiple <tt>name[]</tt> parameters to query multiple metrics:\n"
030            + "<ul>\n"
031            + "<li><a href=\"metrics?name[]=my_metric_a&name=my_metrics_b\">"
032            + "/metrics?name[]=my_metric_a&amp;name=[]=my_metric_b</a></li>\n"
033            + "</ul>\n"
034            + "The <tt>name[]</tt> parameter can be used by the Prometheus server for scraping. "
035            + "Add the following snippet to your scrape job configuration in "
036            + "<tt>prometheus.yaml</tt>:\n"
037            + "<pre>\n"
038            + "params:\n"
039            + "    name[]:\n"
040            + "        - my_metric_a\n"
041            + "        - my_metric_b\n"
042            + "</pre>\n"
043            + "<h2>Debug Parameter</h2>\n"
044            + "The Prometheus Java metrics library supports multiple exposition formats.\n"
045            + "The Prometheus server sends the <tt>Accept</tt> header "
046            + "to indicate which format it accepts.\n"
047            + "By default, the Prometheus server accepts OpenMetrics text format, "
048            + "unless the Prometheus server is started with feature flag "
049            + "<tt>--enable-feature=native-histograms</tt>,\n"
050            + "in which case the default is Prometheus protobuf.\n"
051            + "The Prometheus Java metrics library supports a <tt>debug</tt> query parameter "
052            + "for viewing the different formats in a Web browser:\n"
053            + "<ul>\n"
054            + "<li><a href=\"metrics?debug=openmetrics\">/metrics?debug=openmetrics</a>: "
055            + "View OpenMetrics text format.</li>\n"
056            + "<li><a href=\"metrics?debug=text\">/metrics?debug=text</a>: "
057            + "View Prometheus text format (this is the default when accessing the "
058            + "<a href=\"metrics\">/metrics</a> endpoint with a Web browser).</li>\n"
059            + "<li><a href=\"metrics?debug=prometheus-protobuf\">"
060            + "/metrics?debug=prometheus-protobuf</a>: "
061            + "View a text representation of the Prometheus protobuf format.</li>\n"
062            + "</ul>\n"
063            + "Note that the <tt>debug</tt> parameter is only for viewing different formats in a "
064            + "Web browser, it should not be used by the Prometheus server for scraping. "
065            + "The Prometheus server uses the <tt>Accept</tt> "
066            + "header for indicating which format it accepts.\n"
067            + "</body>\n"
068            + "</html>\n";
069    this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8);
070    this.contentType = "text/html; charset=utf-8";
071  }
072
073  @Override
074  public void handle(HttpExchange exchange) throws IOException {
075    try {
076      exchange.getResponseHeaders().set("Content-Type", contentType);
077      exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length));
078      exchange.sendResponseHeaders(200, responseBytes.length);
079      exchange.getResponseBody().write(responseBytes);
080    } finally {
081      exchange.close();
082    }
083  }
084}