Rask guide til mikrometer

1. Introduksjon

Mikrometer gir en enkel fasade over instrumenteringsklientene for en rekke populære overvåkingssystemer. Foreløpig støtter den følgende overvåkingssystemer: Atlas, Datadog, Graphite, Ganglia, Influx, JMX og Prometheus.

I denne artikkelen vil vi introdusere den grunnleggende bruken av Micrometer og dens integrering med Spring.

For enkelhets skyld tar vi Micrometer Atlas som et eksempel for å demonstrere de fleste av våre brukstilfeller.

2. Maven avhengighet

Til å begynne med, la oss legge til følgende avhengighet til pom.xml:

 io.mikrometer mikrometer-register-atlas 0.12.0.RELEASE 

Den siste versjonen finner du her.

3. MeterRegistry

I Micrometer, a MeterRegistry er kjernekomponenten som brukes til å registrere målere. Vi kan gjentas over registeret og videreføre beregningene for hver meter, for å generere en tidsserie i backend med kombinasjoner av beregninger og dimensjonsverdier.

Den enkleste formen for registret er SimpleMeterRegistry. Men i de fleste tilfeller bør vi bruke en MeterRegistry eksplisitt designet for vårt overvåkingssystem; for Atlas er det AtlasMeterRegistry.

CompositeMeterRegistry lar flere registre legges til. Det gir en løsning for å publisere applikasjonsberegninger til forskjellige støttede overvåkingssystemer samtidig.

Vi kan legge til noen MeterRegistry nødvendig for å laste opp dataene til flere plattformer:

CompositeMeterRegistry compositeRegistry = ny CompositeMeterRegistry (); SimpleMeterRegistry oneSimpleMeter = ny SimpleMeterRegistry (); AtlasMeterRegistry atlasMeterRegistry = nytt AtlasMeterRegistry (atlasConfig, Clock.SYSTEM); compositeRegistry.add (oneSimpleMeter); compositeRegistry.add (atlasMeterRegistry);

Det er statisk global registerstøtte i Micrometer: Metrics.globalRegistry. Også et sett med statiske byggere basert på dette globale registeret er gitt for å generere målere i Beregninger:

@Test offentlig ugyldighet gittGlobalRegistry_whenIncrementAnywhere_thenCounted () {class CountedObject {private CountedObject () {Metrics.counter ("objects.instance"). Increment (1.0); }} Metrics.addRegistry (ny SimpleMeterRegistry ()); Metrics.counter ("objects.instance"). Inkrement (); nytt CountedObject (); Valgfri counterOptional = Metrics.globalRegistry .find ("objects.instance"). Counter (); assertTrue (counterOptional.isPresent ()); assertTrue (counterOptional.get (). count () == 2.0); }

4. Merker og Meter

4.1. Merker

En identifikator for en Måler består av navn og koder. Det foreslås at vi skal følge en navngivningskonvensjon som skiller ord med en prikk for å garantere bærbarhet av metriske navn på tvers av flere overvåkingssystemer.

Counter counter = registry.counter ("page.visitors", "age", "20s");

Merker kan brukes til å kutte beregningen for å resonnere om verdiene. I koden ovenfor, page.visitors er navnet på måleren, med alder = 20s som taggen. I dette tilfellet er telleren ment å telle besøkende på siden med alderen 20 til 30 år.

For et stort system kan vi legge til vanlige koder i et register, si at beregningene er fra en bestemt region:

registry.config (). commonTags ("region", "ua-øst");

4.2. Disk

EN Disk rapporterer bare en telling over en spesifisert egenskap for en applikasjon. Vi kan bygge en tilpasset teller med den flytende byggmesteren eller hjelpemetoden til enhver MetricRegistry:

Counter counter = Counter .builder ("instance") .description ("indikerer antall forekomster av objektet"). Tagger ("dev", "performance") .register (registry); counter.increment (2.0); assertTrue (counter.count () == 2); counter.increment (-1); assertTrue (counter.count () == 2);

Som det fremgår av utdraget ovenfor, prøvde vi å redusere telleren med ett, men vi kan bare øke telleren monotont med et fast positivt beløp.

4.3. Tidtakere

For å måle ventetid eller hyppighet av hendelser i systemet vårt, kan vi bruke Tidtakere. EN Timer vil rapportere minst den totale tiden og antall hendelser for bestemte tidsserier.

For eksempel kan vi registrere en applikasjonshendelse som kan vare i flere sekunder:

SimpleMeterRegistry-register = nytt SimpleMeterRegistry (); Timer timer = registry.timer ("app.event"); timer.record (() -> {try {TimeUnit.MILLISECONDS.sleep (1500);} catch (InterruptedException ignored) {}}); timer.record (3000, MILLISEKONDER); assertTrue (2 == timer.count ()); assertTrue (4510> timer.totalTime (MILLISECONDS) && 4500 <= timer.totalTime (MILLISECONDS));

For å registrere langvarige hendelser bruker vi LongTaskTimer:

SimpleMeterRegistry-register = nytt SimpleMeterRegistry (); LongTaskTimer longTaskTimer = LongTaskTimer .builder ("3rdPartyService") .register (register); long currentTaskId = longTaskTimer.start (); prøv {TimeUnit.SECONDS.sleep (2); } fangst (InterruptedException ignorert) {} long timeElapsed = longTaskTimer.stop (currentTaskId); assertTrue (timeElapsed / (int) 1e9 == 2);

4.4. Måler

En måler viser gjeldende verdi av en meter.

Annet enn andre målere, Målere skal bare rapportere data når de observeres. Målere kan være nyttig når du overvåker statistikk over hurtigbuffer, samlinger osv .:

SimpleMeterRegistry-register = nytt SimpleMeterRegistry (); Listeliste = ny ArrayList (4); Gauge gauge = Gauge .builder ("cache.size", list, List :: size) .register (registry); assertTrue (gauge.value () == 0.0); list.add ("1"); assertTrue (gauge.value () == 1.0);

4.5. Distribusjon Sammendrag

Distribusjon av hendelser og et enkelt sammendrag er gitt av Distribusjon Sammendrag:

SimpleMeterRegistry-register = nytt SimpleMeterRegistry (); DistributionSummary distributionSummary = DistributionSummary .builder ("request.size") .baseUnit ("bytes") .register (register); distributionSummary.record (3); distributionSummary.record (4); distributionSummary.record (5); assertTrue (3 == distributionSummary.count ()); assertTrue (12 == distributionSummary.totalAmount ());

Videre Distribusjon Sammendrag og Tidtakere kan berikes med kvantiler:

SimpleMeterRegistry-register = nytt SimpleMeterRegistry (); Timer timer = Timer.builder ("test.timer") .kvantiles (WindowSketchQuantiles .quantiles (0.3, 0.5, 0.95) .create ()) .register (registry);

I utdraget over, tre målere med koder kvantil = 0,3, kvantil = 0,5 og kvantil = 0,95 vil være tilgjengelig i registeret, som indikerer verdiene under henholdsvis 95%, 50% og 30% av observasjonene.

For å se disse kvantilene i aksjon, la oss legge til følgende poster:

timer.record (2, TimeUnit.SECONDS); timer.record (2, TimeUnit.SECONDS); timer.record (3, TimeUnit.SECONDS); timer.record (4, TimeUnit.SECONDS); timer.record (8, TimeUnit.SECONDS); timer.record (13, TimeUnit.SECONDS);

Da kan vi verifisere ved å trekke ut verdier i disse tre kvantilene Målere:

Liste quantileGauges = registry.getMeters (). Stream () .filter (m -> m.getType (). Navn (). Tilsvarer ("Gauge")). Kart (meter -> (Gauge) meter) .collect (Collectors (Collectors) .å liste opp()); assertTrue (3 == quantileGauges.size ()); Kart quantileMap = extractTagValueMap (register, Type.Gauge, 1e9); assertThat (quantileMap, allOf (hasEntry ("quantile = 0.3", 2), hasEntry ("quantile = 0.5", 3), hasEntry ("quantile = 0.95", 8)));

Dessuten støtter Micrometer også histogrammer:

DistributionSummary hist = DistributionSummary .builder ("summary"). Histogram (Histogram.linear (0, 10, 5)) .register (register);

I likhet med kvantiler, etter å ha lagt til flere poster, kan vi se at histogram håndterer beregningen ganske bra:

Karthistogrammer = extractTagValueMap (register, Type.Teller, 1.0); assertThat (histogrammer, allOf (hasEntry ("bucket = 0.0", 0), hasEntry ("bucket = 10.0", 2), hasEntry ("bucket = 20.0", 2), hasEntry ("bucket = 30.0", 1), hasEntry ("bucket = 40.0", 1), hasEntry ("bucket = Infinity", 0)));

Generelt kan histogrammer bidra til å illustrere en direkte sammenligning i separate bøtter. Histogrammer kan også tidsskaleres, noe som er ganske nyttig for å analysere responstid for backend-tjenester:

SimpleMeterRegistry-register = nytt SimpleMeterRegistry (); Timer timer = Timer .builder ("timer") .histogram (Histogram.linearTime (TimeUnit.MILLISECONDS, 0, 200, 3)) .register (registry); // ... assertThat (histogrammer, allOf (hasEntry ("bucket = 0.0", 0), hasEntry ("bucket = 2.0E8", 1), hasEntry ("bucket = 4.0E8", 1), hasEntry ("bucket = Uendelig ", 3)));

5. Bindemidler

Mikrometeret har flere innebygde permer for å overvåke JVM, cacher, ExecutorService og loggføringstjenester.

Når det gjelder JVM og systemovervåking, kan vi overvåke klasselaster-beregninger (ClassLoaderMetrics), JVM-minnepool (JvmMemoryMetrics) og GC-beregninger (JvmGcMetrics), tråd og CPU-bruk (JvmThreadMetrics, ProcessorMetrics).

Cache-overvåking (for øyeblikket støttes bare Guava, EhCache, Hazelcast og koffein) støttes av instrumentering med GuavaCacheMetrics, EhCache2Metrics, HazelcastCacheMetrics, og KoffeinCacheMetrics. Og for å overvåke tilbakekoblingstjeneste kan vi binde LogbackMetrics til ethvert gyldig register:

nye LogbackMetrics (). bind (register);

Bruken av ovennevnte permer er ganske lik LogbackMetrics og er ganske enkle, så vi vil ikke dykke ned i ytterligere detaljer her.

6. Vårintegrasjon

Spring Boot Actuator gir avhengighetsstyring og automatisk konfigurasjon for Micrometer. Nå støttes den i Spring Boot 2.0 / 1.x og Spring Framework 5.0 / 4.x.

Vi trenger følgende avhengighet (den siste versjonen finner du her):

 io.mikrometer mikrometer-fjær-arv 0.12.0.RELEASE 

Uten ytterligere endring av eksisterende kode har vi aktivert vårstøtte med mikrometeret. JVM-minnestikk for vår-søknad blir automatisk registrert i det globale registeret og publisert til standard atlasendepunkt: // localhost: 7101 / api / v1 / publish.

Det er flere konfigurerbare egenskaper tilgjengelig for å kontrollere beregninger som eksporterer atferd, og starter med spring.metrics.atlas. *. Sjekk AtlasConfig for å se en fullstendig liste over konfigurasjonsegenskaper for Atlas-publisering.

Hvis vi trenger å binde flere beregninger, bare legg dem til som @Bønne til applikasjonssammenheng.

Si at vi trenger JvmThreadMetrics:

@Bean JvmThreadMetrics threadMetrics () {returner nye JvmThreadMetrics (); }

Når det gjelder nettovervåking, er den automatisk konfigurert for hvert sluttpunkt i applikasjonen vår, men likevel håndterbar via en konfigurasjonsegenskap: spring.metrics.web.autoTimeServerRequests.

Standardimplementeringen gir fire dimensjoner av beregninger for endepunkter: HTTP-forespørselsmetode, HTTP-svarskode, endepunkt URI og unntaksinformasjon.

Når forespørsler blir besvart, målinger angående forespørselsmetoden (, POSTosv.) vil bli publisert i Atlas.

Med Atlas Graph API kan vi generere en graf for å sammenligne responstiden for forskjellige metoder:

Som standard er responskoder for 20x, 30x, 40x, 50x vil også bli rapportert:

Vi kan også sammenligne forskjellige URI-er:

eller sjekk unntaksberegninger:

Merk at vi også kan bruke @Timed på kontrollerklassen eller spesifikke endepunktsmetoder for å tilpasse koder, lang oppgave, kvantiler og persentiler av beregningene:

@RestController @Timed ("people") offentlig klasse PeopleController {@GetMapping ("/ people") @Timed (value = "people.all", longTask = true) offentlig Liste listePeople () {// ...}}

Basert på koden ovenfor, kan vi se følgende tagger ved å sjekke Atlas sluttpunkt // localhost: 7101 / api / v1 / tags / name:

["folk", "folk.all", "jvmBufferCount", ...]

Micrometer fungerer også i funksjonen web framework innført i Spring Boot 2.0. Beregninger kan aktiveres ved å filtrere RouterFunction:

RouterFunctionMetrics metrics = nye RouterFunctionMetrics (register); RouterFunctions.route (...) .filter (metrics.timer ("server.requests"));

Målinger fra datakilden og planlagte oppgaver kan også samles inn. Sjekk den offisielle dokumentasjonen for mer informasjon.

7. Konklusjon

I denne artikkelen introduserte vi beregningsfasaden Micrometer. Ved å abstrahere bort og støtte flere overvåkingssystemer under vanlig semantikk, gjør verktøyet det enkelt å bytte mellom forskjellige overvåkingsplattformer.

Som alltid kan du finne den fulle implementeringskoden for denne artikkelen på Github.


$config[zx-auto] not found$config[zx-overlay] not found