Module: NewRelic::Agent::Instrumentation::MiddlewareTracing

Included in:
MiddlewareProxy, Rack::AgentMiddleware
Defined in:
lib/new_relic/agent/instrumentation/middleware_tracing.rb

Constant Summary collapse

TXN_STARTED_KEY =
'newrelic.transaction_started'
CONTENT_TYPE =
'Content-Type'
CONTENT_LENGTH =
'Content-Length'

Instance Method Summary collapse

Instance Method Details

#_nr_has_middleware_tracingObject



33
34
35
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 33

def _nr_has_middleware_tracing
  true
end

#build_transaction_options(env, first_middleware) ⇒ Object



37
38
39
40
41
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 37

def build_transaction_options(env, first_middleware)
  opts = transaction_options
  opts = merge_first_middleware_options(opts, env) if first_middleware
  opts
end

#call(env) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
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/middleware_tracing.rb', line 83

def call(env)
  first_middleware = note_transaction_started(env)

  state = NewRelic::Agent::Tracer.state

  begin
    options = build_transaction_options(env, first_middleware)

    finishable = Tracer.start_transaction_or_segment(
      name: options[:transaction_name],
      category: category,
      options: options
    )

    events.notify(:before_call, env) if first_middleware

    result = target == self ? traced_call(env) : target.call(env)

    if first_middleware
      capture_response_attributes(state, result)
      events.notify(:after_call, env, result)
    end

    result
  rescue Exception => e
    NewRelic::Agent.notice_error(e)
    raise e
  ensure
    finishable&.finish
  end
end

#capture_http_response_code(state, result) ⇒ Object



55
56
57
58
59
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 55

def capture_http_response_code(state, result)
  if result.is_a?(Array) && state.current_transaction
    state.current_transaction.http_response_code = result[0]
  end
end

#capture_response_attributes(state, result) ⇒ Object



77
78
79
80
81
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 77

def capture_response_attributes(state, result)
  capture_http_response_code(state, result)
  capture_response_content_type(state, result)
  capture_response_content_length(state, result)
end

#capture_response_content_length(state, result) ⇒ Object



68
69
70
71
72
73
74
75
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 68

def capture_response_content_length(state, result)
  if result.is_a?(Array) && state.current_transaction
    _, headers, _ = result
    length = headers[CONTENT_LENGTH]
    length = length.reduce(0) { |sum, h| sum + h.to_i } if length.is_a?(Array)
    state.current_transaction.response_content_length = length
  end
end

#capture_response_content_type(state, result) ⇒ Object



61
62
63
64
65
66
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 61

def capture_response_content_type(state, result)
  if result.is_a?(Array) && state.current_transaction
    _, headers, _ = result
    state.current_transaction.response_content_type = headers[CONTENT_TYPE]
  end
end

#eventsObject



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

def events
  NewRelic::Agent.instance.events
end

#merge_first_middleware_options(opts, env) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 43

def merge_first_middleware_options(opts, env)
  opts[:apdex_start_time] = QueueTime.parse_frontend_timestamp(env)
  # this case is for the rare occasion that an app is using Puma::Rack
  # without having ::Rack as a dependency
  opts[:request] = ::Rack::Request.new(env.dup) if defined? ::Rack
  opts
end

#note_transaction_started(env) ⇒ Object



51
52
53
# File 'lib/new_relic/agent/instrumentation/middleware_tracing.rb', line 51

def note_transaction_started(env)
  env[TXN_STARTED_KEY] = true unless env[TXN_STARTED_KEY]
end