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(String metricsPath) { 015 String metrics = metricsPath.startsWith("/") ? metricsPath.substring(1) : metricsPath; 016 String responseString = 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 + String.format("The metrics path is <a href=\"%s\">%s</a>.\n", metrics, metricsPath) 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 + String.format( 028 "<li><a href=\"%s?name[]=my_metric\">%s?name[]=my_metric</a></li>\n", 029 metrics, metricsPath) 030 + "</ul>\n" 031 + "You can also use multiple <tt>name[]</tt> parameters to query multiple metrics:\n" 032 + "<ul>\n" 033 + String.format("<li><a href=\"%s?name[]=my_metric_a&name[]=my_metric_b\">", metrics) 034 + String.format("%s?name[]=my_metric_a&name[]=my_metric_b</a></li>\n", metricsPath) 035 + "</ul>\n" 036 + "The <tt>name[]</tt> parameter can be used by the Prometheus server for scraping. " 037 + "Add the following snippet to your scrape job configuration in " 038 + "<tt>prometheus.yaml</tt>:\n" 039 + "<pre>\n" 040 + "params:\n" 041 + " name[]:\n" 042 + " - my_metric_a\n" 043 + " - my_metric_b\n" 044 + "</pre>\n" 045 + "<h2>Debug Parameter</h2>\n" 046 + "The Prometheus Java metrics library supports multiple exposition formats.\n" 047 + "The Prometheus server sends the <tt>Accept</tt> header " 048 + "to indicate which format it accepts.\n" 049 + "By default, the Prometheus server accepts OpenMetrics text format, " 050 + "unless the Prometheus server is started with feature flag " 051 + "<tt>--enable-feature=native-histograms</tt>,\n" 052 + "in which case the default is Prometheus protobuf.\n" 053 + "The Prometheus Java metrics library supports a <tt>debug</tt> query parameter " 054 + "for viewing the different formats in a Web browser:\n" 055 + "<ul>\n" 056 + String.format( 057 "<li><a href=\"%s?debug=openmetrics\">%s?debug=openmetrics</a>: ", 058 metrics, metricsPath) 059 + "View OpenMetrics text format.</li>\n" 060 + String.format( 061 "<li><a href=\"%s?debug=text\">%s?debug=text</a>: ", metrics, metricsPath) 062 + "View Prometheus text format (this is the default when accessing the " 063 + String.format( 064 "<a href=\"%s\">%s</a> endpoint with a Web browser).</li>\n", metrics, metricsPath) 065 + String.format("<li><a href=\"%s?debug=prometheus-protobuf\">", metrics) 066 + String.format("%s?debug=prometheus-protobuf</a>: ", metricsPath) 067 + "View a text representation of the Prometheus protobuf format.</li>\n" 068 + "</ul>\n" 069 + "Note that the <tt>debug</tt> parameter is only for viewing different formats in a " 070 + "Web browser, it should not be used by the Prometheus server for scraping. " 071 + "The Prometheus server uses the <tt>Accept</tt> " 072 + "header for indicating which format it accepts.\n" 073 + "</body>\n" 074 + "</html>\n"; 075 this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8); 076 this.contentType = "text/html; charset=utf-8"; 077 } 078 079 @Override 080 public void handle(HttpExchange exchange) throws IOException { 081 try { 082 exchange.getResponseHeaders().set("Content-Type", contentType); 083 exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); 084 exchange.sendResponseHeaders(200, responseBytes.length); 085 exchange.getResponseBody().write(responseBytes); 086 } finally { 087 exchange.close(); 088 } 089 } 090}