Class: RailsObservatory::TimeSeries::QueryBuilder

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rails_observatory/redis/time_series/query_builder.rb

Instance Method Summary collapse

Constructor Details

#initialize(series_class) ⇒ QueryBuilder

Returns a new instance of QueryBuilder.



6
7
8
9
10
11
12
13
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 6

def initialize(series_class)
  @series_class = series_class
  @conditions = {}
  @samples = nil
  @range_set = false
  @group = nil
  @range = (nil..)
end

Instance Method Details

#avgObject



53
54
55
56
57
58
59
60
61
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 53

def avg
  if @group
    @agg_type = :avg
    @samples = 1
    to_a.index_by { _1.labels[@group] }
  else
    raise "Cannot avg without grouping"
  end
end

#downsample(samples, using:) ⇒ Object



34
35
36
37
38
39
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 34

def downsample(samples, using:)
  clone = self.clone
  clone.instance_variable_set(:@samples, samples)
  clone.instance_variable_set(:@agg_type, using)
  clone
end

#eachObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 73

def each
  @range = ActiveSupport::IsolatedExecutionState[:observatory_slice] || (nil..) unless @range_set
  agg_duration = build_agg_duration
  mrange_args = ['TS.MRANGE', from_ts, to_ts, 'WITHLABELS']
  mrange_args.push('LATEST') if @range.end.nil?
  if @agg_type && @samples
    if @range.end.present?
      mrange_args.push("ALIGN", 'end')
    elsif @range.begin.present?
      mrange_args.push("ALIGN", 'start')
    end
    mrange_args.push("AGGREGATION", @agg_type.to_s.upcase, agg_duration, "EMPTY")
  end
  mrange_args.push('FILTER', *ts_filters)

  # puts mrange_args.join(" ")
  res = @series_class.redis.call(mrange_args)
  return if res.nil?

  res.each do |name, labels, data|
    yield @series_class.new(
      name:,
      labels: Hash[*labels.flatten],
      data:,
      time_range: @range,
      agg_duration: agg_duration
    )
  end
end

#group(label) ⇒ Object



21
22
23
24
25
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 21

def group(label)
  clone = self.clone
  clone.instance_variable_set(:@group, label)
  clone
end

#lastObject



63
64
65
66
67
68
69
70
71
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 63

def last
  if @group
    @agg_type = :last
    @samples = 1
    to_a.index_by { _1.labels[@group] }
  else
    raise "Cannot last without grouping"
  end
end

#slice(range) ⇒ Object



27
28
29
30
31
32
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 27

def slice(range)
  clone = self.clone
  clone.instance_variable_set(:@range_set, true)
  clone.instance_variable_set(:@range, range)
  clone
end

#sumObject



43
44
45
46
47
48
49
50
51
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 43

def sum
  if @group
    @agg_type = :sum
    @samples = 1
    to_a.index_by { _1.labels[@group] }.transform_values { _1.value }
  else
    raise "Cannot sum without grouping"
  end
end

#where(**conditions) ⇒ Object



15
16
17
18
19
# File 'lib/rails_observatory/redis/time_series/query_builder.rb', line 15

def where(**conditions)
  clone = self.clone
  clone.instance_variable_set(:@conditions, @conditions.merge(conditions))
  clone
end