We modeled the metrics instruments included in Kamon based on our own goals and even while they seem similar to instruments with the same names in other metrics libraries, we have a few differences.. let me first explain what each instrument means to us:
The Counter is the simplest one, it just counts and resets to zero upon each flush. Some other libraries allow counters to go up and down but we only allow them to go up, they are ideal for counting errors or occurrences of specifics events in your app but they fall short for things like mailbox sizes, see the MinMaxCounter section bellow to understand why.
Our Histogram is special and different to what all other libraries offer because thanks to the HDR Histogram [1] we can record all the measurements taken by the application with fixed time and space in a very efficient manner and with configurable precision, which by default is 1%, meaning that every measurement that you store is adjusted to one of the available buckets, but never more than 1% away from the original value.. the precision can be configured to even finer values. As you might guess, this is ideal for storing latencies, like we do for processing-time and time-in-mailbox for actors, as well as elapse-time for traces, it doesn't matter if you store one million or one billion measurements, the memory footprint remains the same.
Now we get to one created by us, the MinMaxCounter... when monitoring queues, like we do for actor mailboxes, just having a number going up and down (like a traditional counter) that is collected every X time or recording the queue size every X time (like a traditional gauge) wasn't enough for us.. if you are flushing every 10 seconds (default for StatsD and some others flush every 60 seconds) many things might have happen in those 10 seconds, you could get a million messages in the mailbox and process them all and after 10 seconds you might record 0 as the mailbox size. When monitoring the queue size it is not just about knowing where it is at a given moment because that number is probably incorrect right after reading it, but knowing where it was is of great help. The MinMaxCounter internally has 3 variables, one tracking the current value, one tracking the minimum and one tracking the maximum. These three values are read and stored in a histogram every 100 milliseconds by default and after 10 seconds you would have 300 measurements of where the queue size was that contain the lowest and highest sizes! Knowing the boundaries between which your mailbox sizes usually move is a incredibly valuable information if you try to move from unbounded to bounded mailbox implementations. After each collection, the max and min are reset to the current value, meaning that if no changes occur then the three of them will have the same value. Obviously this is the recommended instrument when recording queue-like metrics.
Finally, our Gauge is a mix between the Histogram and the MinMaxCounter: we take a measurement of a given value every 100 milliseconds by default and store the observed value in a Histogram. This can be seen as a traditional gauge that happens to report 100 values on every flush (assuming the 10 seconds example and default config) rather a single (latest) value on every flush, that's why it uses a histogram snapshot, because usually the number of measurements taken between flushes is usually larger than 1. If you flush every 10 seconds and configure the gauge to refresh every 10 seconds, you effectively turn our gauge in a traditional gauge. The uses for a gauge are diverse, we use them a lot in our system metrics module.
Now let's talk about StatsD... All of our instruments were designed without a specific metrics backend in mind and we always prefer to bring as many information as possible and let the backend summarize the data if needed.. as a example, our New Relic backend takes all the valuable data we have and reduces it to average, min, max, sum and sum of squares before posting to New Relic, because that's what they accept (sad but true).. When trying to match between our instruments and what StatsD offer it was clear that our counters would be StatsD counters and Histograms and MinMaxCounter snapshots would be StatsD timers.. we then tried to report our Gauge information as a StatsD gauge, but it turns out that StatsD will only flush the latest value of a gauge to the backend and in our 10 seconds example, only the last value sent will be reported and the previous 99 would be thrown away, not precisely what we wanted for our users valuable data, that's why for StatsD we report gaugues as timers as well. As a additional note, I always try to use the word "distribution" in my mind rather than "timer" which in my opinion is a word that could have been better selected.
All that being said, I think you should now understand why we only have counter snapshots and histogram snapshots and why they map the way they do with StatsD instruments, if you still have any doubts or suggestions please let us know, hope you find this information useful, best regards!