prometheus / client_ruby

Prometheus instrumentation library for Ruby applications
Apache License 2.0
513 stars 149 forks source link

Job name for pushgateway can't be a symbol #295

Closed ngoral closed 1 year ago

ngoral commented 1 year ago

After updating for a patch version I realized a job name, passed to Push can't be a symbol. (Thank me, I wrote the tests, and they failed, not production :) ) There's no such requirement in docs (or I missed it). So I passed symbols as names, no strings.

I am eager to help, but can't deside what to do: validate that job argument passed to Prometheus::Client::Push.new is a string, or just convert it to string inside?

It fails here: https://github.com/prometheus/client_ruby/blob/main/lib/prometheus/client/push.rb#L92 So we can add job.to_s there, or right in the initialize method as @job = job.to_s. Or validate it at the beginning and raise an error, as other methods for metrics do

Sinjo commented 1 year ago

Hey @ngoral, thanks for the bug report! This is a great catch and is very much a real issue.

Previously, before I added the code to correctly handle / in job names, we were getting away with the implicit conversion of symbols into strings by ERB::Util::url_encode:

irb(main):005:0> ERB::Util::url_encode(:hi)
=> "hi"

As you've noticed, symbols don't have include? defined on them. It's also worth noting that Base64.urlsafe_encode64 won't perform the same conversion.

irb(main):001:0> :foo.include?("/")
(irb):1:in `<main>': undefined method `include?' for :foo:Symbol (NoMethodError)
...
irb(main):006:0> Base64.urlsafe_encode64(:hi)
<internal:pack>:8:in `pack': no implicit conversion of Symbol into String (TypeError)

I think you're right about the solution: we should convert job into a string before using it inside this method. That matches what we do for metric labels (see also: the associated tests).

If you'd like to send us a PR to match that behaviour then I'll happily review it! If not, I'm happy to make the change on your behalf. Either way, thank you for bringing this to us rather than just working around it.