Measure Metrics
CatalogTribe in Shanghai
debop@coupang.com 2018.01.18
Agenda
• Purpose of Measurements
• Measurement flow
• Dashboard examples
• Type of measures
• Count,Time, Meter, Gauge, Histogram
• How to measures
• Use metrics directly
• Use Annotations
Purpose of Measurements
• Gathering Objective, Quantifiable data
• System Health Check withTimely measured data
• Back data to select points for System Improvements
• Analysis measured data for Maintenance and Improvement
Measurements flow
Dashboards (Grafana)
Store Measures
Application
Storage
• Count
• Timers
• Meters (P95, P99)
• Gauge (JMX,Ratio,Cached)
• Histogram
Reporter
Measurements flow
Dashboards (Grafana)
Store Measures
Application
Storage
• Count
• Timers
• Meters (P95, P99)
• Gauge (JMX,Ratio,Cached)
• Histogram
Reporter
Measurements flow
Dashboards (Grafana)
Store Measures
Application
Storage
• Count
• Timers
• Meters (P95, P99)
• Gauge (JMX,Ratio,Cached)
• Histogram
Reporter
Measurements flow
Dashboards (Grafana)
Report periodical Store Measures
Application
Storage
• Count
• Timers
• Meters (P95, P99)
• Gauge (JMX,Ratio,Cached)
• Histogram
Reporter
Measurements flow
Dashboards (Grafana)
Report periodical Store Measures
Application
Storage
• Count
• Timers
• Meters (P95, P99)
• Gauge (JMX,Ratio,Cached)
• Histogram
Reporter
Dashboard examples
Dashboard
Deathwing Redis cache
Latency by API
Type of measurements
• Count (ex: Call count)
• Time (ex:API Latency)
• Meter (ex:API Latency in P50, P95, P99 …)
• Gauge
• JVM, Ratio, Cache
• Histogram
How to measure
How to measure - Directly
private final Counter pendingJobs = metrics.counter(name(QueueManager.class, "pending-jobs"));
public void addJob(Job job) {
pendingJobs.inc();
queue.offer(job);
}
private final Timer responses = metrics.timer(name(RequestHandler.class, "responses"));
public String handleRequest(Request request, Response response) {
final Timer.Context context = responses.time();
try {
// etc;
return "OK";
} finally {
context.stop();
}
}
Count
Elapsed Time
(Latency)
How to measure - Directly
public class DatabaseHealthCheck extends HealthCheck {
private final Database database;
public DatabaseHealthCheck(Database database) {
this.database = database;
}
@Override
public HealthCheck.Result check() throws Exception {
if (database.isConnected()) {
return HealthCheck.Result.healthy();
} else {
return HealthCheck.Result.unhealthy("Cannot connect to " + database.getUrl());
}
}
}
final HealthCheckRegistry healthChecks = new HealthCheckRegistry();
Health Check
How to measure - Annotations
• Use coupang-metrics
• Support for Guice and Spring both
• @Count, @Timed, @Meter, @Gauge …
• Support Async Call by @AsyncCount, @AsyncTimed
How to measure - Annotation
open class InstrumentedWithCounterParent {
@Counted(name = "counterParent", absolute = true, monotonic = true)
open fun counterParent(): String = "counterParent"
}
How to measure - Annotation
open class InstrumentedWithTimed {
@Timed(name = "things")
open fun doAThing(): String {
Thread.sleep(10L)
return "poop"
}
@Timed
open fun doAThingWithDefaultScope(): String {
Thread.sleep(10L)
return "defaultResult"
}
@Timed(name = "absoluteName", absolute = true)
open fun doAThingWithAbsoluteName(): String = "defaultProtected"
}
How to measure - Annotation
open class InstrumentedWithMetered {
@Metered(name = "things")
open fun doAThing(): String {
Thread.sleep(10L)
return "poop"
}
@Metered
open fun doAThingWithDefaultScope(): String = "defaultResult"
@Metered
open protected fun doAThingWithProtectedScope(): String = "defaultProtected"
@Metered(name = "n")
open fun doAThingWithName(): String = "withName"
@Metered(name = "absoluteName", absolute = true)
open fun doAThingWithAbsoluteName(): String = "defaultProtected"
}
How to measure - Annotation
@Configuration
class HealthCheckConfiguration {
@Bean
fun customHealthCheck(): CustomHealthCheck = CustomHealthCheck()
@Bean
fun healthCheckRegistry(): HealthCheckRegistry = HealthCheckRegistry().apply {
register("customHealthCheck", customHealthCheck())
}
}
@com.codahale.metrics.health.annotation.Async(period = 50, unit = TimeUnit.MILLISECONDS)
open class CustomHealthCheck() : HealthCheck() {
var shouldFail: Boolean = false
override fun check(): Result = when {
shouldFail -> Result.unhealthy(RuntimeException("Fail whale"))
else -> Result.healthy()
}
}
TO DO
• Add measures to exists API and sub apis
• JVM Measures (provided by dropwizard library)
• Add your business measures
• Add HealthCheck to Servers (DB, Cache …)
• Implements Dashboard with Grafana
Thank you!

measure metrics

  • 1.
    Measure Metrics CatalogTribe inShanghai debop@coupang.com 2018.01.18
  • 2.
    Agenda • Purpose ofMeasurements • Measurement flow • Dashboard examples • Type of measures • Count,Time, Meter, Gauge, Histogram • How to measures • Use metrics directly • Use Annotations
  • 3.
    Purpose of Measurements •Gathering Objective, Quantifiable data • System Health Check withTimely measured data • Back data to select points for System Improvements • Analysis measured data for Maintenance and Improvement
  • 4.
    Measurements flow Dashboards (Grafana) StoreMeasures Application Storage • Count • Timers • Meters (P95, P99) • Gauge (JMX,Ratio,Cached) • Histogram Reporter
  • 5.
    Measurements flow Dashboards (Grafana) StoreMeasures Application Storage • Count • Timers • Meters (P95, P99) • Gauge (JMX,Ratio,Cached) • Histogram Reporter
  • 6.
    Measurements flow Dashboards (Grafana) StoreMeasures Application Storage • Count • Timers • Meters (P95, P99) • Gauge (JMX,Ratio,Cached) • Histogram Reporter
  • 7.
    Measurements flow Dashboards (Grafana) Reportperiodical Store Measures Application Storage • Count • Timers • Meters (P95, P99) • Gauge (JMX,Ratio,Cached) • Histogram Reporter
  • 8.
    Measurements flow Dashboards (Grafana) Reportperiodical Store Measures Application Storage • Count • Timers • Meters (P95, P99) • Gauge (JMX,Ratio,Cached) • Histogram Reporter
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
    Type of measurements •Count (ex: Call count) • Time (ex:API Latency) • Meter (ex:API Latency in P50, P95, P99 …) • Gauge • JVM, Ratio, Cache • Histogram
  • 14.
  • 15.
    How to measure- Directly private final Counter pendingJobs = metrics.counter(name(QueueManager.class, "pending-jobs")); public void addJob(Job job) { pendingJobs.inc(); queue.offer(job); } private final Timer responses = metrics.timer(name(RequestHandler.class, "responses")); public String handleRequest(Request request, Response response) { final Timer.Context context = responses.time(); try { // etc; return "OK"; } finally { context.stop(); } } Count Elapsed Time (Latency)
  • 16.
    How to measure- Directly public class DatabaseHealthCheck extends HealthCheck { private final Database database; public DatabaseHealthCheck(Database database) { this.database = database; } @Override public HealthCheck.Result check() throws Exception { if (database.isConnected()) { return HealthCheck.Result.healthy(); } else { return HealthCheck.Result.unhealthy("Cannot connect to " + database.getUrl()); } } } final HealthCheckRegistry healthChecks = new HealthCheckRegistry(); Health Check
  • 17.
    How to measure- Annotations • Use coupang-metrics • Support for Guice and Spring both • @Count, @Timed, @Meter, @Gauge … • Support Async Call by @AsyncCount, @AsyncTimed
  • 18.
    How to measure- Annotation open class InstrumentedWithCounterParent { @Counted(name = "counterParent", absolute = true, monotonic = true) open fun counterParent(): String = "counterParent" }
  • 19.
    How to measure- Annotation open class InstrumentedWithTimed { @Timed(name = "things") open fun doAThing(): String { Thread.sleep(10L) return "poop" } @Timed open fun doAThingWithDefaultScope(): String { Thread.sleep(10L) return "defaultResult" } @Timed(name = "absoluteName", absolute = true) open fun doAThingWithAbsoluteName(): String = "defaultProtected" }
  • 20.
    How to measure- Annotation open class InstrumentedWithMetered { @Metered(name = "things") open fun doAThing(): String { Thread.sleep(10L) return "poop" } @Metered open fun doAThingWithDefaultScope(): String = "defaultResult" @Metered open protected fun doAThingWithProtectedScope(): String = "defaultProtected" @Metered(name = "n") open fun doAThingWithName(): String = "withName" @Metered(name = "absoluteName", absolute = true) open fun doAThingWithAbsoluteName(): String = "defaultProtected" }
  • 21.
    How to measure- Annotation @Configuration class HealthCheckConfiguration { @Bean fun customHealthCheck(): CustomHealthCheck = CustomHealthCheck() @Bean fun healthCheckRegistry(): HealthCheckRegistry = HealthCheckRegistry().apply { register("customHealthCheck", customHealthCheck()) } } @com.codahale.metrics.health.annotation.Async(period = 50, unit = TimeUnit.MILLISECONDS) open class CustomHealthCheck() : HealthCheck() { var shouldFail: Boolean = false override fun check(): Result = when { shouldFail -> Result.unhealthy(RuntimeException("Fail whale")) else -> Result.healthy() } }
  • 22.
    TO DO • Addmeasures to exists API and sub apis • JVM Measures (provided by dropwizard library) • Add your business measures • Add HealthCheck to Servers (DB, Cache …) • Implements Dashboard with Grafana
  • 23.