Yabeda

repository·master·Indexed 21 days ago

https://github.com/yabeda-rb/yabeda

An extendable framework for instrumenting Ruby applications with metrics. Yabeda provides a modular way to define counters, gauges, histograms, and summaries, using plugins for frameworks like Rails, Sidekiq, and ActiveRecord, and adapters to export data to monitoring systems such as Prometheus or Datadog.

Tokens
6.6K
Snippets
22
Records
30
Agent score
76%

What's inside Yabeda

  1. Configure tag precedence

    master

    When multiple tags are applied to a metric, Yabeda follows a specific precedence order (from highest to lowest):

    1. Manually specified tags: Tags passed directly to the metric method (e.g., .increment({key: value})).
    2. Thread local tags: Tags specified via Yabeda.with_tags.
    3. Group specific tags: Tags defined via default_tag within a specific group block.
    4. Global tags: Tags defined via default_tag at the top level of Yabeda.configure.

    Warning: When using Yabeda.with_tags, all metrics generated within that block must have those tags defined, or the operation may fail.

  2. Test Yabeda metrics with RSpec

    master

    To test metrics in RSpec, first add require "yabeda/rspec" to your rails_helper.rb or spec_helper.rb.

    You can then use several matchers to verify metric updates:

    • increment_yabeda_counter(metric): Verifies a counter increased. Use .by(n) to check the amount.
    • update_yabeda_gauge(metric_name): Verifies a gauge was updated. Use .to(value) to check the new value.
    • measure_yabeda_histogram(metric): Verifies a histogram measurement. Use .with(value) to check the range/value.
    • observe_yabeda_summary(metric): Verifies a summary observation.

    You can also scope tests using .with_tags(...) and verify specific tag values using .with(...).

    # spec_helper.rb
    require "yabeda/rspec"
    
    # Example tests
    
    it "increments counters" do
      expect { subject }.to increment_yabeda_counter(Yabeda.myapp.foo_count).by(3)
    end
    
    it "updates gauges with tags" do
      expect { subject }.to \
        update_yabeda_gauge("some_gauge_name").\
        with_tags(method: "command", command: "subscribe")
    end
    
    expect { subject }.to \
      measure_yabeda_histogram(Yabeda.something.anything_runtime).
      with(be_between(0.005, 0.05))
    
    expect { whatever }.to increment_yabeda_counter(:my_counter).with(
      { tag: "foo" } => 1,
      { tag: "bar" } => (be >= 42),
    )
  3. Install Yabeda and its plugins

    master

    To use Yabeda, add the yabeda gem to your Gemfile. You typically also need plugins to collect metrics for specific frameworks (like Rails or Sidekiq) and a monitoring system adapter (like Prometheus) to export them.

    Example Gemfile configuration:

    gem 'yabeda'
    
    # Framework plugins
    gem 'yabeda-rails'
    gem 'yabeda-sidekiq'
    
    # Monitoring adapter
    gem 'yabeda-prometheus'

    After updating your Gemfile, run bundle.

    gem 'yabeda'
    
    # Add some plugins to quickly start collecting some essential metrics:
    # gem 'yabeda-rails'
    # gem 'yabeda-sidekiq'
    
    # Then add monitoring system adapter, e.g.:
    # gem 'yabeda-prometheus'
  4. Declare and use custom metrics

    master

    You can define custom metrics within a Yabeda.configure block using groups. Supported metric types include counter, gauge, histogram, and summary.

    1. Declaration

    Metrics are organized into groups. You can add comments, units, and tags during declaration.

    2. Initialization

    After declaring metrics, you must call Yabeda.configure! to apply the configuration. Note: If you are using Ruby on Rails, this step is handled automatically.

    3. Usage

    Access metrics via the group name on the Yabeda module. Use methods like .increment for counters or .measure for histograms.

    4. Periodic Collection

    Use the collect block to report metrics that represent the current state of your application (e.g., counting active records). This block is executed periodically by your adapter.

    5. Default Tags

    You can set global tags or group-specific tags. You can also temporarily override tags for a specific block of code using Yabeda.with_tags.

    # 1. Declare metrics
    Yabeda.configure do
      group :your_app do
        counter   :bells_rang_count, comment: "Total number of bells being rang", tags: %i[bell_size]
        gauge     :whistles_active,  comment: "Number of whistles ready to whistle"
        histogram :whistle_runtime do
          comment "How long whistles are being active"
          unit :seconds
        end
        summary :bells_ringing_duration, unit: :seconds, comment: "How long bells are ringing"
      end
    end
    
    # 2. Apply configuration (Automatic in Rails)
    Yabeda.configure!
    
    # 3. Use metrics
    def ring_the_bell(id)
      bell = Bell.find(id)
      bell.ring!
      Yabeda.your_app.bells_rang_count.increment({bell_size: bell.size}, by: 1)
    end
    
    def whistle!
      Yabeda.your_app.whistle_runtime.measure do
        # Run your code
      end
    end
    
    # 4. Periodic collection
    Yabeda.configure do
      collect do
        your_app.whistles_active.set({}, Whistle.where(state: :active).count)
      end
    end
    
    # 5. Default tags and overrides
    Yabeda.configure do
      default_tag :rails_environment, 'production'
      default_tag :tag_name, 'override', group: :your_app
    end
    
    Yabeda.with_tags(rails_environment: 'staging') do
      Yabeda.your_app.bells_rang_count.increment({bell_size: bell.size}, by: 1)
    end
  5. Install Yabeda and plugins

    master

    To start collecting metrics, you need to install the core yabeda gem, specific plugins for your framework/tools, and a monitoring system adapter (e.g., Prometheus).

    Example setup for a Rails and Sidekiq application using Prometheus:

    1. Add plugins to your Gemfile:
      • gem 'yabeda-rails'
      • gem 'yabeda-sidekiq'
    2. Add a monitoring system adapter:
      • gem 'yabeda-prometheus'
  6. Disable metric export using NullAdapter

    master
    The Yabeda::NullAdapter is an adapter that discards all metrics. It is intended for use cases where you want to disable metric export entirely, such as in development environments or when no monitoring backend (like Prometheus) is configured. It implements the standard adapter interface but performs no operations when metrics are registered or updated.
  7. How collectors and collect! work

    master

    Yabeda uses 'collectors' (Procs) to periodically retrieve metrics. These collectors are intended to be executed by monitoring system adapters.

    When an adapter needs to scrape metrics, it should call Yabeda.collect!, which iterates through all registered collectors and executes them.

  8. Configure Yabeda debug mode

    master

    Yabeda uses the anyway_config gem for configuration. You can enable debug mode to collect metrics measuring Yabeda's own performance, such as yabeda_collect_duration (which tracks how long collector blocks take to run).

    To enable debug mode:

    • Set the environment variable YABEDA_DEBUG=true.
    • Or call Yabeda.debug! in your code.

    Config Key:

    • debug (boolean, default: false): Enables performance metrics for Yabeda.
  9. Implement a custom Yabeda monitoring system adapter

    master

    To support a new monitoring system, you must create a class that inherits from Yabeda::BaseAdapter. You need to implement the register! method (or the specific register_X! methods) to handle different metric types, and the corresponding perform_X! methods to execute the actual metric updates in your monitoring system.

    Metric Registration

    For each metric type your system supports, implement the corresponding registration method:

    • register_counter!(metric)
    • register_gauge!(metric)
    • register_histogram!(metric)
    • register_summary!(metric)

    If a method is not implemented, it should raise NotImplementedError.

    Metric Execution

    Once registered, the adapter must implement the execution methods:

    • perform_counter_increment!(counter, tags, increment)
    • perform_gauge_set!(metric, tags, value)
    • perform_histogram_measure!(metric, tags, value)
    • perform_summary_observe!(metric, tags, value)

    Native Gauge Increment/Decrement

    Yabeda::BaseAdapter provides an optional method perform_gauge_increment!(_gauge, _tags, _increment).

    • If your monitoring system supports native gauge increments/decrements, implement this method and ensure it returns a non-nil value.
    • If it does not support it, leave it as the default (which returns nil).
    class MyCustomAdapter < Yabeda::BaseAdapter
      def register_counter!(metric)
        # implementation
      end
    
      def perform_counter_increment!(counter, tags, increment)
        # implementation
      end
    
      def perform_gauge_increment!(gauge, tags, increment)
        # return non-nil if supported
        true
      end
    end
  10. Filter metrics using allow-lists or deny-lists

    master

    You can control which metrics are exposed within a group using only (allow-list) or except (deny-list). This is particularly useful for disabling high-cardinality metrics provided by third-party plugins.

    Example: Disabling specific metrics from yabeda-activerecord:

    Yabeda.configure do
      group :activerecord do
        except :queries_total, :query_duration
      end
    end
    Yabeda.configure do
      group :internal do
        only :foo
    
        counter :foo
        gauge :bar
      end
    end
  11. Limit metrics to specific adapters

    master

    You can restrict which metrics or entire groups are exposed to specific monitoring adapters. This is useful when you want certain metrics to go to Prometheus but not to Datadog, for example.

    You can specify the adapter at the group level or the individual metric level using the adapter option.

    Yabeda.configure do
      group :internal do
        adapter :prometheus
    
        counter :foo
        gauge :bar
      end
    
      group :cloud do
        adapter :newrelic
    
        counter :baz
      end
    
      counter :qux, adapter: :prometheus
    end
  12. Available Yabeda plugins

    master

    Yabeda provides a variety of plugins to collect metrics for different Ruby components:

    • Rails: yabeda-rails (basic metrics for Rails applications)
    • ActiveRecord: yabeda-activerecord (query performance and connection pool statistics)
    • Sidekiq: yabeda-sidekiq (complete monitoring of Sidekiq metrics)
    • Faktory: yabeda-faktory (monitoring of Faktory Ruby Workers)
    • GraphQL: yabeda-graphql (GraphQL-Ruby application performance)
    • Puma: yabeda-puma-plugin (Puma web-server metrics)
    • HTTP Requests: yabeda-http_requests (built-in metrics for external HTTP requests)
    • Schked: yabeda-schked (built-in metrics for Schked recurring jobs)
    • AnyCable: yabeda-anycable (performance metrics for AnyCable RPC server)