uber-go/tally

repository·master·Indexed 21 days ago

https://github.com/uber-go/tally

A fast, buffered, and hierarchical metrics collection library for Go. Tally provides a unified interface for emitting counters, gauges, timers, and histograms, managing emission velocity through buffering. It includes built-in reporters for Prometheus, StatsD, and M3, and supports custom backend implementations via the StatsReporter interface.

Tokens
9.2K
Snippets
38
Records
49
Agent score
72%

What's inside tally

  1. Configure timer types for Prometheus

    master

    The Prometheus reporter supports two types of timers via the TimerType enum:

    • SummaryTimerType: Reports into a Prometheus summary.
    • HistogramTimerType: Reports into a Prometheus histogram (this is the default).

    You can set the global default using Options.DefaultTimerType or specify a type per-metric using RegisterTimerOptions.

    type TimerType int
    
    const (
    	SummaryTimerType   TimerType = iota
    	HistogramTimerType
    )
  2. How tally's core components work together

    master

    Tally uses three main abstractions to manage metrics:

    1. Scope: The primary interface for developers. It keeps track of metrics (Counters, Gauges, Timers, and Histograms) and manages their common metadata (tags).
    2. Metrics: The actual data points you record. Tally buffers counters, gauges, and histograms at a specified interval to reduce emission velocity, but does not buffer timer values so they can be sampled accurately.
    3. Reporter: The backend implementation that accepts aggregated values from the Scope and forwards them to your metrics ingestion pipeline (e.g., Prometheus, StatsD).

    You can create hierarchical scopes using Tagged (to add metadata) or SubScope (to add name prefixes).

  3. Use the buffered StatsD reporter

    master

    The StatsD reporter allows you to emit metrics to a StatsD server. It can be used with either a basic or a buffered StatsD client. When metrics are emitted, they follow the standard StatsD format (e.g., stats.name:value|type).

    To see a complete end-to-end implementation, refer to the examples/statsd_main.go file in the repository.

    stats.my-service.test-histogram.100ms-200ms:2|c
    stats.my-service.test-counter:1|c
    stats.my-service.test-gauge:813|g
  4. Combine multiple CachedStatsReporters with NewMultiCachedReporter

    master

    Use NewMultiCachedReporter to wrap multiple tally.CachedStatsReporter implementations into a single reporter. This is used when you need the buffering/caching capabilities of CachedStatsReporter across multiple backends.

    reporter := NewMultiCachedReporter(m3Reporter, promReporter, ...)
  5. Combine multiple StatsReporters with NewMultiReporter

    master

    Use NewMultiReporter to wrap multiple tally.StatsReporter implementations into a single reporter. This allows you to emit metrics to several different backends simultaneously using a single reporter instance.

    reporter := NewMultiReporter(statsdReporter, ...)
  6. Configure StatsD reporter options

    master

    The StatsD reporter is configured using the Options struct. Currently, it supports setting the emission sample rate.

    Options

    FieldTypeDescription
    SampleRatefloat32The metrics emission sample rate. Defaults to 1 if not set.
    // Options is a set of options for the tally reporter.
    type Options struct {
    	// SampleRate is the metrics emission sample rate. If you
    	// do not set this value it will be set to 1.
    	SampleRate float32
    }
  7. Configure the Prometheus reporter with Options

    master

    When initializing a Prometheus reporter, you can use the Options struct to customize how metrics are registered and how timers behave.

    Key configuration capabilities include:

    • Custom Registry: Provide a specific prom.Registerer. If nil, the default registerer is used.
    • Timer Defaults: Set DefaultTimerType to either SummaryTimerType or HistogramTimerType. The default is HistogramTimerType.
    • Bucket/Objective Defaults: Define DefaultHistogramBuckets or DefaultSummaryObjectives to be used when creating timers without specific options.
    • Error Handling: Use OnRegisterError to define a custom callback for registration failures. By default, the reporter will panic if registration fails.
    type Options struct {
    	Registerer               prom.Registerer
    	DefaultTimerType          TimerType
    	DefaultHistogramBuckets  []float64
    	DefaultSummaryObjectives map[float64]float64
    	OnRegisterError           func(err error)
    }
  8. Define valid character sets for sanitization

    master

    When configuring SanitizeOptions, you use the ValidCharacters struct to specify which runes are allowed. A character is considered valid if it falls within any of the provided Ranges or matches any rune in the Characters slice.

    SanitizeRange is an inclusive range defined by two runes: [start, end].

  9. Understand the difference between Counters, Gauges, Timers, and Histograms

    master

    Tally provides four primary metric types:

    1. Counter: Tracks a cumulative total that only increases (e.g., total_requests). Use Inc(v).
    2. Gauge: Tracks an instantaneous measurement that can fluctuate (e.g., current_memory_usage). Use Update(v).
    3. Timer: Measures the duration of events. Unlike Histograms, Timers in Tally are often buffered and flushed as individual observations to a reporter. Use Record(d) or Start().
    4. Histogram: Categorizes observations into buckets to show distribution (e.g., request_latency_buckets). Use RecordValue(v) or RecordDuration(d).