Gauge

A Gauge is a handle to the current metric record value, that is, it represents a single numerical Meter that can float up and down at will. Gauge is typically used for changing measurements, such as current memory usage, set with the return value of the ToDoubleFunction parameter, as well as for “counts” that move up and down, such as the number of messages in the queue.

Typical use scenarios for Gauge mentioned in the official documentation are for measuring the size of collections or maps or the number of threads in a running state. Gauge is used to monitor events or tasks with natural upper bounds, while Counter is used to monitor events or tasks with no natural upper bounds, so you should use Counter instead of Gauge for things like total Http requests.

MeterRegistry provides some easy ways to build Gauge related methods for observing values, functions, collections, and maps: List list = registry.gauge(“listGauge”, Collections.emptyList(), new ArrayList<>(), List::size); List list2 = registry.gaugeCollectionSize(“listSize2”, Tags.empty(), new ArrayList<>()); Map<String, Integer> map = registry.gaugeMapSize(“mapGauge”, Tags.empty(), new HashMap<>()); The above three methods build Gauge through MeterRegistry and return collections or mapping instances that can be used to record the change value as its size changes. The more important advantage is that we don’t need to be aware of the presence of the Gauge interface, just use collections or map instances as we would normally.

In addition, the Gauge support Java. Lang. Number of subclasses, Java. Util. Concurrent. The atomic AtomicInteger in the package and AtomicLong, and Guava AtomicDouble offers: AtomicInteger n = registry.gauge(“numberGauge”, new AtomicInteger(0)); n.set(1); n.set(2);

In addition to using MeterRegistry to create gauges, you can also create gauges using the Builder stream: Gauge = Gauge. Builder (” Gauge “, myObj, MyObj ::gaugeValue. Description (“a description of what this gauge does”) // Optional. Tags (“region”, “Test “) // Optional. Register (registry);

Usage Scenarios:

Based on personal experience and practice, the conclusions are as follows:

Monitoring of floating values with natural (physical) upper bounds, such as physical memory, collections, maps, values, etc. Monitoring of logically bounded floating values, such as backlogged messages, backlogged tasks (in thread pools), is essentially monitoring of collections or maps.

For a more practical example, suppose you want to send a message or push to a logged-in user. The message is placed on a blocking queue and a thread consumes the message for other operations: Public Class GaugeMain {

private static final MeterRegistry MR = new SimpleMeterRegistry();
private static final BlockingQueue<Message> QUEUE = new ArrayBlockingQueue<>(500);
private static BlockingQueue<Message> REAL_QUEUE;

    static {
        REAL_QUEUE = MR.gauge("messageGauge", QUEUE, Collection::size);
    }

    public static void main(String[] args) throws Exception {
        consume();
        Message message = new Message();
        message.setUserId(1L);
        message.setContent("content");
        REAL_QUEUE.put(message);
    }

    private static void consume() throws Exception {
        new Thread(() -> {
            while (true) {
                try {
                    Message message = REAL_QUEUE.take();
                    //handle message
                    System.out.println(message);
                } catch (InterruptedException e) {
                    //no-op
                }
            }
        }).start();
    }
Copy the code

}

The above example is poorly written and is intended to demonstrate its use. Do not use it in a production environment.

TimeGauge

TimeGauge is a specialization of Gauge. Compared to Gauge, the constructor has a TimeUnit parameter that specifies the base TimeUnit for the ToDoubleFunction entry. Public class TimeGaugeMain {public class TimeGaugeMain {

private static final SimpleMeterRegistry R = new SimpleMeterRegistry(); public static void main(String[] args) throws Exception{ AtomicInteger count = new AtomicInteger(); TimeGauge.Builder<AtomicInteger> timeGauge = TimeGauge.builder("timeGauge", count, TimeUnit.SECONDS, AtomicInteger::get); timeGauge.register(R); count.addAndGet(10086); print(); count.set(1); print(); } private static void print()throws Exception{ Search.in(R).meters().forEach(each -> { StringBuilder builder = new StringBuilder(); builder.append("name:") .append(each.getId().getName()) .append(",tags:") .append(each.getId().getTags()) .append(",type:").append(each.getId().getType()) .append(",value:").append(each.measure()); System.out.println(builder.toString()); }); }}Copy the code

Name: / / output timeGauge, tags: [], type: the GAUGE, the value: [Measurement {statistic = ‘value’, Name: value = 10086.0}] timeGauge, tags: [], type: the GAUGE, value: [Measurement {statistic = ‘value’, value = 1.0}]

DistributionSummary

Summary is primarily used to track the distribution of events, and in Micrometer, the corresponding class is DistributionSummary. It is used in much the same way as a Timer, but its recorded values do not depend on time units.

A common usage scenario: Use DistributionSummary to measure the payload size of requests hitting the server. Create a DistributionSummary instance with MeterRegistry as follows: DistributionSummary summary = registry. Summary (“response.size”); Create the following by builder stream: DistributionSummary summary = DistributionSummary .builder(“response.size”) .description(“a description of what this Summary does”) // Optional. BaseUnit (“bytes”) // Optional. Tags (“region”, “test”) // Optional.scale(100) // Optional.

Many of the build parameters in DistributionSummary are related to scaling and histogram representation, as shown in the next section.