Git Product home page Git Product logo

metrics's Introduction

What is it?

hh-metrics is a java library that aggregates metrics in memory and sends aggregated values to a monitoring system using statsd protocol.

Motivation

In memory aggregation

In case of thousands events per second you do not want to send each event over network because of serialization and network overhead as well as high probability of loosing events when using UDP. It is better to aggregate a stream of events in memory and periodically send aggregated values to a monitoring system.

Metric breakdown

In addition, we find it convenient to track events with breakdown by tags. For example "number of cache calls with breakdown by regions and nodes". Then you can answer questions like: What is a total number of cache calls? What are most popular cache regions? What cache nodes are down and do not reply?

Memory limits

There is a risk of consuming too much memory if a tag has too many values. For example, you decide to track "how much database time is consumed by each url of your application". If you forget to remove ids from urls, you'll end up with thousands of independent counters that can consume too much memory.

Another risk is using many tags. For example, if a metric is broken down by 3 tags: tag1 has 10 distinct values, tag2 has 100 distinct values and tag3 has 1000 distinct values, you will end up with 10 * 100 * 1000 = 1 000 000 different combinations that again can consume too much memory.

To prevent high memory consumption we use several techniques.

  1. Our aggregators has a mandatory limit on the maximum number of distinct tags.
  2. Each time we get a snapshot of aggregated values to be sent to a monitoring system, we reset an aggregator.

Why not Dropwizard Metrics?

At the time of writing Dropwizard Metrics library does not have metric breakdowns, memory limits and native support of statsd.

Constraints

We use popular StatsD protocol to send metrics to a monitoring system. Unfortunately, statsd does not have such concept as "metric breakdown". You should somehow encode tags in a metric name. We do it like this:

cache.calls.region_is_vacancy.node_is_127-0-0-1

In this case metric name is cache.calls, cache region is vacancy and cache node is 127-0-0-1.

This scheme should be supported by your monitoring system. See, for example, okmeter.io.

Build

We use Apache Maven so just:

mvn install

Quick guide

Pretend you have thousands calls to a cache and you want to send number of cache hits to your monitoring system.

But just a number of hits is not very informative. You want to have cache hits broken down by cache regions and nodes.

Here is an example of how it can be accomplished:

public class CacheClient {
  
  private final Counters hitCounters;
  
  public CacheClient(StatsDSender statsDSender) {
    // Create Counters aggregator that maintains a separate counter for each combination of tags (region and node in our case).
    int maxNumOfCounters = 500;
    this.hitCounters = new Counters(maxNumOfCounters);
    
    // Register hitCounters in statsDSender to periodically send accumulated values to a monitoring system
    String hitCountersMetricName = "cache.hits";
    statsDSender.sendCountersPeriodically(hitCountersMetricName, hitCounters);
  }
  
  public Object get(String region, int id) {
    // Some code here that fetches an object from a cache node by region and id
    // ...
    // Register hit
    hitCounters.add(1, new Tag("region", region), new Tag("node", node));
  }
}

Here we use Counters aggregator. There are also other types of aggregators: Histogram, Histograms, Max. See java doc for more details.

When you register hitCounters in StatsDSender, it periodically gets snapshot of hitCounters, sends accumulated values to statsd server and resets hitCounters to prevent overflow and reduce memory consumption.

StatsDSender can be reused between different parts of your application and is passed to the CacheClient as a dependency. It can be created like this:

String statsdHost = "localhost";
int statsdPort = 8125;
int maxQueueSize = 10_000;
String prefix = null;
StatsDClient statsDClient = new NonBlockingStatsDClient(prefix, statsdHost, statsdPort, maxQueueSize);

StatsDSender statsDSender = new StatsDSender(statsDClient, scheduledExecutorService);

We use java-dogstatsd-client as StatsDClient.

metrics's People

Contributors

aulust avatar dzharikhin avatar kapiton42 avatar

Stargazers

Artur Khalikov avatar

Watchers

Yaroslav Barov avatar Алексей Огнев avatar Pavel Martyshev avatar  avatar Ellin Pino Tolstov avatar James Cloos avatar Andrey Ivanov avatar Sergey Abkaryan avatar Ekaterina Tyulkina avatar Gleb Zhukov avatar Nik avatar Grigoriy Troitskiy avatar Andrew Sumin avatar Dmitry Parfenov avatar Trushin Arseniy avatar Nikolai Miroshnichenko avatar Alexey Gorlenko avatar Vitaliy Baranov avatar Alexander Tsybulko avatar Renat Osmanov avatar Nikolay Nosak avatar Sergey Kuptsov avatar Tereshchenko Evgenii avatar Artem Maslikov avatar Igor avatar Alexander Linnik avatar Алексей Галкин avatar Eugeny Zibrov avatar Anton S avatar Evgeny Bokshitsky avatar Konstantin Zhitkov avatar Svetlana Volskaya avatar Privezentsev Yura avatar Irina Garanina avatar Stas Yarkin avatar Vera Lobacheva avatar Snurnicyn Konstantin avatar  avatar Oleg Negrozov avatar Петрукович Евгений avatar Yuri Zhanov avatar Mikhail Ruban avatar Evgeniya Konomanina avatar Anton Migalin avatar Evgeniy Kovalev avatar Виктор Реушкин avatar Anton Miroshnichenko avatar Dmitry Sukhovitsyn avatar Sophia Sorokina avatar Мария Ощепкова avatar Nikita Basharov avatar Pavlov Dmitry avatar  avatar Dmitry Savkin avatar Artem avatar Leonid Feskov avatar Mikhail Gorelov avatar Хабарова Елена avatar Novikov Mikhail avatar Влад Кобзарь avatar Ksenia Kolesnikova avatar Andrey Shevchik avatar Ruslan avatar Dmitriy Chekanov avatar  avatar Irina Petrova avatar  avatar Denis Samodurov avatar  avatar

Forkers

alexrogalskiy

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.