Module: OneApm::Collector::StatsEngine::MetricStats

Included in:
OneApm::Collector::StatsEngine
Defined in:
lib/one_apm/collector/stats_engine/metric_stats.rb

Overview

Handles methods related to actual Metric collection

Constant Summary collapse

OA_SCOPE_PLACEHOLDER =
'__SCOPE__'.freeze

Instance Method Summary collapse

Instance Method Details

#apply_rules_to_metric_data(rules_engine, stats_hash) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 197

def apply_rules_to_metric_data(rules_engine, stats_hash)
  renamed_stats = OneApm::Collector::StatsHash.new(stats_hash.started_at)
  stats_hash.each do |spec, stats|
    new_name = rules_engine.rename(spec.name)
    unless new_name.nil?
      new_spec = OneApm::MetricSpec.new(new_name, spec.scope)
      renamed_stats[new_spec].merge!(stats)
    end
  end
  renamed_stats
end

#clear_statsObject

For use by test code only.



224
225
226
227
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 224

def clear_stats
  reset!
  OneApm::Agent::BusyCalculator.reset
end

#coerce_to_metric_spec_array(metric_names_or_specs, scope) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 209

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 << OneApm::MetricSpec.new(name_or_spec)
      specs << OneApm::MetricSpec.new(name_or_spec, scope) if scope
    when OneApm::MetricSpec
      specs << name_or_spec
    end
  end
  specs
end

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

Deprecated.

This method is deprecated and not thread safe, and should not be used by any new client code. Use OneApm::Manager.record_metric instead.

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



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 131

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[OneApm::MetricSpec.new(metric_name, scope)]
    else
      unscoped_spec = OneApm::MetricSpec.new(metric_name)
      unscoped_stats = @stats_hash[unscoped_spec]
      if scope && scope != metric_name
        scoped_spec = OneApm::MetricSpec.new(metric_name, scope)
        scoped_stats = @stats_hash[scoped_spec]
        stats = OneApm::Metrics::ChainedStats.new(scoped_stats, unscoped_stats)
      else
        stats = unscoped_stats
      end
    end
  end
  stats
end

#get_stats_no_scope(metric_name) ⇒ Object

Deprecated.

This method is deprecated and not thread safe, and should not be used by any new client code. Use OneApm::Manager.record_metric instead.

Lookup the Stats object for a given unscoped metric, returning a new Stats object if one did not exist previously.



117
118
119
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 117

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

#harvest!Object



189
190
191
192
193
194
195
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 189

def harvest!
  now = Time.now
  snapshot = reset!
  snapshot = apply_rules_to_metric_data(@metric_rules, snapshot)
  snapshot.harvested_at = now
  snapshot
end

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

Returns a stat if one exists, otherwise returns nil.



152
153
154
155
156
157
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 152

def lookup_stats(metric_name, scope_name = '')
  spec = OneApm::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



176
177
178
179
180
181
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 176

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

#merge_transaction_metrics!(txn_metrics, scope) ⇒ Object



183
184
185
186
187
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 183

def merge_transaction_metrics!(txn_metrics, scope)
  with_stats_lock do
    @stats_hash.merge_transaction_metrics!(txn_metrics, scope)
  end
end

#metric_specsObject



237
238
239
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 237

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.



231
232
233
234
235
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 231

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

#record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics = nil, value = nil, aux = nil, &blk) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 89

def record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics=nil, value=nil, aux=nil, &blk)
  txn = state.current_transaction
  if txn
    txn.metrics.record_scoped(scoped_metric, value, aux, &blk)
    txn.metrics.record_unscoped(scoped_metric, value, aux, &blk)
    if summary_metrics
      txn.metrics.record_unscoped(summary_metrics, value, aux, &blk)
    end
  else
    specs = coerce_to_metric_spec_array(scoped_metric, nil)
    if summary_metrics
      specs.concat(coerce_to_metric_spec_array(summary_metrics, nil))
    end
    with_stats_lock do
      @stats_hash.record(specs, value, aux, &blk)
    end
  end
end

#record_unscoped_metrics(state, metric_names, value = nil, aux = nil, &blk) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 53

def record_unscoped_metrics(state, metric_names, value=nil, aux=nil, &blk)
  txn = state.current_transaction
  if txn
    txn.metrics.record_unscoped(metric_names, value, aux, &blk)
  else
    specs = coerce_to_metric_spec_array(metric_names, nil)
    with_stats_lock do
      @stats_hash.record(specs, value, aux, &blk)
    end
  end
end

#reset!Object



167
168
169
170
171
172
173
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 167

def reset!
  with_stats_lock do
    old = @stats_hash
    @stats_hash = StatsHash.new
    old
  end
end

#tl_record_scoped_and_unscoped_metrics(scoped_metric, summary_metrics = nil, value = nil, aux = nil, &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.

Like tl_record_unscoped_metrics, but records a scoped metric as well.

This is an internal method, subject to change at any time. Client apps and gems should use the public API (OneApm::Manager.record_metric) instead.

The given scoped_metric will be recoded as both a scoped and an unscoped metric. The summary_metrics will be recorded as unscoped metrics only.

If called during a transaction, all metrics will be attached to the Transaction, and not merged into the global set of metrics until the end of the transaction.

If called outside of a transaction, only the unscoped metrics will be recorded, directly into the global set of metrics (under a lock).



84
85
86
87
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 84

def tl_record_scoped_and_unscoped_metrics(scoped_metric, summary_metrics=nil, value=nil, aux=nil, &blk)
  state = OneApm::TransactionState.tl_get
  record_scoped_and_unscoped_metrics(state, scoped_metric, summary_metrics, value, aux, &blk)
end

#tl_record_supportability_metric_count(metric, value) ⇒ Object

Helper for recording a straight value into the count



160
161
162
163
164
165
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 160

def tl_record_supportability_metric_count(metric, value)
  real_name = "Supportability/#{metric}"
  tl_record_unscoped_metrics(real_name) do |stat|
    stat.call_count = value
  end
end

#tl_record_unscoped_metrics(metric_names, value = nil, aux = nil, &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.

Update the unscoped metrics given in metric_names. metric_names may be either a single name, or an array of names.

This is an internal method, subject to change at any time. Client apps and gems should use the public API (OneApm::Manager.record_metric) instead.

There are four ways to use this method:

  1. With a numeric value, it will update the Stats objects associated with the given metrics by calling record_data_point(value, aux). aux will be treated in this case as the exclusive time associated with the call being recorded.

  2. With a value of :apdex_s, :apdex_t, or :apdex_f, it will treat the associated stats as an Apdex metric, updating it to reflect the occurrence of a transaction falling into the given category. The aux value in this case should be the apdex threshold used in bucketing the request.

  3. If a block is given, value and aux will be ignored, and instead the Stats object associated with each named unscoped metric will be yielded to the block for customized update logic.

  4. If value is a Stats instance, it will be merged into the Stats associated with each named unscoped metric.

If this method is called during a transaction, the metrics will be attached to the Transaction, and not merged into the global set until the end of the transaction.

Otherwise, the metrics will be recorded directly into the global set of metrics, under a lock.



48
49
50
51
# File 'lib/one_apm/collector/stats_engine/metric_stats.rb', line 48

def tl_record_unscoped_metrics(metric_names, value=nil, aux=nil, &blk)
  state = OneApm::TransactionState.tl_get
  record_unscoped_metrics(state, metric_names, value, aux, &blk)
end