Repository navigation
DirectFileStore fails on Ruby 4.x: undefined method 'parse' for CGI #329
Description
Activity
Hello! Thanks for the report. I've got a couple of PRs open that will fix this:
Once they're merged I'll cut a new release and ping you here!
Reacted by Eduardo Bohrersame here. I've fixed it on my rails app with this monkey patch (in
config/initializers/monkey_patch_prometheus_client.rb)Prometheus::Client::DataStores::DirectFileStore.const_get("MetricStore").class_eval do def all_values stores_data = Hash.new { |hash, key| hash[key] = [] } # There's no need to call `synchronize` here. We're opening a second handle to # the file, and `flock`ing it, which prevents inconsistent reads stores_for_metric.each do |file_path| store = Prometheus::Client::DataStores::DirectFileStore::FileMappedDict.new(file_path, true) store.all_values.each do |(labelset_qs, v, ts)| # Labels come as a query string, that we parse with URI.decode_www_form as this: # "foo=bar&x=y" => { "foo" => "bar", "x" => "y" } # Turn the keys back into symbols label_set = URI.decode_www_form(labelset_qs).map do |k, v| [k.to_sym, v] end.to_h stores_data[label_set] << [v, ts] end ensure store.close if store end # Aggregate all the different values for each label_set aggregate_hash = Hash.new { |hash, key| hash[key] = 0.0 } stores_data.each_with_object(aggregate_hash) do |(label_set, values), acc| acc[label_set] = aggregate_values(values) end end end
Might attempt to open a PR later today
Hey, sorry for the lack of progress on this. I have the code teed up already, but haven't had time to write and run a test I wanted to before shipping it. I don't get employer-sponsored time to work on this gem any more and life is busy.
Reacted by Francis Pérez Padilla@Sinjo I totally understand! No pressure at all, we're very grateful for all your work. For now I'm happy with my monkey patch, I'll remove it when this is fixed upstream 😄
@Sinjo dont worry and thanks for your incredible work.
I was able to work around this by explicitly adding the cgi gem to my Gemfile:
gem 'cgi', '~> 0.5.1'Ruby 4 no longer ships CGI.parse in the default bundled cgi — it now lives in the standalone gem. Adding it back restores the method and DirectFileStore works as expected again.
This should be a good option for anyone hitting this issue until a definitive fix.This is fixed in 5.0.0, which I pushed to RubyGems a few days ago.
If you're curious about the testing I wanted to do, it's here: #330 (comment)
Hi 👋
I’m seeing an incompatibility when using prometheus-client with Ruby 4.x, specifically when using Prometheus::Client::DataStores::DirectFileStore.
The same code works correctly on Ruby 3.4.2, but fails on Ruby 4.0.1 with a NoMethodError related to CGI.parse.
Other data stores were not tested yet, but the error clearly originates from DirectFileStore.
Environment
Ruby:
✅ 3.4.2 (works)
❌ 4.0.1 (fails)
Reproduction steps
Expected behavior (Ruby 3.4.2)
Actual behavior (Ruby 4.0.1)
Fast Analysis
This issue appears to be specific to DirectFileStore, more precisely in
DirectFileStore::MetricStore#all_values.
Ruby 4 removed or changed the availability of CGI.parse.
In Ruby 3.x this method exists, but in Ruby 4.x it raises NoMethodError.