yabeda-rb / yabeda

Extendable framework for collecting and exporting metrics from your Ruby application
MIT License
775 stars 25 forks source link

Access Puma stats in models #11

Closed ghost closed 4 years ago

ghost commented 4 years ago

Hi, this is not really an issue with the code, rather a request for information. I have a Rails (API) only application, running on Puma, and I need to know how much load my application is under in the Rails model (it will inform the behaviour of the model), Initially I was planning to interrogate the Puma state, then the socket and so, on, but I see all this is already implemented in Yabeda, so seems a no-brainer to use it, but I've been grepping around the documentation, the code, I can't seem to find out how to access the Puma stats directly. Any pointers would be much appreciated!

Thanks

Envek commented 4 years ago

Hmm. This one is tricky.

The correct thing to do will be to write your own adapter for Yabeda, that will receive gauge updates and store them somehow. See lib/yabeda/base_adapter.rb for reference.

Something like this:

class MyModelAdapter < Yabeda::BaseAdapter
  def initialize()
    # do init. E.g. start background thread for scraping
  end

  def register_gauge!(metric)
    # use if you need to register gauges somehow, keep empty otherwise
  end

  def perform_gauge_set!(metric, tags, value)
    return unless metric.group == :puma # should be symbol but not sure
    # Store it temporarily somewhere, process later
  end

  # Same for counters and histograms. yabeda-puma-plugin doesn't have any yet, so at least empty methods should exist
end

Your adapter MUST initiate process of metrics collection (only then yabeda-puma-plugin's collect block will be called and permanently store all collected values after that. See, for example, how yabeda-datadog runs these collectors.

When in doubt, please take a look at yabeda-datadog adapter which does all that machinery by itself (without relying to any other gem's polling mechanisms).

I hope that it helps, feel free to ask more questions.

ghost commented 4 years ago

That's great -- thanks @Envek. I'll close this now so as not to scruffy up your nice clean repo :smile:

Envek commented 4 years ago

@jjg-dressipi, are you successful with this approach? Do you need any help? Or may be you have some useful observations, comments, or code snippets to share?

I think that your use case worth documentiing ;-)

ghost commented 4 years ago

In the end, the Puma stats weren't the numbers that I was hoping for (the per-process backlog remained at zero, even when I pummelled the 4-process 1-thread puma server with 8 parallel requests, not sure why, but they didn't give me a measure of the overload). I found that just accessing the system load (via the sys-cpu gem) was a better measure, then it seems less impact just to have a standalone side-process to make those numbers available via a TCP socket (I've done that several times to good effect, and so could use one of the earlier verison as a template). So in the end I didn't use yabada, but I keep an eye out for possible use-cases in other projects in the pipeline. Thanks for your help on this!

luisdavim commented 3 years ago

Sorry for bumping an old thread, but I'm interested in this, my use case is to implement a readiness endpoint that is aware of the Puma capacity, if I'm running out of threads to server I want to mark that instance as not ready so no new connections are sent to it. Any pointers?