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



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

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.



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

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

#coerce_to_metric_spec_array(metric_names_or_specs, scope) ⇒ Object



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

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, use_scope = true, scoped_metric_only = false, scope = nil) ⇒ Object

If use_scope is true, two chained metrics are created, one with scope and one without If scoped_metric_only is true, only a scoped metric is created (used by rendering metrics which by definition are per controller only)



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

def get_stats(metric_name, use_scope = true, scoped_metric_only = false, scope = nil)
  scope ||= scope_name if use_scope
  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.



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

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)


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

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



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

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



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

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

#metric_specsObject



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

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.



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

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



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

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



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

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



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

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



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

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