Class: ServerTiming::ResponseManipulator

Inherits:
Object
  • Object
show all
Defined in:
lib/server_timing/response_manipulator.rb

Overview

Adds the ‘Server-Timing’ response header w/metrics from Scout.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, rack_response) ⇒ ResponseManipulator

Returns a new instance of ResponseManipulator.



8
9
10
11
12
13
14
15
# File 'lib/server_timing/response_manipulator.rb', line 8

def initialize(env, rack_response)
  @env = env
  @rack_response = rack_response

  @rack_status = rack_response[0]
  @rack_headers = rack_response[1]
  @rack_body = rack_response[2]
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



6
7
8
# File 'lib/server_timing/response_manipulator.rb', line 6

def env
  @env
end

#rack_bodyObject (readonly)

Returns the value of attribute rack_body.



5
6
7
# File 'lib/server_timing/response_manipulator.rb', line 5

def rack_body
  @rack_body
end

#rack_headersObject (readonly)

Returns the value of attribute rack_headers.



5
6
7
# File 'lib/server_timing/response_manipulator.rb', line 5

def rack_headers
  @rack_headers
end

#rack_responseObject (readonly)

Returns the value of attribute rack_response.



4
5
6
# File 'lib/server_timing/response_manipulator.rb', line 4

def rack_response
  @rack_response
end

#rack_statusObject (readonly)

Returns the value of attribute rack_status.



5
6
7
# File 'lib/server_timing/response_manipulator.rb', line 5

def rack_status
  @rack_status
end

Instance Method Details

#add_headerObject



33
34
35
# File 'lib/server_timing/response_manipulator.rb', line 33

def add_header
  rack_headers['Server-Timing'] = payload
end

#callObject



17
18
19
20
21
22
23
# File 'lib/server_timing/response_manipulator.rb', line 17

def call
  return rack_response unless preconditions_met?

  store_metrics
  add_header
  rebuild_rack_response
end

#payloadObject



64
65
66
67
68
# File 'lib/server_timing/response_manipulator.rb', line 64

def payload
  headers = server_timing_metrics.map(&:to_header)
  headers << TimingMetric.new('Total', server_timing_metrics.map(&:duration).reduce(0,:+)).to_header
  headers.join(",")
end

#preconditions_met?Boolean

Checks if we should attempt to gather metrics.

Returns:

  • (Boolean)


26
27
28
29
30
31
# File 'lib/server_timing/response_manipulator.rb', line 26

def preconditions_met?
  # tracked_request.root_layer is nil for Rack apps ... unsure why.
  return false unless tracked_request.root_layer

  Auth.permitted?
end

#rebuild_rack_responseObject



70
71
72
# File 'lib/server_timing/response_manipulator.rb', line 70

def rebuild_rack_response
  [rack_status, rack_headers, rack_body]
end

#server_timing_metricsObject



59
60
61
# File 'lib/server_timing/response_manipulator.rb', line 59

def server_timing_metrics
  @server_timing_metrics ||= store.metrics.map { |meta, stats| TimingMetric.from_scout(meta,stats)}
end

#storeObject



41
42
43
# File 'lib/server_timing/response_manipulator.rb', line 41

def store
  @store ||= ServerTiming::Store.new
end

#store_metricsObject



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/server_timing/response_manipulator.rb', line 45

def store_metrics
  layer_finder = ScoutApm::LayerConverters::FindLayerByType.new(tracked_request)
  converters = [ScoutApm::LayerConverters::MetricConverter]

  walker = ScoutApm::LayerConverters::DepthFirstWalker.new(tracked_request.root_layer)
  converters = converters.map do |klass|
    instance = klass.new(ScoutApm::Agent.instance.context, tracked_request, layer_finder, store)
    instance.register_hooks(walker)
    instance
  end
  walker.walk
  converters.each {|i| i.record! }
end

#tracked_requestObject



37
38
39
# File 'lib/server_timing/response_manipulator.rb', line 37

def tracked_request
  @tracked_request ||= ScoutApm::RequestManager.lookup
end