Module: NewRelic::Agent::StatsEngine::MetricStats

Included in:
NewRelic::Agent::StatsEngine
Defined in:
lib/new_relic/agent/stats_engine/metric_stats.rb

Overview

Handles methods related to actual Metric collection

Constant Summary collapse

SCOPE_PLACEHOLDER =
:__SCOPE__

Instance Method Summary collapse

Instance Method Details

#apply_rules_to_metric_data(rules_engine, stats_hash) ⇒ Object



144
145
146
147
148
149
150
151
152
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 144

def apply_rules_to_metric_data(rules_engine, stats_hash)
  renamed_stats = NewRelic::Agent::StatsHash.new
  stats_hash.each do |spec, stats|
    new_name = rules_engine.rename(spec.name)
    new_spec = NewRelic::MetricSpec.new(new_name, spec.scope)
    renamed_stats[new_spec].merge!(stats)
  end
  renamed_stats
end

#clear_statsObject

For use by test code only.



169
170
171
172
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 169

def clear_stats
  reset_stats
  NewRelic::Agent::BusyCalculator.reset
end

#coerce_to_metric_spec_array(metric_names_or_specs, scope) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 154

def coerce_to_metric_spec_array(metric_names_or_specs, scope)
  specs = []
  Array(metric_names_or_specs).map do |name_or_spec|
    case name_or_spec
    when String
      specs << NewRelic::MetricSpec.new(name_or_spec)
      specs << NewRelic::MetricSpec.new(name_or_spec, scope) if scope
    when NewRelic::MetricSpec
      specs << name_or_spec
    end
  end
  specs
end

#get_stats(metric_name, _ = true, scoped_metric_only = false, scope = nil) ⇒ Object

If scoped_metric_only is true, only a scoped metric is created (used by rendering metrics which by definition are per controller only) Leaving second, unused parameter for compatibility



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 64

def get_stats(metric_name, _ = true, scoped_metric_only = false, scope = nil)
  stats = nil
  with_stats_lock do
    if scoped_metric_only
      stats = @stats_hash[NewRelic::MetricSpec.new(metric_name, scope)]
    else
      unscoped_spec = NewRelic::MetricSpec.new(metric_name)
      unscoped_stats = @stats_hash[unscoped_spec]
      if scope && scope != metric_name
        scoped_spec = NewRelic::MetricSpec.new(metric_name, scope)
        scoped_stats = @stats_hash[scoped_spec]
        stats = NewRelic::Agent::ChainedStats.new(scoped_stats, unscoped_stats)
      else
        stats = unscoped_stats
      end
    end
  end
  stats
end

#get_stats_no_scope(metric_name) ⇒ Object

a simple accessor for looking up a stat with no scope - returns a new stats object if no stats object for that metric exists yet



58
59
60
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 58

def get_stats_no_scope(metric_name)
  get_stats(metric_name, false)
end

#harvest_timeslice_data(old_stats_hash, rules_engine = RulesEngine.new) ⇒ Object

Harvest the timeslice data. First recombine current statss with any previously unsent metrics, clear out stats cache, and return the current stats.



138
139
140
141
142
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 138

def harvest_timeslice_data(old_stats_hash, rules_engine=RulesEngine.new)
  snapshot = reset_stats
  snapshot = apply_rules_to_metric_data(rules_engine, snapshot)
  snapshot.merge!(old_stats_hash)
end

#in_transaction?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 186

def in_transaction?
  !!transaction_stats_hash
end

#lookup_stats(metric_name, scope_name = '') ⇒ Object

Returns a stat if one exists, otherwise returns nil. If you want auto-initialization, use one of get_stats or get_stats_no_scope



86
87
88
89
90
91
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 86

def lookup_stats(metric_name, scope_name = '')
  spec = NewRelic::MetricSpec.new(metric_name, scope_name)
  with_stats_lock do
    @stats_hash.has_key?(spec) ? @stats_hash[spec] : nil
  end
end

#merge!(other_stats_hash) ⇒ Object

merge data from previous harvests into this stats engine



128
129
130
131
132
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 128

def merge!(other_stats_hash)
  with_stats_lock do
    @stats_hash.merge!(other_stats_hash)
  end
end

#metric_specsObject



182
183
184
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 182

def metric_specs
  with_stats_lock { @stats_hash.keys }
end

#metricsObject

Returns all of the metric names of all the stats in the engine. For use by test code only.



176
177
178
179
180
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 176

def metrics
  with_stats_lock do
    @stats_hash.keys.map { |spec| spec.to_s }
  end
end

#record_metrics(metric_names_or_specs, value = nil, options = {}, &blk) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Lookup and write to the named metric in a single call.

This method is thead-safe, and is preferred to the lookup / modify method pairs (e.g. get_stats + record_data_point)



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 20

def record_metrics(metric_names_or_specs, value=nil, options={}, &blk)
  scoped = options[:scoped]
  scope = in_transaction? ? SCOPE_PLACEHOLDER : nil
  effective_scope = scoped && scope

  specs = coerce_to_metric_spec_array(metric_names_or_specs, effective_scope)

  if in_transaction?
    transaction_stats_hash.record(specs, value, &blk)
  else
    with_stats_lock do
      @stats_hash.record(specs, value, &blk)
    end
  end
end

#record_metrics_internal(metric_specs, value, aux) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Fast-path version of the #record_metrics version above, used in performance-sensitive code paths

metric_specs must be an Array of MetricSpec objects value and aux are passed directly to the corresponding parameters of StatsHash#record



44
45
46
47
48
49
50
51
52
53
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 44

def record_metrics_internal(metric_specs, value, aux)
  tsh = transaction_stats_hash
  if tsh
    tsh.record(metric_specs, value, aux)
  else
    with_stats_lock do
      @stats_hash.record(metric_specs, value, aux)
    end
  end
end

#record_supportability_metric(metric, value = nil) ⇒ Object

Helper method for recording supportability metrics consistently



110
111
112
113
114
115
116
117
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 110

def record_supportability_metric(metric, value=nil)
  real_name = "Supportability/#{metric}"
  if block_given?
    record_metrics(real_name) { |stat| yield stat }
  else
    record_metrics(real_name, value)
  end
end

#record_supportability_metric_count(metric, value) ⇒ Object

Helper for recording a straight value into the count



103
104
105
106
107
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 103

def record_supportability_metric_count(metric, value)
  record_supportability_metric(metric) do |stat|
    stat.call_count = value
  end
end

#record_supportability_metric_timed(metric) ⇒ Object

Helper method for timing supportability metrics



94
95
96
97
98
99
100
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 94

def record_supportability_metric_timed(metric)
  start_time = Time.now
  yield
ensure
  duration = (Time.now - start_time).to_f
  record_supportability_metric(metric, duration)
end

#reset_statsObject



119
120
121
122
123
124
125
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 119

def reset_stats
  with_stats_lock do
    old = @stats_hash
    @stats_hash = StatsHash.new
    old
  end
end