001package io.prometheus.client; 002 003/** 004 * SimpleTimer, to measure elapsed duration in seconds as a double. 005 * 006 * <p> 007 * This is a helper class intended to measure latencies and encapsulate the conversion to seconds without losing precision. 008 * 009 * <p> 010 * Keep in mind that preferred approaches avoid using this mechanism if possible, since latency metrics broken out by 011 * outcome should be minimized; {@link Summary#startTimer()} and {@link Histogram#startTimer()} are preferred. 012 * Consider moving outcome labels to a separate metric like a counter. 013 * 014 * <p> 015 * Example usage: 016 * <pre> 017 * {@code 018 * class YourClass { 019 * static final Summary requestLatency = Summary.build() 020 * .name("requests_latency_seconds") 021 * .help("Request latency in seconds.") 022 * .labelNames("aLabel") 023 * .register(); 024 * 025 * void processRequest(Request req) { 026 * SimpleTimer requestTimer = new SimpleTimer(); 027 * try { 028 * // Your code here. 029 * } finally { 030 * requestLatency.labels("aLabelValue").observe(requestTimer.elapsedSeconds()); 031 * } 032 * } 033 * } 034 * } 035 * </pre> 036 * 037 */ 038public class SimpleTimer { 039 private final long start; 040 static TimeProvider defaultTimeProvider = new TimeProvider(); 041 private final TimeProvider timeProvider; 042 043 static class TimeProvider { 044 long nanoTime() { 045 return System.nanoTime(); 046 } 047 } 048 049 // Visible for testing. 050 SimpleTimer(TimeProvider timeProvider) { 051 this.timeProvider = timeProvider; 052 start = timeProvider.nanoTime(); 053 } 054 055 public SimpleTimer() { 056 this(defaultTimeProvider); 057 } 058 059 /** 060 * @return Measured duration in seconds since {@link SimpleTimer} was constructed. 061 */ 062 public double elapsedSeconds() { 063 return elapsedSecondsFromNanos(start, timeProvider.nanoTime()); 064 } 065 066 public static double elapsedSecondsFromNanos(long startNanos, long endNanos) { 067 return (endNanos - startNanos) / Collector.NANOSECONDS_PER_SECOND; 068 } 069}