Class: Telegraf::Rack

Inherits:
Object
  • Object
show all
Defined in:
lib/telegraf/rack.rb

Overview

Telegraf::Rack

This rack middleware collects request metrics and sends them to the telegraf agent. A ‘Point` data structure is added to the Rack environment to assign custom tags and values. This point can be accessed using the environment key defined in `::Telegraf::Rack::FIELD_NAME`.

Example:

if (point = request.env[::Telegraf::Rack::FIELD_NAME])
  point.tags[:tag] = 'tag'
  point.values[:value] = 10
end

Tags:

  • ‘status`:

    Response status unless request errored
    

Values:

  • ‘request_ms`:

    Total request processing time including response sending.
    
  • ‘app_ms`:

    Total application processing time.
    
  • ‘send_ms`:

    Time took to send the response body.
    
  • ‘queue_ms`:

    Queue time calculated from a `X-Request-Start` header if present. The
    header is expected to be formatted like this `t=<timestamp>` and
    contain a floating point timestamp in seconds.
    

Defined Under Namespace

Classes: Point

Constant Summary collapse

FIELD_NAME =
'telegraf.rack.point'
HEADER_REGEX =
/t=(\d+(\.\d+)?)/.freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, agent:, series: 'rack', tags: {}, logger: nil) ⇒ Rack

rubocop:enable Lint/StructNewOverride



55
56
57
58
59
60
61
# File 'lib/telegraf/rack.rb', line 55

def initialize(app, agent:, series: 'rack', tags: {}, logger: nil)
  @app = app
  @tags = tags.freeze
  @agent = agent
  @series = series.to_s.freeze
  @logger = logger
end

Instance Method Details

#call(env) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/telegraf/rack.rb', line 63

def call(env)
  if (request_start = extract_request_start(env))
    queue_ms = (::Time.now.utc - request_start) * 1000 # milliseconds
  end

  rack_start = ::Rack::Utils.clock_time
  point = env[FIELD_NAME] = Point.new(@tags.dup, {})
  point.values[:queue_ms] = queue_ms if queue_ms

  begin
    begin
      status, headers, body = @app.call(env)
    ensure
      point.tags[:status] ||= status || -1
      point.values[:app_ms] = \
        (::Rack::Utils.clock_time - rack_start) * 1000 # milliseconds
    end

    send_start = ::Rack::Utils.clock_time
    proxy = ::Rack::BodyProxy.new(body) do
      point.values[:send_ms] = \
        (::Rack::Utils.clock_time - send_start) * 1000 # milliseconds

      finish(env, point, rack_start)
    end

    [status, headers, proxy]
  ensure
    finish(env, point, rack_start) unless proxy
  end
end