5 Ocak 2021 Salı

Micrometer ile Metrik Yazmak

Giriş
Metric'leri loglamak için io.micrometer.core.instrument.logging.LoggingMeterRegistry sınıfı kullanılır. Açıklaması şöyle
To be able to send custom metrics we need to import MeterRegistry from the Micrometer library and inject it into our class. 

It is possible to instantiate these types of meters from MeterRegistry:
- Counter: reports merely a count over a specified property of an application
- Gauge: shows the current value of a meter
- Timers: measures latencies or frequency of events
- DistributionSummary: provides distribution of events and a simple summary
Counter vs. gauge, summary vs. histogram yazısına bakabilirsiniz

Gradle
Şöyle yaparız
implementation 'org.springframework.boot:spring-boot-starter-actuator:2.6.3'
implementation 'io.micrometer:micrometer-registry-atlas:1.8.2'
implementation 'io.micrometer:micrometer-registry-prometheus:1.8.2'
MeterRegistryCustomizer Sınıfı
Örnek
Şöyle yaparız
@Configuration
public class MicroSvcMeterRegistryConfig {
  @Value("${spring.application.name}")
  String appName;

  @Value("${env}")
  String environment;

  @Value("${instanceId}")
  String instanceId;

  @Bean
  MeterRegistryCustomizer<PrometheusMeterRegistry> configureMetricsRegistry() {
    return registry -> registry.config()
      .commonTags("appName", appName, 
                  "env", environment, 
                   "instanceId", instanceId);
  }
}
@TimedAspect Anotasyonu
Örnek
Şöyle yaparız
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.MeterRegistry;

@Configuration
public class RegistryConfig {
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
  return registry -> registry.config().commonTags("region", "someRegionName");
  }
  
  @Bean
  TimedAspect timedAspect(MeterRegistry registry) {
    return new TimedAspect(registry);
  }
}
@Timed Anotasyonu
Açıklaması şöyle
The quickest and easiest way to instrument REST controllers is to use the @Timed annotation on the controller or on individual methods of the controller. @Timed automatically adds these tags to the timer: exception, method, outcome, status, uri. It is also possible to supply additional tags to the @Timed annotation.

extraTags Alanı
Örnek
Şöyle yaparız
import io.micrometer.annotation.Timed;

@Slf4j
@RestController
public class DemoController {
  @GetMapping("/push-log")
  @ResponseStatus(HttpStatus.NO_CONTENT)
  @Timed(extraTags = {"demo-tag", "test-val"})
  public void pushLog() {
    log.debug("...");
  }
}
percentiles Alanı
Açıklaması şöyle
The '@Timed' annotation tells mirometer to record the percentiles of the method run times.
Şöyle yaparız
@Scheduled(cron = "0 10 2 ? * ?")
@SchedulerLock(name = "coinbase_avg_scheduledTask", 
        lockAtLeastFor = "PT1M", lockAtMostFor = "PT23H")
@Timed(value = "create.cb.avg", percentiles = { 0.5, 0.95, 0.99 })
public void createCbHAvg() {
  this.coinbaseService.createCbAvg();
}
MeterRegistry Sınıfı
Şu satırı dahil ederiz
import io.micrometer.core.instrument.MeterRegistry;
counter metodu - Sayaç
Counter nesnesi döndürür.

gauge metodu
gauge().set() şeklinde kullanılır
Örnek
Şöyle yaparız
@Component
public class Scheduler {

  private final AtomicInteger testGauge;
  private final Counter testCounter;

  public Scheduler(MeterRegistry meterRegistry) {
    testGauge = meterRegistry.gauge("custom_gauge", new AtomicInteger(0));
    testCounter = meterRegistry.counter("custom_counter");
  }

  @Scheduled(fixedRateString = "1000", initialDelayString = "0")
  public void schedulingTask() {
    testGauge.set(Scheduler.getRandomNumberInRange(0, 100));

    testCounter.increment();
  }

  private static int getRandomNumberInRange(int min, int max) {
    if (min >= max) {
      throw new IllegalArgumentException("max must be greater than min");
    }

    Random r = new Random();
    return r.nextInt((max - min) + 1) + min;
  }
}
Counter Sınıfı
Şu satırı dahil ederiz
import io.micrometer.core.instrument.Counter;
increment metodu

Örnek
Şöyle yaparız
import io.micrometer.core.instrument.MeterRegistry;

@RestController
@RequestMapping("/")
public class PrometheusSpringBoot {

  private final MeterRegistry meterRegistry;

  public PrometheusSpringBoot(MeterRegistry meterRegistry) {
    this.meterRegistry = meterRegistry;
  }

  @GetMapping("/2xx")
  public String simulate2xxResponse() {
    meterRegistry.counter("orders.2xx","status","OK").increment();
    return "...";
  }

  @GetMapping("/5xx")
  public String simulate5xxResponse() {
    meterRegistry.counter("orders.5xx","status","NOTOK").increment();
    return "...";
  }
  @PostMapping("/alert-hook")
  public void receiveAlertHook(@RequestBody Map request) throws Exception {
    System.out.println(request);
  }
}
Örnek
Şöyle yaparız
import io.micrometer.core.instrument.MeterRegistry;

@GetMapping("/2xx")
public String simulate2xxResponse() {
  meterRegistry.counter("orders.2xx","status","OK").increment();
  return "Got 2xx Response";
}
Örnek
Şöyle yaparız
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Scheduler {

  private final AtomicInteger testGauge;
  private final Counter testCounter;

  public Scheduler(MeterRegistry meterRegistry) {
    testGauge = meterRegistry.gauge("custom_gauge", new AtomicInteger(0));
    testCounter = meterRegistry.counter("custom_counter");
  }

  @Scheduled(fixedDelay=1000) // delay per 1 seconds
  public void schedulingTask() {
    testGauge.set(Scheduler.getRandomNumberInRange(0, 100));

    testCounter.increment();
  }

  private static int getRandomNumberInRange(int min, int max) {
    if (min >= max) {
      throw new IllegalArgumentException("max must be greater than min");
    }

    Random r = new Random();
    return r.nextInt((max - min) + 1) + min;
  }
}

Hiç yorum yok:

Yorum Gönder