Comments (11)
+1 for Custom Collectors
Examples of usage:
- Getting instantly values from
ActiveRecord::Base.connection_pool.stat
- Getting instantly values from Puma server (through control socket)
- Getting instantly values from GC.stat
- etc..
from client_ruby.
Hi @directionless,
I would like to understand this problem better...
Do you have any examples where you need this functionality?
Thank you
from client_ruby.
Since submitting this, I've stopped working on the project that needed this. However, the need was real, and I believe should I pick up ruby and prometheus I'll encounter it again.
It generally centers around importing metrics that are generated elsewhere. The python docs have a reasonably clear explanation:
Sometimes it is not possible to directly instrument code, as it is not in your control. This requires you to proxy metrics from other systems.
@a0s has some good examples.
Mine were business/app data, for example:
- total users
User.count
- active users
ActiveRecord::SessionStore::Session.where("updated_at > ?", 15.minutes.ago).count
- Similar for other important data models
- Etc.
I usually want these metrics for several reasons. First, it makes for a simple business analytics system. I've already got metrics and graphs, I may as well add in a little bit of BI. Second, when debugging application issues, I usually also want those numbers on a graph. Third, I may want to set alerts. More concretely, I probably know that my application performance is strongly correlated with the number of widgets in the system. So I want to be monitoring that widget count, and comparing it.
For that use case, I also ran into #9 and ended up writing a fork of the gitlab prometheus-client-mmap gem. Submitted upstream at https://gitlab.com/gitlab-org/prometheus-client-mmap/merge_requests/24
from client_ruby.
BTW,
total users
User.count
active usersActiveRecord::SessionStore::Session.where("updated_at > ?", 15.minutes.ago).count
I think there is a better place for this. There is postgres_exporter. You able to add custom metrics with custom SQL scripts. Moreover, making requests like a User.count
on a Postgres-side is better for performance.
from client_ruby.
Hey @directionless!
I totally get your use case, and I think they are valid things to want to export in Prometheus. We export many similar metrics from our services.
Can I ask what is missing to support this, though? I've always produced a Collector class that adheres to the Rack middleware interface, then place this in the scrape middleware chain and have it pull the metrics just before responding to a scrape.
As a result, I'm not sure what we need from the library that is missing?
from client_ruby.
@directionless I open-sourced my small library for client_ruby. And add prototype of CustomCollector.
from client_ruby.
To reiterate -- I am no longer working on the project that had this use case. So I cannot easily evaluate how well this would replace it. But, comments inline...
I think there is a better place for this. There is postgres_exporter.
While I think that's better for some things, as active record models get more complicated, I'm very leery of separating the reporting logic from it. And, as in your library, that's not going to work for puma stats.
Can I ask what is missing to support this, though? I've always produced a Collector class that adheres to the Rack middleware interface, then place this in the scrape middleware chain and have it pull the metrics just before responding to a scrape.
That sounds interesting, and may cover this, but I don't know that I understand what that would do. Initially it sounds like it would work, is there an example somewhere of how that would work? I can imagine it either exactly meeting the original request for custom collectors. Or feeling like re-implementing a lot of existing features.
There's probably also something caveat about timing. Some metrics are cheap and I want to pull them frequently. Other metrics are expensive, and I want to pull them less frequently. Though perhaps that's best done by sticking some cache+ttl in the metric pull.
from client_ruby.
@lawrencejones How do you feel about having a CustomCollector
class that basically implements that Rack interface, and calls a couple of overridable methods (before
, after
, around
, maybe?) so that all you need to do is subclass it, set up your metrics declaration, and override one of those methods to set / increment those metrics in them. (And add to the middleware chain)
It's essentially the same as you said, but it may be more clear / easier to use as an interface?
Either way, I think this is mostly solved by documentation. We possibly don't need that class, just a code snippet in the README
on how you'd implement your own custom collector that is easy to understand.
Either way, I don't think this should block the 1.0 release
from client_ruby.
I'm not sure, thinking about it, a metric that when read fetches its value could be really useful, especially in the fork world.
But it's entirely separate from the 1.0 release- literally nothing should hold that back, there is no reason to delay the 1.0 release as far as I can see. The number of people who adopt Prometheus in ruby every day and use the pre 1.0 grows every day, so the faster this is released the better for the community.
from client_ruby.
Agreed on that last point. Will get your thoughts on the metric that fetches when read next time I see you :-)
from client_ruby.
I made quick and dirty hack to this kind of purpose for my rails app.
# config/initializers/prometheus.rb
require 'prometheus/client'
Prometheus::Client.registry.gauge(:room_temperature_celsius, docstring: '...', labels: [:room])
# app/controller/prometheus_exporter.rb
require 'prometheus/client'
require 'prometheus/client/formats/text'
class PrometheusExporterController < ApplicationController
def index
gauge = Prometheus::Client.registry.get(:room_temperature_celsius)
gauge.set(21.534, labels: { room: 'kitchen' })
render plain: Prometheus::Client::Formats::Text.marshal(Prometheus::Client.registry)
end
end
# config/routes.rb
get '/metrics' => 'prometheus_exporter#index', format: false
And It works for me.
$ curl http://localhost:5000/metrics
# TYPE room_temperature_celsius gauge
# HELP room_temperature_celsius ...
room_temperature_celsius{room="kitchen"} 21.534
from client_ruby.
Related Issues (20)
- specifying ip-address and portnumber HOT 6
- CPU usage growing over time with DirectFileStore HOT 1
- better path handling HOT 14
- Update README.md with changes to pushgateway client
- Update CHANGELOG.md for 3.0.0 release HOT 1
- `generate_path` yields incorrect values for Sinatra+Rack::Build apps HOT 6
- Exporter port option doesn't work HOT 2
- Counter metric is reset when it has no labels HOT 8
- ERROR: Permission to prometheus/client_ruby.git denied HOT 2
- The rack example does not work because of `Rack::Lint::LintError` HOT 1
- Aaup HOT 1
- How to metrify ActiveRecord sql queries and Redis jobs (sidekiq/resque)? HOT 1
- pushing metrics with instance grouping_key would result: instance is reserved HOT 6
- Fix `Rack` deprecation warning
- Improving DirectFileStore for performance and scalability HOT 18
- Implement native histograms support HOT 4
- cannot load such file -- prometheus/middleware/collector (LoadError) HOT 2
- Job name for pushgateway can't be a symbol HOT 1
- UTF-8: Implement support in Ruby client library HOT 5
- How can I change how paths are labelled? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from client_ruby.