jgraichen / telegraf-ruby

Send events from Ruby to a Telegraf agent
GNU Lesser General Public License v3.0
13 stars 7 forks source link
influx metrics rack rails ruby telegraf

Telegraf

Gem Version GitHub Workflow Status

Send events to a local Telegraf agent or anything that can receive the InfluxDB line protocol.

It further includes plugins for Rack, Rails, ActiveJob and Sidekiq to collect request events. See plugin usage details below.

Examples

Screenshot of a Grafana dashboard showing overview metrics about the application controllers performance such as slow actions, controller runtime breakdown, total time consumption Screenshot of a Grafana dashboard showing detailed metrics about an individual controller actions including a flamegraph for request performance
Screenshot of a Grafana dashboard showing detailed queue time metrics including percentiles and median for multiple applications Screenshot of a Grafana dashboard showing metrics about sidekiq background jobs such as runtime and errors

Installation

gem 'telegraf'

And then execute:

bundle

Or install it yourself as:

gem install telegraf

Usage as a library

Configure telegraf socket listener e.g.:

[[inputs.socket_listener]]
  service_address = "udp://localhost:8094"
telegraf = Telegraf::Agent.new 'udp://localhost:8094'
telegraf = Telegraf::Agent.new # default: 'udp://localhost:8094'

telegraf.write('demo',
    tags: {tag_a: 'A', tag_b: 'B'},
    values: {value_a: 1, value_b: 1.5})

telegraf.write([{
    series: 'demo',
    tags: {tag_a: 'A', tag_b: 'B'},
    values: {value_a: 1, value_b: 1.5}
}])

There is no buffer or batch handling, nor connection pooling or keep alive. Each #write creates a new connection (unless it's a datagram connection).

There is no exception handling.

Using the Rack and Rails plugins

This gem includes a Rails plugin and middlewares / adapters for Rack, ActiveJob and Sidekiq, to collect request and background worker events. You need to require them explicitly:

Rack

require "telegraf/rack"

agent = ::Telegraf::Agent.new
use ::Telegraf::Rack.new(series: 'rack', agent: agent, tags: {global: 'tag'})

See middleware class documentation for more details.

The Rack middleware supports parsing the X-Request-Start: t=<timestamp> header expecting a fractional (UTC) timestamp when the request has been started or first received by e.g. a load balancer. An additional value queue_ms with the queue time will be included.

Rails

The Rails plugin needs to be required, too, but will automatically install additional components (Rack, ActiveJob, Sidekiq and Rails-specific instrumentation).

# e.g. in application.rb

# Load rails plugin (!) or add `require: 'telegraf/rails'` to Gemfile
require "telegraf/rails"

class MyApplication > ::Rails::Application
  # Configure receiver
  config.telegraf.connect = "udp://localhost:8094"

  # Global tags added to all events. These will override
  # any local tag with the same name.
  config.telegraf.tags = {}

  # By default the Rack middleware to collect events is installed
  config.telegraf.rack.enabled = true
  config.telegraf.rack.series = "requests"
  config.telegraf.rack.tags = {}

  # These are the default settings when ActiveJob is detected
  config.telegraf.active_job.enabled = true
  config.telegraf.active_job.series = "active_job"
  config.telegraf.active_job.tags = {}

  # These are the default settings when Sidekiq is detected
  config.telegraf.sidekiq.enabled = true
  config.telegraf.sidekiq.series = "sidekiq"
  config.telegraf.sidekiq.tags = {}

  # Additionally the application is instrumented to tag events with
  # controller and action as well as to collect app, database and view timings
  config.telegraf.instrumentation = true
end

Received event example:

requests,action=index,controller=TestController,instance=TestController#index,method=GET,status=200 db_ms=0.0,view_ms=2.6217450003969134,action_ms=2.702335,app_ms=4.603561000294576,send_ms=0.09295000018028077,request_ms=4.699011000411701,queue_ms=0.00003000028323014

See the various classes' documentation for more details on the collected tags and values:

ActiveJob

require "telegraf/active_job"

agent = ::Telegraf::Agent.new
ActiveSupport::Notifications.subscribe(
  'perform.active_job',
  Telegraf::ActiveJob.new(agent: agent, series: 'active_job', tags: {global: 'tag'})
)

See plugin class documentation for more details.

Sidekiq

require "telegraf/sidekiq"

agent = ::Telegraf::Agent.new
Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add ::Telegraf::Sidekiq::Middleware, agent, series: 'sidekiq', tags: {global: 'tag'}
  end
end

See middleware class documentation for more details.

License

Copyright (C) 2017-2024 Jan Graichen

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/.