001package io.prometheus.metrics.core.datapoints; 002 003import io.prometheus.metrics.model.snapshots.Labels; 004 005/** 006 * Represents a single counter data point, i.e. a single line for a counter metric in Prometheus 007 * text format. 008 * 009 * <p>Example usage: 010 * 011 * <pre>{@code 012 * Counter counter = Counter.builder() 013 * .name("tasks_total") 014 * .labelNames("status") 015 * .register(); 016 * CounterDataPoint newTasks = counter.labelValues("new"); 017 * CounterDataPoint pendingTasks = counter.labelValues("pending"); 018 * CounterDataPoint completedTasks = counter.labelValues("completed"); 019 * }</pre> 020 * 021 * <p>Using {@code DataPoint} directly improves performance. If you increment a counter like this: 022 * 023 * <pre>{@code 024 * counter.labelValues("pending").inc(); 025 * }</pre> 026 * 027 * the label value {@code "pending"} needs to be looked up every single time. Using the {@code 028 * CounterDataPoint} like this: 029 * 030 * <pre>{@code 031 * CounterDataPoint pendingTasks = counter.labelValues("pending"); 032 * pendingTasks.inc(); 033 * }</pre> 034 * 035 * allows you to look up the label value only once, and then use the {@code CounterDataPoint} 036 * directly. This is a worthwhile performance improvement when instrumenting a performance-critical 037 * code path. 038 * 039 * <p>If you have a counter without labels like this: 040 * 041 * <pre>{@code 042 * Counter counterWithoutLabels = Counter.builder() 043 * .name("events_total") 044 * .register(); 045 * }</pre> 046 * 047 * You can use it as a {@code CounterDataPoint} directly. So the following: 048 * 049 * <pre>{@code 050 * CounterDataPoint counterData = counterWithoutLabels.labelValues(); // empty label values 051 * }</pre> 052 * 053 * is equivalent to 054 * 055 * <pre>{@code 056 * CounterDataPoint counterData = counterWithoutLabels; 057 * }</pre> 058 */ 059public interface CounterDataPoint extends DataPoint { 060 061 /** Add one. */ 062 default void inc() { 063 inc(1L); 064 } 065 066 /** 067 * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. 068 */ 069 default void inc(long amount) { 070 inc((double) amount); 071 } 072 073 /** 074 * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. 075 */ 076 void inc(double amount); 077 078 /** Add one, and create a custom exemplar with the given labels. */ 079 default void incWithExemplar(Labels labels) { 080 incWithExemplar(1.0, labels); 081 } 082 083 /** 084 * Add {@code amount}, and create a custom exemplar with the given labels. Throws an {@link 085 * IllegalArgumentException} if {@code amount} is negative. 086 */ 087 default void incWithExemplar(long amount, Labels labels) { 088 inc((double) amount); 089 } 090 091 /** 092 * Add {@code amount}, and create a custom exemplar with the given labels. Throws an {@link 093 * IllegalArgumentException} if {@code amount} is negative. 094 */ 095 void incWithExemplar(double amount, Labels labels); 096 097 /** Get the current value. */ 098 double get(); 099 100 /** Get the current value as a {@code long}. Decimal places will be discarded. */ 101 long getLongValue(); 102}