Module: OneApm::Agent::Instrumentation::TransactionBase::ClassMethods

Defined in:
lib/one_apm/inst/transaction_base.rb

Instance Method Summary collapse

Instance Method Details

#add_transaction_tracer(method, options = {}) ⇒ Object

Add transaction tracing to the given method. This will treat the given method as a main entrypoint for instrumentation, just like controller actions are treated by default. Useful especially for background tasks.

Example for background job:

class Job
  include OneApm::Agent::Instrumentation::TransactionBase
  def run(task)
     ...
  end

  # Instrument run so tasks show up under task.name.
  # Note single quoting to defer eval to runtime.
  add_transaction_tracer :run, :name => '#{args[0].name}'
end

Here’s an example of a controller that uses a dispatcher action to invoke operations which you want treated as top level actions, so they aren’t all lumped into the invoker action.

MyController < ActionController::Base
  include OneApm::Agent::Instrumentation::TransactionBase
  # dispatch the given op to the method given by the service parameter.
  def invoke_operation
    op = params['operation']
    send op
  end
  # Ignore the invoker to avoid double counting
  oneapm_ignore :only => 'invoke_operation'
  # Instrument the operations:
  add_transaction_tracer :print
  add_transaction_tracer :show
  add_transaction_tracer :forward
end

Here’s an example of how to pass contextual information into the transaction so it will appear in transaction traces:

class Job
  include OneApm::Agent::Instrumentation::TransactionBase
  def process(account)
     ...
  end
  # Include the account name in the transaction details.  Note the single
  # quotes to defer eval until call time.
  add_transaction_tracer :process, :params => '{ :account_name => args[0].name }'
end

See OneApm::Agent::Instrumentation::TransactionBase#perform_action_with_oneapm_trace for the full list of available options.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/one_apm/inst/transaction_base.rb', line 151

def add_transaction_tracer(method, options = {})
  options[:name] ||= method.to_s

  argument_list = generate_argument_list(options)
  traced_method, punctuation = parse_punctuation(method)
  with_method_name, without_method_name = build_method_names(traced_method, punctuation)

  if already_added_transaction_tracer?(self, with_method_name)
    OneApm::Manager.logger.warn("Transaction tracer already in place for class = #{self.name}, method = #{method.to_s}, skipping")
    return
  end

  class_eval <<-EOC
    def #{with_method_name}(*args, &block)
      perform_action_with_oneapm_trace(#{argument_list.join(',')}) do
        #{without_method_name}(*args, &block)
      end
    end
  EOC

  visibility = OneApm::Helper.instance_method_visibility self, method

  alias_method without_method_name, method.to_s
  alias_method method.to_s, with_method_name

  send visibility, method
  send visibility, with_method_name

  OneApm::Manager.logger.debug("Traced transaction: class = #{self.name}, method = #{method.to_s}, options = #{options.inspect}")
end

#already_added_transaction_tracer?(target, with_method_name) ⇒ Boolean

Returns:

  • (Boolean)


207
208
209
210
211
212
213
# File 'lib/one_apm/inst/transaction_base.rb', line 207

def already_added_transaction_tracer?(target, with_method_name)
  if OneApm::Helper.instance_methods_include?(target, with_method_name)
    true
  else
    false
  end
end

#build_method_names(traced_method, punctuation) ⇒ Object



200
201
202
203
204
205
# File 'lib/one_apm/inst/transaction_base.rb', line 200

def build_method_names(traced_method, punctuation)
  [
    "#{traced_method.to_s}_with_oneapm_transaction_trace#{punctuation}",
    "#{traced_method.to_s}_without_oneapm_transaction_trace#{punctuation}"
    ]
end

#generate_argument_list(options) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/one_apm/inst/transaction_base.rb', line 186

def generate_argument_list(options)
  options.map do |key, value|
    value = if value.is_a?(Symbol)
      value.inspect
    elsif key == :params
      value.to_s
    else
      %Q["#{value.to_s}"]
    end

    %Q[:#{key} => #{value}]
  end
end

#oneapm_ignore(options = {}) ⇒ Object

Have OneApm ignore actions in this controller. Specify the actions as hash options using :except and :only. If no actions are specified, all actions are ignored.



56
57
58
# File 'lib/one_apm/inst/transaction_base.rb', line 56

def oneapm_ignore(options = {})
  oneapm_ignore_aspect(OA_DO_NOT_TRACE_KEY, options)
end

#oneapm_ignore_apdex(options = {}) ⇒ Object

Have OneApm omit apdex measurements on the given actions. Typically used for actions that are not user facing or that skew your overall apdex measurement. Accepts :except and :only options.



66
67
68
# File 'lib/one_apm/inst/transaction_base.rb', line 66

def oneapm_ignore_apdex(options = {})
  oneapm_ignore_aspect(OA_IGNORE_APDEX_KEY, options)
end

#oneapm_ignore_aspect(property, options = {}) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/one_apm/inst/transaction_base.rb', line 78

def oneapm_ignore_aspect(property, options = {})
  if options.empty?
    oneapm_write_attr property, true
  elsif !options.is_a?(Hash)
    OneApm::Manager.logger.error "oneapm_#{property} takes an optional hash with :only and :except lists of actions (illegal argument type '#{options.class}')"
  else
    oneapm_write_attr property, options
  end
end

#oneapm_ignore_enduser(options = {}) ⇒ Object

Have OneApm skip install javascript_instrumentation



74
75
76
# File 'lib/one_apm/inst/transaction_base.rb', line 74

def oneapm_ignore_enduser(options = {})
  oneapm_ignore_aspect(OA_IGNORE_ENDUSER_KEY, options)
end

#oneapm_read_attr(attr_name) ⇒ Object



92
93
94
# File 'lib/one_apm/inst/transaction_base.rb', line 92

def oneapm_read_attr(attr_name)
  instance_variable_get(attr_name)
end

#oneapm_write_attr(attr_name, value) ⇒ Object



88
89
90
# File 'lib/one_apm/inst/transaction_base.rb', line 88

def oneapm_write_attr(attr_name, value)
  instance_variable_set(attr_name, value)
end

#parse_punctuation(method) ⇒ Object



182
183
184
# File 'lib/one_apm/inst/transaction_base.rb', line 182

def parse_punctuation(method)
  [method.to_s.sub(/([?!=])$/, ''), $1]
end