001package io.prometheus.metrics.core.datapoints; 002 003import java.util.concurrent.Callable; 004import java.util.function.Supplier; 005 006/** 007 * Convenience API for timing durations. 008 * <p> 009 * Durations are recorded in seconds. The Prometheus instrumentation guidelines <a href="https://prometheus.io/docs/instrumenting/writing_exporters/#naming">say</a>: 010 * <i>"Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools".</i> 011 */ 012public interface TimerApi { 013 014 /** 015 * Start a {@code Timer}. Example: 016 * <pre>{@code 017 * Histogram histogram = Histogram.builder() 018 * .name("http_request_duration_seconds") 019 * .help("HTTP request service time in seconds") 020 * .unit(SECONDS) 021 * .labelNames("method", "path") 022 * .register(); 023 * 024 * try (Timer timer = histogram.labelValues("GET", "/").startTimer()) { 025 * // duration of this code block will be observed. 026 * } 027 * }</pre> 028 * Durations are recorded in seconds. The Prometheus instrumentation guidelines <a href="https://prometheus.io/docs/instrumenting/writing_exporters/#naming">say</a>: 029 * <i>"Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools".</i> 030 */ 031 Timer startTimer(); 032 033 /** 034 * Observe the duration of the {@code func} call. Example: 035 * <pre>{@code 036 * Histogram histogram = Histogram.builder() 037 * .name("request_duration_seconds") 038 * .help("HTTP request service time in seconds") 039 * .unit(SECONDS) 040 * .labelNames("method", "path") 041 * .register(); 042 * 043 * histogram2.labelValues("GET", "/").time(() -> { 044 * // duration of this code block will be observed. 045 * }); 046 * }</pre> 047 * <p> 048 * Durations are recorded in seconds. The Prometheus instrumentation guidelines <a href="https://prometheus.io/docs/instrumenting/writing_exporters/#naming">say</a>: 049 * <i>"Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools".</i> 050 */ 051 default void time(Runnable func) { 052 try (Timer timer = startTimer()) { 053 func.run(); 054 } 055 } 056 057 /** 058 * Like {@link #time(Runnable)}, but returns the return value of {@code func}. 059 */ 060 default <T> T time(Supplier<T> func) { 061 try (Timer timer = startTimer()) { 062 return func.get(); 063 } 064 } 065 066 /** 067 * Like {@link #time(Supplier)}, but {@code func} may throw a checked {@code Exception}. 068 */ 069 default <T> T timeChecked(Callable<T> func) throws Exception { 070 try (Timer timer = startTimer()) { 071 return func.call(); 072 } 073 } 074}