Module: RailsMetrics::Store

Extended by:
ActiveSupport::Concern
Included in:
ORM::ActiveRecord
Defined in:
lib/rails_metrics/store.rb

Overview

This module contains the default API for storing notifications. Imagine that you configure your store to be the Metric class:

RailsMetrics.set_store { Metric }

Whenever a notification comes, RailsMetrics instantiates a new store and call configure on it with the instrumentation arguments:

metric = Metric.new
metric.configure(args)
metric

After all metrics are configured they are nested and save_metrics! is called, where each metric saves itself and its children.

The method save_metrics! is implemented below and it requires the method save_metric! to be implemented in the target class.

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

VALID_ORDERS =
%w(earliest latest slowest fastest).freeze

Instance Method Summary collapse

Instance Method Details

#child_of?(node) ⇒ Boolean

Returns:

  • (Boolean)

100
101
102
# File 'lib/rails_metrics/store.rb', line 100

def child_of?(node)
  node.parent_of?(self)
end

#childrenObject

Stores the children of this metric when a tree is created.


79
80
81
# File 'lib/rails_metrics/store.rb', line 79

def children
  @children ||= []
end

#configure(args) ⇒ Object

Configure the current metric by setting the values yielded by the instrumentation event.


51
52
53
54
55
56
# File 'lib/rails_metrics/store.rb', line 51

def configure(args)
  self.name       = args[0].to_s
  self.started_at = args[1]
  self.duration   = (args[2] - args[1]) * 1000000
  self.payload    = RailsMetrics::PayloadParser.filter(name, args[4])
end

#destroyObject

Destroy all children if it's a request metric.


121
122
123
124
# File 'lib/rails_metrics/store.rb', line 121

def destroy
  self.class.by_request_id(self.id).delete_all if rack_request?
  super
end

#duration_in_msObject


62
63
64
# File 'lib/rails_metrics/store.rb', line 62

def duration_in_ms
  self.duration * 0.001
end

#duration_in_usObject


58
59
60
# File 'lib/rails_metrics/store.rb', line 58

def duration_in_us
  self.duration
end

#exclusive_durationObject


66
67
68
# File 'lib/rails_metrics/store.rb', line 66

def exclusive_duration
  @exclusive_duration ||= self.duration - children.sum(&:duration)
end

#exclusive_duration_in_msObject


74
75
76
# File 'lib/rails_metrics/store.rb', line 74

def exclusive_duration_in_ms
  self.exclusive_duration * 0.001
end

#exclusive_duration_in_usObject


70
71
72
# File 'lib/rails_metrics/store.rb', line 70

def exclusive_duration_in_us
  self.exclusive_duration
end

#parent_of?(node) ⇒ Boolean

Returns if the current node is the parent of the given node. If this is a new record, we can use started_at values to detect parenting. However, if it was already saved, we lose microseconds information from timestamps and we must rely solely in id and parent_id information.

Returns:

  • (Boolean)

91
92
93
94
95
96
97
98
# File 'lib/rails_metrics/store.rb', line 91

def parent_of?(node)
  if new_record?
    start = (self.started_at - node.started_at) * 1000000
    start <= 0 && (start + self.duration >= node.duration)
  else
    self.id == node.parent_id
  end
end

#rack_request?Boolean

Returns:

  • (Boolean)

83
84
85
# File 'lib/rails_metrics/store.rb', line 83

def rack_request?
  self.name == "rack.request"
end

#save_metrics!(request_id = nil, parent_id = nil) ⇒ Object

Save the current metric and all of its children by properly setting the request and parent ids.


106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rails_metrics/store.rb', line 106

def save_metrics!(request_id=nil, parent_id=nil)
  self.request_id, self.parent_id = request_id, parent_id
  save_metric!

  children.each do |child|
    child.save_metrics!(request_id || self.id, self.id)
  end

  unless self.request_id
    self.request_id ||= self.id
    save_metric!
  end
end