SlideShare a Scribd company logo
Erin Schnabel @ebullientworks
Know Your (Java) App
Collect metrics with Micrometer
What makes a system (or service) observable?
Workload routing


System health
Service-centric


problem determination
Context + relationships


for end–to-end analysis
Statistics & trends


Analytics
Service is ready


Service is not a zombie
How many times was


method x called?
Method x was called
What happened when


method x was called
Health Checks Distributed Trace
Metrics Log Entries
Metrics: Time series data
How does data change over time?
• Time is the x-axis


• Data collected at regular intervals


• Each measured value appended to the end of a series


• Used for trend analysis, anomaly detection, alerting


Not for debugging, diagnostics, or root cause analysis
Metrics: Dimensions
Filtered/Selective aggregation
http_server_requests_seconds_count{


env="test",


method="GET",


outcome="SUCCESS",


status="200",


uri="/example/prime/{number}",} 5.0


Cardinality: Each unique combination (name & all tag/values) is its own time series
What is Micrometer?
https://micrometer.io -- Open Source metrics library
"Screw gauge" micrometer
Developer API
• Obtain a MeterRegistry


• Create a Meter (name + tag=value combination)


Gauge


Counter


Timer


DistributionSummary
FunctionCounter


FunctionTimer, LongTaskTimer
Counter: increase only → .increment()
1. registry.counter("example.prime.number", "type", "prime");


2. Counter.builder("counter")


.baseUnit("beans")
/
/
optional


.description("a description")
/
/
optional


.tags("region", "test")
/
/
optional


.register(registry);


3. @Counted(value = "metric.all", extraTags = { "region", "test" })
*
*
Timer → .record(duration)
1. registry.timer("my.timer", "region", "test");


2. Timer.builder("my.timer")


.description("description ")
/
/
optional


.tags("region", "test")
/
/
optional


.register(registry);


3. @Timed(value = "call", extraTags = {"region", "test"})
*
*
Working with Timers
1. timer.record(()
-
>
noReturnValue());


2. timer.recordCallable(()
-
>
returnValue());


3. Runnable r = timer.wrap(()
-
>
noReturnValue());


4. Callable c = timer.wrap(()
-
>
returnValue());


5. Sample s = Timer.start(registry); doStuff; s.stop(timer);
Gauge: increase/decrease, observed value
1. List<String> list = registry.gauge("list.size", Tags.of(
.
.
.
),


new ArrayList
<
>
(), List
:
:
size);


2. Gauge.builder("jvm.threads.peak", threadBean, ThreadMXBean
:
:
getPeakThreadCount)


.tags("region", "test")


.description("The peak live thread count
.
.
.
")


.baseUnit(BaseUnits.THREADS)


.register(registry);
FunctionCounter: gauge-like, counter function
1. registry.more().counter(
.
.
.
)


2. FunctionCounter.builder("hibernate.transactions", statistics,


s
-
>
s.getTransactionCount() - s.getSuccessfulTransactionCount())


.tags("entityManagerFactory", sessionFactoryName)


.tags("result", "failure")


.description("The number of transactions we know to have failed")


.register(registry);
FunctionTimer: gauge-like, counter & duration function
1. registry.more().timer(
.
.
.
);


2. FunctionTimer.builder("cache.gets.latency", cache,


c
-
>
c.getLocalMapStats().getGetOperationCount(),


c
-
>
c.getLocalMapStats().getTotalGetLatency(),


TimeUnit.NANOSECONDS)


.tags("name", cache.getName())


.description("Cache gets")


.register(registry);
LongTaskTimer (active count, longest active task)
1. registry.more().longTaskTimer("long.task", "region", "test");


2. LongTaskTimer.builder("long.task")


.description("a description")
/
/
optional


.tags("region", "test")
/
/
optional


.register(registry);


3. @Timed(value = "long.task", extraTags = {"extra", "tag"}, longTask = true)
*
*
Distribution Summary → .record(value), not time
1. registry.summary("name", "region", "test")


2. DistributionSummary.builder("response.size")


.description("a description")
/
/
optional


.baseUnit("bytes") /
/
optional


.tags("region", "test")
/
/
optional


.register(registry);
Library Maintainer API
• Provide a MeterBinder (optional dependency)


• Register library-speci
fi
c metrics


• Quarkus / Spring discover MeterBinder implementations


binder.bindTo(registry)
Configuration and Filtering
• Late-binding con
fi
guration provided by MeterFilter


• Sourced from user code or shared library


• Accept/Deny
fi
lters:
fi
ne-grained control over gathered metrics


• Transform: rename metrics, add/ignore/replace/rename tags


• Customize Timer / Histogram behavior


• Percentiles, quantiles, Service Level Agreement(SLA) boundaries
Monster Combat
https://github.com/ebullient/monster-combat
https://twitter.com/ebullientworks/status/1328835279659085828?s=20


https://jaxenter.com/metrics-dnd-173311.html
Rolling dice
Micrometer:


Dice.setMonitor((k, v) -> {


registry.counter("dice.rolls", "die", k, "face", label(v))


.increment();


});
© 2020 IBM Corporation
Attacks : Hits and Misses
• AC == Armor class




Attacker rolls a d20...




20 – critical hit (HIT)


1 – critical miss (MISS)


• DC == Dif
fi
culty class




Defender rolls a d20...
: oneRound:


Troll(LARGE GIANT){AC:15,HP:84(8d10+40),STR:18(+4),DEX:13(+1),CON:20(+5),INT:7(-2),WIS:9(-1),C


Pit Fiend(LARGE FIEND){AC:19,HP:300(24d10+168),STR:26(+8),DEX:14(+2),CON:24(+7),INT:22(+6),W
: attack: miss: Troll(36) -> Pit Fiend(100)


: attack: miss: Troll(36) -> Pit Fiend(100)


: attack: hit> Troll(36) -> Pit Fiend(97) for 9 damage using Claws[7hit,11(2d6+4)|slashing]


: attack: hit> Pit Fiend(97) -> Troll(10) for 22 damage using Bite[14hit,22(4d6+8)|piercing]


: attack: MISS: Pit Fiend(97) -> Troll(10)


: attack: HIT> Pit Fiend(97) -> Troll(0) for 34 damage using Mace[14hit,15(2d6+8)|bludgeoning]


: oneRound: survivors


Pit Fiend(LARGE FIEND){AC:19,HP:300(24d10+168),STR:26(+8),DEX:14(+2),CON:24(+7),INT:22(+6),W
Micrometer: Timer & Distribution Summary
• Records value


registry.summary("round.attacks",


"hitOrMiss", event.hitOrMiss(),


"attackType", event.getAttackType(),


"damageType", event.getType())


.record((double) event.getDamageAmount());


• Default metrics: count, sum, max


• Optional: cumulative histogram buckets, pre-computed quantile
So many bugs...
There is often no practical way to write tests for all permutations...
This ended up being a problem with the
original conversion from HTML to JSON.
Who wrote this code, anyway?
Questions?

More Related Content

PPTX
Kubernetes PPT.pptx
PPTX
Maria db 이중화구성_고민하기
PDF
Présentation des services AWS
PPTX
Adopting OpenTelemetry
PDF
Apache Spark on K8S Best Practice and Performance in the Cloud
PPTX
APACHE KAFKA / Kafka Connect / Kafka Streams
PDF
Fluentd vs. Logstash for OpenStack Log Management
PPTX
Kafka 101
Kubernetes PPT.pptx
Maria db 이중화구성_고민하기
Présentation des services AWS
Adopting OpenTelemetry
Apache Spark on K8S Best Practice and Performance in the Cloud
APACHE KAFKA / Kafka Connect / Kafka Streams
Fluentd vs. Logstash for OpenStack Log Management
Kafka 101

What's hot (20)

PDF
BigData_Chp4: NOSQL
PDF
Kubernetes Scheduler deep dive
PDF
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
DOCX
Keepalived+MaxScale+MariaDB_운영매뉴얼_1.0.docx
PPTX
Introduction to Apache Kafka
PDF
Oracle Cloud Infrastructure:2022年4月度サービス・アップデート
PPTX
Deep Dive into Apache Kafka
PPTX
Tuning Apache Kafka Connectors for Flink.pptx
PDF
Cours Big Data Chap2
PPTX
Issues of OpenStack multi-region mode
PPSX
Thinking big
PDF
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
PDF
Cours d'introduction au Cloud Computing
PDF
The Beginner’s Guide To Spring Cloud
PDF
[pgday.Seoul 2022] PostgreSQL with Google Cloud
PPTX
Indexing with MongoDB
PDF
Leveraging Docker for Hadoop build automation and Big Data stack provisioning
PPTX
Introduction to Apache ZooKeeper
PDF
Rapport de projet_de_fin_d__tudes__pfe__safwen (8)
PPTX
OpenStack Architecture and Use Cases
BigData_Chp4: NOSQL
Kubernetes Scheduler deep dive
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
Keepalived+MaxScale+MariaDB_운영매뉴얼_1.0.docx
Introduction to Apache Kafka
Oracle Cloud Infrastructure:2022年4月度サービス・アップデート
Deep Dive into Apache Kafka
Tuning Apache Kafka Connectors for Flink.pptx
Cours Big Data Chap2
Issues of OpenStack multi-region mode
Thinking big
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Cours d'introduction au Cloud Computing
The Beginner’s Guide To Spring Cloud
[pgday.Seoul 2022] PostgreSQL with Google Cloud
Indexing with MongoDB
Leveraging Docker for Hadoop build automation and Big Data stack provisioning
Introduction to Apache ZooKeeper
Rapport de projet_de_fin_d__tudes__pfe__safwen (8)
OpenStack Architecture and Use Cases
Ad

Similar to Know your app: Add metrics to Java with Micrometer | DevNation Tech Talk (20)

PDF
Testing in a distributed world
PPTX
Logging, tracing and metrics: Instrumentation in .NET 5 and Azure
PPTX
Hadoop metric을 이용한 알람 개발
PDF
Lightning Fast Monitoring against Lightning Fast Outages
PDF
Unit Testing
PDF
Apache Eagle: Secure Hadoop in Real Time
PDF
Apache Eagle at Hadoop Summit 2016 San Jose
PDF
Struts2 - 101
PPTX
Performance eng prakash.sahu
PPTX
Rx 101 Codemotion Milan 2015 - Tamir Dresher
PPTX
Tamir Dresher - Reactive Extensions (Rx) 101
PPTX
Metabolomic Data Analysis Workshop and Tutorials (2014)
PDF
Monitoring with Prometheus
PPTX
Sumo Logic Quickstart - Jan 2017
PPT
Instrumentation and measurement
PDF
Performance Test Driven Development with Oracle Coherence
PDF
I Can See Clearly Now - Observing & understanding your Spring applications at...
PDF
Sumo Logic QuickStart Webinar
PPTX
Big data at experimental facilities
PDF
Detection as Code, Automation, and Testing: The Key to Unlocking the Power of...
Testing in a distributed world
Logging, tracing and metrics: Instrumentation in .NET 5 and Azure
Hadoop metric을 이용한 알람 개발
Lightning Fast Monitoring against Lightning Fast Outages
Unit Testing
Apache Eagle: Secure Hadoop in Real Time
Apache Eagle at Hadoop Summit 2016 San Jose
Struts2 - 101
Performance eng prakash.sahu
Rx 101 Codemotion Milan 2015 - Tamir Dresher
Tamir Dresher - Reactive Extensions (Rx) 101
Metabolomic Data Analysis Workshop and Tutorials (2014)
Monitoring with Prometheus
Sumo Logic Quickstart - Jan 2017
Instrumentation and measurement
Performance Test Driven Development with Oracle Coherence
I Can See Clearly Now - Observing & understanding your Spring applications at...
Sumo Logic QuickStart Webinar
Big data at experimental facilities
Detection as Code, Automation, and Testing: The Key to Unlocking the Power of...
Ad

More from Red Hat Developers (20)

PDF
DevNation Tech Talk: Getting GitOps
PDF
Exploring the power of OpenTelemetry on Kubernetes
PDF
GitHub Makeover | DevNation Tech Talk
PDF
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
PDF
Extra micrometer practices with Quarkus | DevNation Tech Talk
PDF
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
PDF
Integrating Loom in Quarkus | DevNation Tech Talk
PDF
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
PDF
Containers without docker | DevNation Tech Talk
PDF
Distributed deployment of microservices across multiple OpenShift clusters | ...
PDF
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
PDF
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
PDF
11 CLI tools every developer should know | DevNation Tech Talk
PDF
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
PDF
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
PDF
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
PDF
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
PDF
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
PDF
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
PDF
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk
DevNation Tech Talk: Getting GitOps
Exploring the power of OpenTelemetry on Kubernetes
GitHub Makeover | DevNation Tech Talk
Quinoa: A modern Quarkus UI with no hassles | DevNation tech Talk
Extra micrometer practices with Quarkus | DevNation Tech Talk
Event-driven autoscaling through KEDA and Knative Integration | DevNation Tec...
Integrating Loom in Quarkus | DevNation Tech Talk
Quarkus Renarde 🦊♥: an old-school Web framework with today's touch | DevNatio...
Containers without docker | DevNation Tech Talk
Distributed deployment of microservices across multiple OpenShift clusters | ...
DevNation Workshop: Object detection with Red Hat OpenShift Data Science [Mar...
Dear security, compliance, and auditing: We’re sorry. Love, DevOps | DevNatio...
11 CLI tools every developer should know | DevNation Tech Talk
A Microservices approach with Cassandra and Quarkus | DevNation Tech Talk
GitHub Actions and OpenShift: ​​Supercharging your software development loops...
To the moon and beyond with Java 17 APIs! | DevNation Tech Talk
Profile your Java apps in production on Red Hat OpenShift with Cryostat | Dev...
Kafka at the Edge: an IoT scenario with OpenShift Streams for Apache Kafka | ...
Kubernetes configuration and security policies with KubeLinter | DevNation Te...
Level-up your gaming telemetry using Kafka Streams | DevNation Tech Talk

Recently uploaded (20)

PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Machine learning based COVID-19 study performance prediction
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPT
Teaching material agriculture food technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Spectroscopy.pptx food analysis technology
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Programs and apps: productivity, graphics, security and other tools
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Electronic commerce courselecture one. Pdf
PPTX
Machine Learning_overview_presentation.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Encapsulation theory and applications.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Machine learning based COVID-19 study performance prediction
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Chapter 3 Spatial Domain Image Processing.pdf
Teaching material agriculture food technology
Reach Out and Touch Someone: Haptics and Empathic Computing
20250228 LYD VKU AI Blended-Learning.pptx
Spectroscopy.pptx food analysis technology
Advanced methodologies resolving dimensionality complications for autism neur...
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Programs and apps: productivity, graphics, security and other tools
“AI and Expert System Decision Support & Business Intelligence Systems”
Electronic commerce courselecture one. Pdf
Machine Learning_overview_presentation.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Encapsulation theory and applications.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
gpt5_lecture_notes_comprehensive_20250812015547.pdf

Know your app: Add metrics to Java with Micrometer | DevNation Tech Talk

  • 1. Erin Schnabel @ebullientworks Know Your (Java) App Collect metrics with Micrometer
  • 2. What makes a system (or service) observable? Workload routing 
 System health Service-centric 
 problem determination Context + relationships 
 for end–to-end analysis Statistics & trends 
 Analytics Service is ready 
 Service is not a zombie How many times was 
 method x called? Method x was called What happened when 
 method x was called Health Checks Distributed Trace Metrics Log Entries
  • 3. Metrics: Time series data How does data change over time? • Time is the x-axis • Data collected at regular intervals • Each measured value appended to the end of a series • Used for trend analysis, anomaly detection, alerting Not for debugging, diagnostics, or root cause analysis
  • 5. What is Micrometer? https://micrometer.io -- Open Source metrics library "Screw gauge" micrometer
  • 6. Developer API • Obtain a MeterRegistry • Create a Meter (name + tag=value combination) Gauge Counter Timer DistributionSummary FunctionCounter FunctionTimer, LongTaskTimer
  • 7. Counter: increase only → .increment() 1. registry.counter("example.prime.number", "type", "prime"); 2. Counter.builder("counter") 
 .baseUnit("beans") / / optional 
 .description("a description") / / optional 
 .tags("region", "test") / / optional 
 .register(registry); 3. @Counted(value = "metric.all", extraTags = { "region", "test" }) * *
  • 8. Timer → .record(duration) 1. registry.timer("my.timer", "region", "test"); 2. Timer.builder("my.timer") 
 .description("description ") / / optional 
 .tags("region", "test") / / optional 
 .register(registry); 3. @Timed(value = "call", extraTags = {"region", "test"}) * *
  • 9. Working with Timers 1. timer.record(() - > noReturnValue()); 
 2. timer.recordCallable(() - > returnValue()); 
 3. Runnable r = timer.wrap(() - > noReturnValue()); 
 4. Callable c = timer.wrap(() - > returnValue()); 
 5. Sample s = Timer.start(registry); doStuff; s.stop(timer);
  • 10. Gauge: increase/decrease, observed value 1. List<String> list = registry.gauge("list.size", Tags.of( . . . ), 
 new ArrayList < > (), List : : size); 2. Gauge.builder("jvm.threads.peak", threadBean, ThreadMXBean : : getPeakThreadCount) 
 .tags("region", "test") 
 .description("The peak live thread count . . . ") 
 .baseUnit(BaseUnits.THREADS) 
 .register(registry);
  • 11. FunctionCounter: gauge-like, counter function 1. registry.more().counter( . . . ) 2. FunctionCounter.builder("hibernate.transactions", statistics, 
 s - > s.getTransactionCount() - s.getSuccessfulTransactionCount()) 
 .tags("entityManagerFactory", sessionFactoryName) 
 .tags("result", "failure") 
 .description("The number of transactions we know to have failed") 
 .register(registry);
  • 12. FunctionTimer: gauge-like, counter & duration function 1. registry.more().timer( . . . ); 2. FunctionTimer.builder("cache.gets.latency", cache, 
 c - > c.getLocalMapStats().getGetOperationCount(), 
 c - > c.getLocalMapStats().getTotalGetLatency(), 
 TimeUnit.NANOSECONDS) 
 .tags("name", cache.getName()) 
 .description("Cache gets") 
 .register(registry);
  • 13. LongTaskTimer (active count, longest active task) 1. registry.more().longTaskTimer("long.task", "region", "test"); 2. LongTaskTimer.builder("long.task") 
 .description("a description") / / optional 
 .tags("region", "test") / / optional 
 .register(registry); 3. @Timed(value = "long.task", extraTags = {"extra", "tag"}, longTask = true) * *
  • 14. Distribution Summary → .record(value), not time 1. registry.summary("name", "region", "test") 2. DistributionSummary.builder("response.size") 
 .description("a description") / / optional 
 .baseUnit("bytes") / / optional 
 .tags("region", "test") / / optional 
 .register(registry);
  • 15. Library Maintainer API • Provide a MeterBinder (optional dependency) • Register library-speci fi c metrics 
 • Quarkus / Spring discover MeterBinder implementations binder.bindTo(registry)
  • 16. Configuration and Filtering • Late-binding con fi guration provided by MeterFilter • Sourced from user code or shared library 
 • Accept/Deny fi lters: fi ne-grained control over gathered metrics • Transform: rename metrics, add/ignore/replace/rename tags • Customize Timer / Histogram behavior • Percentiles, quantiles, Service Level Agreement(SLA) boundaries
  • 18. Rolling dice Micrometer: 
 Dice.setMonitor((k, v) -> { registry.counter("dice.rolls", "die", k, "face", label(v)) .increment(); });
  • 19. © 2020 IBM Corporation Attacks : Hits and Misses • AC == Armor class 
 
 Attacker rolls a d20... 
 
 20 – critical hit (HIT) 
 1 – critical miss (MISS) • DC == Dif fi culty class 
 
 Defender rolls a d20... : oneRound: Troll(LARGE GIANT){AC:15,HP:84(8d10+40),STR:18(+4),DEX:13(+1),CON:20(+5),INT:7(-2),WIS:9(-1),C Pit Fiend(LARGE FIEND){AC:19,HP:300(24d10+168),STR:26(+8),DEX:14(+2),CON:24(+7),INT:22(+6),W : attack: miss: Troll(36) -> Pit Fiend(100) : attack: miss: Troll(36) -> Pit Fiend(100) : attack: hit> Troll(36) -> Pit Fiend(97) for 9 damage using Claws[7hit,11(2d6+4)|slashing] : attack: hit> Pit Fiend(97) -> Troll(10) for 22 damage using Bite[14hit,22(4d6+8)|piercing] : attack: MISS: Pit Fiend(97) -> Troll(10) : attack: HIT> Pit Fiend(97) -> Troll(0) for 34 damage using Mace[14hit,15(2d6+8)|bludgeoning] : oneRound: survivors Pit Fiend(LARGE FIEND){AC:19,HP:300(24d10+168),STR:26(+8),DEX:14(+2),CON:24(+7),INT:22(+6),W
  • 20. Micrometer: Timer & Distribution Summary • Records value 
 registry.summary("round.attacks", "hitOrMiss", event.hitOrMiss(), "attackType", event.getAttackType(), "damageType", event.getType()) .record((double) event.getDamageAmount()); • Default metrics: count, sum, max • Optional: cumulative histogram buckets, pre-computed quantile
  • 21. So many bugs... There is often no practical way to write tests for all permutations... This ended up being a problem with the original conversion from HTML to JSON. Who wrote this code, anyway?