2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/stack-service-base/prometheus_parser.rb', line 2
def self.parse_metrics(text)
metrics = Hash.new { |h, k| h[k] = { series: [] } }
series = ->(name, labels) do
metrics[name][:series].find { _1[:labels] == labels } ||
metrics[name][:series] << { labels: labels } and metrics[name][:series].last
end
text.each_line(chomp: true) do |l|
case l
when /\A#\s*HELP\s+(\S+)\s+(.+)/
metrics[$1.to_sym][:help] = $2
when /\A#\s*TYPE\s+(\S+)\s+(\S+)/
metrics[$1.to_sym][:type] = $2.to_sym
when /\A([^ {]+)(?:\{([^}]*)\})?\s+([0-9eE+\-\.]+)\z/
name, lbls, val = $1.to_sym, $2, $3.to_f
labels = lbls.to_s.split(',').to_h { |kv| k, v = kv.split('='); [k.to_sym, v.delete('"')] }
case
when name.to_s.end_with?('_bucket')
base = name.to_s.sub(/_bucket\z/, '').to_sym
le = labels.delete(:le)
(entry = series[base, labels])[:buckets] ||= {}
entry[:buckets][le] = val
when name.to_s =~ /(.*)_(sum|count)\z/
base, field = Regexp.last_match(1).to_sym, Regexp.last_match(2).to_sym
(series[base, labels])[field] = val
when labels.key?(:quantile) q = labels.delete(:quantile)
(entry = series[name, labels])[:quantiles] ||= {}
entry[:quantiles][q] = val
else metrics[name][:series] << { labels: labels, value: val }
end
end
end
metrics
end
|