Class: NewRelic::Agent::StatsHash

Inherits:
Object
  • Object
show all
Defined in:
lib/new_relic/agent/stats_engine/stats_hash.rb

Defined Under Namespace

Classes: StatsHashLookupError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(started_at = Process.clock_gettime(Process::CLOCK_REALTIME)) ⇒ StatsHash

Returns a new instance of StatsHash.



35
36
37
38
39
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 35

def initialize(started_at = Process.clock_gettime(Process::CLOCK_REALTIME))
  @started_at = started_at.to_f
  @scoped = Hash.new { |h, k| h[k] = NewRelic::Agent::Stats.new }
  @unscoped = Hash.new { |h, k| h[k] = NewRelic::Agent::Stats.new }
end

Instance Attribute Details

#harvested_atObject

Returns the value of attribute harvested_at.



33
34
35
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 33

def harvested_at
  @harvested_at
end

#started_atObject

Returns the value of attribute started_at.



33
34
35
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 33

def started_at
  @started_at
end

Instance Method Details

#==(other) ⇒ Object



53
54
55
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 53

def ==(other)
  self.to_h == other.to_h
end

#[](key) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 64

def [](key)
  case key
  when String
    @unscoped[key]
  when NewRelic::MetricSpec
    if key.scope.empty?
      @unscoped[key.name]
    else
      @scoped[key]
    end
  end
end

#eachObject



77
78
79
80
81
82
83
84
85
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 77

def each
  @scoped.each do |k, v|
    yield(k, v)
  end
  @unscoped.each do |k, v|
    spec = NewRelic::MetricSpec.new(k)
    yield(spec, v)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 87

def empty?
  @unscoped.empty? && @scoped.empty?
end

#handle_stats_lookup_error(key, hash, error) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 121

def handle_stats_lookup_error(key, hash, error)
  # This only happen in the case of a corrupted default_proc
  # Side-step it manually, notice the issue, and carry on....
  NewRelic::Agent.instance.error_collector \
    .notice_agent_error(StatsHashLookupError.new(error, hash, key))
  stats = NewRelic::Agent::Stats.new
  hash[key] = stats
  # Try to restore the default_proc so we won't continually trip the error
  if hash.respond_to?(:default_proc=)
    hash.default_proc = proc { |h, k| h[k] = NewRelic::Agent::Stats.new }
  end
  stats
end

#marshal_dumpObject



41
42
43
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 41

def marshal_dump
  [@started_at, Hash[@scoped], Hash[@unscoped]]
end

#marshal_load(data) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 45

def marshal_load(data)
  @started_at = data.shift
  @scoped = Hash.new { |h, k| h[k] = NewRelic::Agent::Stats.new }
  @unscoped = Hash.new { |h, k| h[k] = NewRelic::Agent::Stats.new }
  @scoped.merge!(data.shift)
  @unscoped.merge!(data.shift)
end

#merge!(other) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 135

def merge!(other)
  @started_at = other.started_at if other.started_at < @started_at

  other.each do |spec, val|
    if spec.scope.empty?
      merge_or_insert(@unscoped, spec.name, val)
    else
      merge_or_insert(@scoped, spec, val)
    end
  end
  self
end

#merge_or_insert(target, name, stats) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 159

def merge_or_insert(target, name, stats)
  if target.has_key?(name)
    target[name].merge!(stats)
  else
    target[name] = stats.dup
  end
end

#merge_transaction_metrics!(txn_metrics, scope) ⇒ Object



148
149
150
151
152
153
154
155
156
157
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 148

def merge_transaction_metrics!(txn_metrics, scope)
  txn_metrics.each_unscoped do |name, stats|
    merge_or_insert(@unscoped, name, stats)
  end
  txn_metrics.each_scoped do |name, stats|
    spec = NewRelic::MetricSpec.new(name, scope)
    merge_or_insert(@scoped, spec, stats)
    merge_or_insert(@unscoped, name, stats)
  end
end

#record(metric_specs, value = nil, aux = nil, &blk) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 101

def record(metric_specs, value = nil, aux = nil, &blk)
  Array(metric_specs).each do |metric_spec|
    if metric_spec.scope.empty?
      key = metric_spec.name
      hash = @unscoped
    else
      key = metric_spec
      hash = @scoped
    end

    begin
      stats = hash[key]
    rescue NoMethodError => e
      stats = handle_stats_lookup_error(key, hash, e)
    end

    stats.record(value, aux, &blk)
  end
end

#sizeObject



91
92
93
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 91

def size
  @unscoped.size + @scoped.size
end

#to_hObject



57
58
59
60
61
62
# File 'lib/new_relic/agent/stats_engine/stats_hash.rb', line 57

def to_h
  hash = {}
  @scoped.each { |k, v| hash[k] = v }
  @unscoped.each { |k, v| hash[NewRelic::MetricSpec.new(k)] = v }
  hash
end