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