Core instrumentation library for the Prometheus Java client, providing fundamental metric types for application monitoring
—
Summary metrics track quantiles and distributions with configurable sliding time windows and precise quantile calculations. They provide count, sum, and quantile values without requiring predefined buckets like histograms.
Create summary metrics using the builder pattern with optional quantile configuration.
/**
* Create a new Summary builder
* @return Builder instance for configuration
*/
public static Summary.Builder build();
/**
* Create a new Summary builder with required fields
* @param name The metric name (without _count/_sum suffixes)
* @param help The help text describing the metric
* @return Builder instance for configuration
*/
public static Summary.Builder build(String name, String help);Usage Example:
import io.prometheus.client.Summary;
// Basic summary (count and sum only)
Summary requestLatency = Summary.build()
.name("request_latency_seconds")
.help("Request latency in seconds")
.register();
// Summary with quantiles
Summary responseTime = Summary.build()
.name("response_time_seconds")
.help("Response time distribution")
.quantile(0.5, 0.01) // 50th percentile ±1%
.quantile(0.95, 0.005) // 95th percentile ±0.5%
.quantile(0.99, 0.001) // 99th percentile ±0.1%
.register();Configure summary quantiles, time windows, and sampling parameters.
public static class Builder extends SimpleCollector.Builder<Builder, Summary> {
/**
* Add a quantile to track with specified error tolerance
* @param quantile Quantile to track (0.0 to 1.0)
* @param error Allowed error for quantile calculation
* @return Builder for method chaining
* @throws IllegalArgumentException if quantile not in [0,1] or error negative
*/
public Builder quantile(double quantile, double error);
/**
* Set the maximum age of observations in seconds
* @param ageSeconds Age in seconds (default: 600)
* @return Builder for method chaining
*/
public Builder maxAgeSeconds(long ageSeconds);
/**
* Set number of age buckets for sliding time window
* @param ageBuckets Number of buckets (default: 5)
* @return Builder for method chaining
*/
public Builder ageBuckets(int ageBuckets);
}Usage Examples:
// High-precision summary with custom time window
Summary preciseLatency = Summary.build()
.name("precise_latency_seconds")
.help("High precision latency tracking")
.quantile(0.50, 0.01) // Median ±1%
.quantile(0.90, 0.005) // 90th percentile ±0.5%
.quantile(0.95, 0.005) // 95th percentile ±0.5%
.quantile(0.99, 0.001) // 99th percentile ±0.1%
.maxAgeSeconds(300) // 5-minute window
.ageBuckets(5) // 5 buckets = 1 minute each
.register();
// Min/max tracking (special cases with zero error)
Summary minMax = Summary.build()
.name("processing_duration_seconds")
.help("Processing duration with min/max")
.quantile(0.0, 0.0) // Minimum (no extra memory)
.quantile(1.0, 0.0) // Maximum (no extra memory)
.quantile(0.5, 0.01) // Median ±1%
.register();Record values in summary metrics for quantile and statistical calculations.
/**
* Record an observation in the summary
* @param amt Value to observe
*/
public void observe(double amt);Usage Examples:
// Basic observations
requestLatency.observe(0.123); // 123ms request
responseTime.observe(0.045); // 45ms response
responseTime.observe(1.234); // 1.234s slower response
// Processing different types of operations
Summary operationDuration = Summary.build()
.name("operation_duration_seconds")
.help("Operation processing time")
.labelNames("operation_type")
.quantile(0.5, 0.01)
.quantile(0.95, 0.005)
.register();
operationDuration.labels("database_query").observe(0.025);
operationDuration.labels("file_write").observe(0.150);
operationDuration.labels("network_call").observe(0.300);Use summaries for automatic duration measurement and timing operations.
/**
* Start a timer for duration measurement
* @return Timer instance for duration tracking
*/
public Timer startTimer();
/**
* Time a Runnable execution and observe duration
* @param timeable Code to time
* @return Duration in seconds
*/
public double time(Runnable timeable);
/**
* Time a Callable execution and observe duration
* @param timeable Code to time
* @return Result from callable
* @throws RuntimeException if callable throws exception
*/
public <E> E time(Callable<E> timeable);Timer provides duration measurement capabilities for summary metrics.
public static class Timer implements Closeable {
/**
* Observe elapsed duration since timer start
* @return Elapsed duration in seconds
*/
public double observeDuration();
/**
* Equivalent to observeDuration() - implements Closeable
*/
public void close();
}Usage Examples:
// Manual timer usage
Summary.Timer timer = requestLatency.startTimer();
try {
processRequest();
} finally {
double duration = timer.observeDuration();
System.out.println("Request took: " + duration + " seconds");
}
// Try-with-resources timer
try (Summary.Timer timer = requestLatency.startTimer()) {
processRequest(); // Automatically observes duration on close
}
// Lambda timing
double duration = requestLatency.time(() -> {
processRequest();
});
// Timing with return value
String result = requestLatency.time(() -> {
return generateResponse();
});
// Batch processing timing
Summary batchProcessing = Summary.build()
.name("batch_processing_seconds")
.help("Batch processing duration")
.quantile(0.5, 0.01)
.quantile(0.95, 0.005)
.register();
List<String> results = batchProcessing.time(() -> {
return processBatch();
});Work with multi-dimensional summaries using label values.
/**
* Get summary child for specific label values
* @param labelValues Values for each label name (must match count)
* @return Summary.Child instance for the label combination
* @throws IllegalArgumentException if wrong number of labels
*/
public Summary.Child labels(String... labelValues);
/**
* Remove summary child for specific label values
* @param labelValues Values identifying the child to remove
*/
public void remove(String... labelValues);
/**
* Remove all summary children
*/
public void clear();Summary.Child provides the same observation and timing operations for labeled instances.
public static class Child {
/** Record observation in child summary */
public void observe(double amt);
/** Start timer for child summary */
public Timer startTimer();
/** Time operations for child summary */
public double time(Runnable timeable);
public <E> E time(Callable<E> timeable);
/** Get summary data snapshot */
public Value get();
}Access summary count, sum, and quantile data.
public static class Value {
/** Total number of observations */
public final long count;
/** Sum of all observed values */
public final double sum;
/** Map of quantile values (quantile -> value) */
public final SortedMap<Double, Double> quantiles;
}Usage Example:
// API endpoint monitoring
Summary apiLatency = Summary.build()
.name("api_endpoint_duration_seconds")
.help("API endpoint response time")
.labelNames("endpoint", "method", "status")
.quantile(0.5, 0.01) // Median
.quantile(0.95, 0.005) // 95th percentile
.quantile(0.99, 0.001) // 99th percentile
.register();
// Track different endpoints
Summary.Child getUserLatency = apiLatency.labels("/users", "GET", "200");
Summary.Child postUserLatency = apiLatency.labels("/users", "POST", "201");
// Time requests
getUserLatency.time(() -> handleGetUser());
postUserLatency.observe(0.156); // Manual observation
// Access summary statistics
Summary.Child.Value stats = getUserLatency.get();
System.out.println("Total requests: " + stats.count);
System.out.println("Average latency: " + (stats.sum / stats.count));
System.out.println("95th percentile: " + stats.quantiles.get(0.95));Quantile Range: Must be between 0.0 and 1.0
0.0 = minimum value (special case, no extra memory)0.5 = median (50th percentile)0.95 = 95th percentile0.99 = 99th percentile1.0 = maximum value (special case, no extra memory)Error Tolerance: Controls precision vs memory usage
0.01 = ±1% error (good for most use cases)0.005 = ±0.5% error (higher precision)0.001 = ±0.1% error (very high precision)0.0 = exact tracking (uses more memory)Summary uses a sliding time window:
maxAgeSeconds / ageBuckets intervalExample with defaults:
Use Summary when:
Use Histogram when:
// SLA monitoring
Summary slaLatency = Summary.build()
.name("sla_response_time_seconds")
.help("Response time for SLA monitoring")
.quantile(0.95, 0.01) // 95% of requests under X seconds
.quantile(0.99, 0.005) // 99% of requests under Y seconds
.maxAgeSeconds(300) // 5-minute sliding window
.register();
// Database query performance
Summary dbQueries = Summary.build()
.name("database_query_duration_seconds")
.help("Database query performance")
.labelNames("query_type", "table")
.quantile(0.5, 0.01) // Median
.quantile(0.9, 0.005) // 90th percentile
.quantile(0.99, 0.001) // 99th percentile
.register();
// Batch processing monitoring
Summary batchJobs = Summary.build()
.name("batch_job_duration_seconds")
.help("Batch job processing time")
.labelNames("job_type")
.quantile(0.0, 0.0) // Minimum (free)
.quantile(0.5, 0.01) // Median
.quantile(1.0, 0.0) // Maximum (free)
.register();Install with Tessl CLI
npx tessl i tessl/maven-io-prometheus--simpleclient