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