Module: NewRelic::Agent::Instrumentation::Sinatra::Tracer

Includes:
ControllerInstrumentation
Included in:
Build::Prepend, Prepend
Defined in:
lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb

Constant Summary collapse

INSTRUMENTATION_NAME =
'Sinatra'

Constants included from ControllerInstrumentation

ControllerInstrumentation::NR_DEFAULT_OPTIONS, ControllerInstrumentation::NR_DO_NOT_TRACE_KEY, ControllerInstrumentation::NR_IGNORE_APDEX_KEY, ControllerInstrumentation::NR_IGNORE_ENDUSER_KEY

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ControllerInstrumentation

#perform_action_with_newrelic_trace

Methods included from ControllerInstrumentation::ClassMethods

#add_transaction_tracer, #already_added_transaction_tracer?, #build_method_names, #generate_argument_list, #newrelic_ignore, #newrelic_ignore_apdex, #newrelic_ignore_aspect, #newrelic_ignore_enduser, #newrelic_read_attr, #newrelic_write_attr, #parse_punctuation

Class Method Details

.included(clazz) ⇒ Object



18
19
20
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 18

def self.included(clazz)
  clazz.extend(self)
end

Instance Method Details

#build_with_tracing(*args, &block) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 35

def build_with_tracing(*args, &block)
  unless NewRelic::Agent.config[:disable_sinatra_auto_middleware]
    newrelic_middlewares.each do |middleware_class|
      try_to_use(self, middleware_class)
    end
  end
  yield
end

#dispatch_with_tracingObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 94

def dispatch_with_tracing
  NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)

  request_params = get_request_params
  filtered_params = ::NewRelic::Agent::ParameterFiltering::apply_filters(request.env, request_params || {})

  name = TransactionNamer.initial_transaction_name(request)
  perform_action_with_newrelic_trace(:category => :sinatra,
    :name => name,
    :params => filtered_params) do
    begin
      yield
    ensure
      # Will only see an error raised if :show_exceptions is true, but
      # will always see them in the env hash if they occur
      had_error = env.has_key?('sinatra.error')
      ::NewRelic::Agent.notice_error(env['sinatra.error']) if had_error
    end
  end
end

#do_not_trace?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 115

def do_not_trace?
  Ignorer.should_ignore?(self, :routes)
end

#get_request_paramsObject



85
86
87
88
89
90
91
92
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 85

def get_request_params
  begin
    @request.params
  rescue => e
    NewRelic::Agent.logger.debug('Failed to get params from Rack request.', e)
    nil
  end
end

#ignore_apdex?Boolean

Overrides ControllerInstrumentation implementation

Returns:

  • (Boolean)


120
121
122
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 120

def ignore_apdex?
  Ignorer.should_ignore?(self, :apdex)
end

#ignore_enduser?Boolean

Overrides ControllerInstrumentation implementation

Returns:

  • (Boolean)


125
126
127
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 125

def ignore_enduser?
  Ignorer.should_ignore?(self, :enduser)
end

#install_lockObject



44
45
46
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 44

def install_lock
  @install_lock ||= Mutex.new
end

#newrelic_middlewaresObject



27
28
29
30
31
32
33
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 27

def newrelic_middlewares
  middlewares = [NewRelic::Rack::BrowserMonitoring]
  if NewRelic::Rack::AgentHooks.needed?
    middlewares << NewRelic::Rack::AgentHooks
  end
  middlewares
end

#newrelic_request_headers(_) ⇒ Object

Expected method for supporting ControllerInstrumentation



23
24
25
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 23

def newrelic_request_headers(_)
  request.env
end

#process_route_with_tracing(*args) ⇒ Object

Capture last route we’ve seen. Will set for transaction on route_eval



57
58
59
60
61
62
63
64
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 57

def process_route_with_tracing(*args)
  begin
    env['newrelic.last_route'] = args[0]
  rescue => e
    ::NewRelic::Agent.logger.debug('Failed determining last route in Sinatra', e)
  end
  yield
end

#route_eval_with_tracing(*args) ⇒ Object

If a transaction name is already set, this call will tromple over it. This is intentional, as typically passing to a separate route is like an entirely separate transaction, so we pick up the new name.

If we’re ignored, this remains safe, since set_transaction_name care for the gating on the transaction’s existence for us.



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 72

def route_eval_with_tracing(*args)
  begin
    if txn_name = TransactionNamer.transaction_name_for_route(env, request)
      ::NewRelic::Agent::Transaction.set_default_transaction_name(
        "#{self.class.name}/#{txn_name}", :sinatra
      )
    end
  rescue => e
    ::NewRelic::Agent.logger.debug('Failed during route_eval to set transaction name', e)
  end
  yield
end

#try_to_use(app, clazz) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb', line 48

def try_to_use(app, clazz)
  install_lock.synchronize do
    # The following line needs else branch coverage
    has_middleware = app.middleware && app.middleware.any? { |info| info && info[0] == clazz } # rubocop:disable Style/SafeNavigation
    app.use(clazz) unless has_middleware
  end
end