telegraf 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2506d8a79e471b78413607796219aa467e330bed37f379482ae51f8b3f41d45
4
- data.tar.gz: 30202e32e4584499161208af9d1e355bb6b8770d425675738a7b4a3e4cad553d
3
+ metadata.gz: 3b39e326a00f3b9cfd52b4de13a300f662faa5be10e4ccdded8b0c9dc936700a
4
+ data.tar.gz: 9805358e5520df9ef662646e1eaece6f2236a0794b2a2ef854016829b06cb0d9
5
5
  SHA512:
6
- metadata.gz: bac63da09a0586326816bb0bf13ec2ca10900af04be4c058f5dd4b524a579ea5752c02573e8b275030dcba8cd66fbcf8b3b96f0e6e7933068ffaffc49197d8e3
7
- data.tar.gz: 261d7ef27d1afa299561581d946d85833a1254835ced37f9cf97d7a01e2364a7d43cd65cdfa1fe616216e75382373dcd840d1089751110549c4eb06d4651cf1d
6
+ metadata.gz: 24fbee3ab6231d5880a181de884adc59a7b7d90295a9a256d4eff06b8943f143977e5828e8fec5ee0845a72bf4aff2fb0e7e84fa23bd916ccb3f15106e843809
7
+ data.tar.gz: 3cca86f680123b2021e186ba5b09d34a09eb6e9be712a5269989ce230305d1bede1421de161e6cda4ae5a63278ecfbf033d3708f9f3e6dba7cab39a5469ecb26
@@ -1,19 +1,23 @@
1
1
  # vim: ft=yaml
2
2
  name: test
3
- on: [push, pull_request]
3
+
4
+ on:
5
+ - push
6
+ - pull_request
7
+
4
8
  jobs:
5
9
  rspec:
6
10
  name: Ruby ${{ matrix.ruby }} / ${{ matrix.gemfile }}
7
- runs-on: ubuntu-20.04
11
+ runs-on: ubuntu-22.04
8
12
 
9
13
  strategy:
10
14
  matrix:
11
15
  ruby:
16
+ - "3.3"
17
+ - "3.2"
12
18
  - "3.1"
13
19
  - "3.0"
14
20
  - "2.7"
15
- - "2.6"
16
- - "2.5"
17
21
  gemfile:
18
22
  - rails_5.2.gemfile
19
23
  - rails_6.0.gemfile
@@ -22,15 +26,17 @@ jobs:
22
26
  - rack_2.0.gemfile
23
27
  - rack_2.1.gemfile
24
28
  - rack_2.2.gemfile
29
+ - sidekiq_6.gemfile
30
+ - sidekiq_7.gemfile
25
31
  exclude:
32
+ - ruby: "3.3"
33
+ gemfile: rails_5.2.gemfile
34
+ - ruby: "3.2"
35
+ gemfile: rails_5.2.gemfile
26
36
  - ruby: "3.1"
27
37
  gemfile: rails_5.2.gemfile
28
38
  - ruby: "3.0"
29
39
  gemfile: rails_5.2.gemfile
30
- - ruby: "2.6"
31
- gemfile: rails_7.0.gemfile
32
- - ruby: "2.5"
33
- gemfile: rails_7.0.gemfile
34
40
  fail-fast: false
35
41
 
36
42
  env:
@@ -51,7 +57,7 @@ jobs:
51
57
 
52
58
  rubocop:
53
59
  name: rubocop
54
- runs-on: ubuntu-20.04
60
+ runs-on: ubuntu-22.04
55
61
 
56
62
  env:
57
63
  BUNDLE_WITHOUT: development
@@ -62,7 +68,7 @@ jobs:
62
68
  - uses: actions/checkout@master
63
69
  - uses: ruby/setup-ruby@v1
64
70
  with:
65
- ruby-version: 3.0
71
+ ruby-version: '3.3'
66
72
  bundler-cache: true
67
73
 
68
74
  - run: bundle exec rubocop --parallel --color
data/.rubocop.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  # vim: ft=yaml
2
2
 
3
3
  inherit_gem:
4
- my-rubocop: default.yml
4
+ rubocop-config: default.yml
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.5
7
+ TargetRubyVersion: 2.7
8
8
  SuggestExtensions: False
9
9
 
10
10
  RSpec/FilePath:
data/Appraisals CHANGED
@@ -41,3 +41,15 @@ appraise 'rack-2.2' do
41
41
  gem 'rack', '~> 2.2.0'
42
42
  end
43
43
  end
44
+
45
+ appraise 'sidekiq-6' do
46
+ group :test do
47
+ gem 'sidekiq', '~> 6.0'
48
+ end
49
+ end
50
+
51
+ appraise 'sidekiq-7' do
52
+ group :test do
53
+ gem 'sidekiq', '~> 7.0'
54
+ end
55
+ end
data/CHANGELOG.md CHANGED
@@ -4,11 +4,19 @@
4
4
 
5
5
  All notable changes to this project will be documented in this file.
6
6
 
7
- The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
8
- and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
9
-
10
7
  ## [Unreleased]
11
8
 
9
+ ## [3.0.0] - 2024-03-11
10
+
11
+ ### Added
12
+
13
+ - New standalone Influx line protocol serializer
14
+ - `before_send` filter option for agent and all plugins (#27)
15
+
16
+ ### Changed
17
+
18
+ - Require Ruby 2.7+
19
+
12
20
  ## [2.1.1] - 2022-08-23
13
21
 
14
22
  ### Fixed
@@ -64,7 +72,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
64
72
 
65
73
  - Remove `influxdb` not unnecessarily restrict users needing a specific influxdb client.
66
74
 
67
- [unreleased]: https://github.com/jgraichen/telegraf-ruby/compare/v2.1.1...HEAD
75
+ [Unreleased]: https://github.com/jgraichen/telegraf-ruby/compare/v3.0.0...HEAD
76
+ [3.0.0]: https://github.com/jgraichen/telegraf-ruby/compare/v2.1.1...v3.0.0
68
77
  [2.1.1]: https://github.com/jgraichen/telegraf-ruby/compare/v2.1.0...v2.1.1
69
78
  [2.1.0]: https://github.com/jgraichen/telegraf-ruby/compare/v2.0.0...v2.1.0
70
79
  [2.0.0]: https://github.com/jgraichen/telegraf-ruby/compare/v1.0.0...v2.0.0
data/Gemfile CHANGED
@@ -5,14 +5,14 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in telegraf.gemspec
6
6
  gemspec
7
7
 
8
- gem 'my-rubocop', github: 'jgraichen/my-rubocop', ref: 'v6'
9
8
  gem 'rake'
10
9
  gem 'rspec', '~> 3.8'
10
+ gem 'rubocop-config', github: 'jgraichen/rubocop-config', ref: 'v11'
11
11
 
12
12
  group :test do
13
13
  gem 'rack'
14
14
  gem 'rails'
15
- gem 'sidekiq', '~> 6.0'
15
+ gem 'sidekiq'
16
16
  end
17
17
 
18
18
  group :development do
data/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # Telegraf
2
2
 
3
3
  [![Gem Version](https://img.shields.io/gem/v/telegraf?logo=ruby)](https://rubygems.org/gems/telegraf)
4
- [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/jgraichen/telegraf-ruby/test?logo=github)](https://github.com/jgraichen/telegraf-ruby/actions)
4
+ [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/jgraichen/telegraf-ruby/test.yml?logo=github)](https://github.com/jgraichen/telegraf-ruby/actions)
5
5
 
6
6
  Send events to a local [Telegraf](https://github.com/influxdata/telegraf) agent or anything that can receive the InfluxDB line protocol.
7
7
 
8
8
  It further includes plugins for Rack, Rails, ActiveJob and Sidekiq to collect request events. See plugin usage details below.
9
9
 
10
- This gem only uses the line protocol from the `influxdb` gem and does not depend on any specific version. This may break in the future but does not restrict you in using a your preferred `influxdb` gem version.
11
-
12
10
  ## Installation
13
11
 
14
12
  ```ruby
@@ -17,20 +15,23 @@ gem 'telegraf'
17
15
 
18
16
  And then execute:
19
17
 
20
- $ bundle
18
+ ```console
19
+ bundle
20
+ ```
21
21
 
22
22
  Or install it yourself as:
23
23
 
24
- $ gem install telegraf
24
+ ```ruby
25
+ gem install telegraf
26
+ ```
25
27
 
26
28
  ## Usage as a library
27
29
 
28
30
  Configure telegraf socket listener e.g.:
29
31
 
30
- ```
32
+ ```toml
31
33
  [[inputs.socket_listener]]
32
34
  service_address = "udp://localhost:8094"
33
-
34
35
  ```
35
36
 
36
37
  ```ruby
@@ -48,13 +49,13 @@ telegraf.write([{
48
49
  }])
49
50
  ```
50
51
 
51
- There is not buffer or batch handling, nor connection pooling or keep alive. Each `#write` creates a new connection (unless it's a datagram connection).
52
+ 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).
52
53
 
53
54
  There is no exception handling.
54
55
 
55
56
  ## Using the Rack and Rails plugins
56
57
 
57
- This gem include a Rails plugin and middlewares / adapters for Rack, ActiveJob and Sidekiq to collect request and background worker events. They need to be explicitly required to be used:
58
+ 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:
58
59
 
59
60
  ### Rack
60
61
 
@@ -110,11 +111,12 @@ end
110
111
 
111
112
  Received event example:
112
113
 
113
- ```
114
+ ```text
114
115
  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
115
116
  ```
116
117
 
117
118
  See the various classes' documentation for more details on the collected tags and values:
119
+
118
120
  - [Rack middleware](lib/telegraf/rack.rb)
119
121
  - [Rails plugin](lib/telegraf/railtie.rb)
120
122
  - [ActiveJob plugin](lib/telegraf/active_job.rb)
@@ -142,17 +144,16 @@ require "telegraf/sidekiq"
142
144
  agent = ::Telegraf::Agent.new
143
145
  Sidekiq.configure_server do |config|
144
146
  config.server_middleware do |chain|
145
- chain.add ::Telegraf::Sidekiq::Middleware, agent: agent, series: 'sidekiq', tags: {global: 'tag'}
147
+ chain.add ::Telegraf::Sidekiq::Middleware, agent, series: 'sidekiq', tags: {global: 'tag'}
146
148
  end
147
149
  end
148
150
  ```
149
151
 
150
152
  See middleware [class documentation](lib/telegraf/sidekiq.rb) for more details.
151
153
 
152
-
153
154
  ## License
154
155
 
155
- Copyright (C) 2017-2020 Jan Graichen
156
+ Copyright (C) 2017-2024 Jan Graichen
156
157
 
157
158
  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.
158
159
 
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack", "~> 2.0.0"
12
11
  gem "rails"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack", "~> 2.1.0"
12
11
  gem "rails"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack", "~> 2.2.0"
12
11
  gem "rails"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack"
12
11
  gem "rails", "~> 5.2.0"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack"
12
11
  gem "rails", "~> 6.0.0"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack"
12
11
  gem "rails", "~> 6.1.0"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -4,13 +4,12 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "rake"
6
6
  gem "rspec", "~> 3.8"
7
- gem "rubocop", "~> 1.7"
8
- gem "rubocop-rspec", "~> 1.41"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
9
8
 
10
9
  group :test do
11
10
  gem "rack"
12
11
  gem "rails", "~> 7.0.0"
13
- gem "sidekiq", "~> 6.0"
12
+ gem "sidekiq"
14
13
  end
15
14
 
16
15
  group :development do
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "rspec", "~> 3.8"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
8
+
9
+ group :test do
10
+ gem "rack"
11
+ gem "rails"
12
+ gem "sidekiq", "~> 6.0"
13
+ end
14
+
15
+ group :development do
16
+ gem "appraisal"
17
+ gem "rake-release", "~> 1.2"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake"
6
+ gem "rspec", "~> 3.8"
7
+ gem "rubocop-config", github: "jgraichen/rubocop-config", ref: "v11"
8
+
9
+ group :test do
10
+ gem "rack"
11
+ gem "rails"
12
+ gem "sidekiq", "~> 7.0"
13
+ end
14
+
15
+ group :development do
16
+ gem "appraisal"
17
+ gem "rake-release", "~> 1.2"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -24,17 +24,16 @@ module Telegraf
24
24
  # Total job processing time.
25
25
  #
26
26
  class ActiveJob
27
- def initialize(agent:, series: 'active_job', tags: {})
28
- @agent = agent
29
- @series = series.to_s.freeze
30
- @tags = tags.freeze
27
+ include Plugin
28
+
29
+ def initialize(series: 'active_job', **kwargs)
30
+ super(series: series, **kwargs)
31
31
  end
32
32
 
33
33
  def call(_name, start, finish, _id, payload)
34
34
  job = payload[:job]
35
35
 
36
- @agent.write(
37
- @series,
36
+ point = Point.new(
38
37
  tags: {
39
38
  **@tags,
40
39
  job: job.class.name,
@@ -45,6 +44,8 @@ module Telegraf
45
44
  app_ms: ((finish - start) * 1000.0), # milliseconds
46
45
  },
47
46
  )
47
+
48
+ _write(point, before_send_kwargs: {payload: payload})
48
49
  end
49
50
  end
50
51
  end
@@ -1,15 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
4
+ require 'telegraf/serializer'
5
+
3
6
  module Telegraf
4
7
  class Agent
5
8
  DEFAULT_CONNECTION = 'udp://localhost:8094'
6
9
 
7
10
  attr_reader :uri, :logger, :tags
8
11
 
9
- def initialize(uri = nil, logger: nil, tags: {})
12
+ def initialize(uri = nil, logger: nil, tags: {}, before_send: nil)
10
13
  @uri = URI.parse(uri || DEFAULT_CONNECTION)
11
14
  @tags = tags
12
15
  @logger = logger
16
+ @serializer = Serializer.new
17
+ @before_send = before_send
13
18
  end
14
19
 
15
20
  def write(*args, **kwargs)
@@ -27,20 +32,19 @@ module Telegraf
27
32
  data = [{series: series || data.to_s, tags: tags, values: values.dup}]
28
33
  end
29
34
 
35
+ if @before_send
36
+ data = @before_send.call(data)
37
+ return unless data
38
+ end
39
+
30
40
  socket = connect @uri
31
- socket.write dump data
41
+ socket.write(@serializer.dump_all(data))
32
42
  ensure
33
43
  socket&.close
34
44
  end
35
45
 
36
46
  private
37
47
 
38
- def dump(data)
39
- data.each.map do |point|
40
- ::InfluxDB::PointValue.new(point).dump
41
- end.join("\n")
42
- end
43
-
44
48
  def connect(uri)
45
49
  case uri.scheme.downcase
46
50
  when 'unix'
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack'
4
+
5
+ module Telegraf
6
+ module Plugin
7
+ # Warning: `:values` member overrides `Struct#values` and it may be
8
+ # unexpected, but nothing we can change here as this is an import public API
9
+ # right now.
10
+ #
11
+ # rubocop:disable Lint/StructNewOverride
12
+ Point = Struct.new(:tags, :values, keyword_init: true) do
13
+ def initialize(tags: {}, values: {})
14
+ super
15
+ end
16
+ end
17
+ # rubocop:enable Lint/StructNewOverride
18
+
19
+ def initialize(agent:, series:, tags: {}, before_send: nil, **)
20
+ @agent = agent
21
+
22
+ @tags = tags.freeze
23
+ @series = String(series).freeze
24
+ @before_send = before_send
25
+ end
26
+
27
+ def _write(point, before_send_kwargs: {})
28
+ if @before_send
29
+ point = @before_send.call(point, **before_send_kwargs)
30
+ return unless point
31
+ end
32
+
33
+ @agent.write(@series, tags: point.tags, values: point.values)
34
+ end
35
+ end
36
+ end
data/lib/telegraf/rack.rb CHANGED
@@ -41,22 +41,15 @@ module Telegraf
41
41
  # contain a floating point timestamp in seconds.
42
42
  #
43
43
  class Rack
44
+ include ::Telegraf::Plugin
45
+
44
46
  FIELD_NAME = 'telegraf.rack.point'
45
47
  HEADER_REGEX = /t=(\d+(\.\d+)?)/.freeze
46
48
 
47
- # Warning: `:values` member overrides `Struct#values` and it may be
48
- # unexpected, but nothing we can change here as this is an import public API
49
- # right now.
50
- #
51
- # rubocop:disable Lint/StructNewOverride
52
- Point = Struct.new(:tags, :values)
53
- # rubocop:enable Lint/StructNewOverride
49
+ def initialize(app, agent:, series: 'rack', tags: {}, logger: nil, before_send: nil) # rubocop:disable Metrics/ParameterLists
50
+ super(agent: agent, series: series, tags: tags, before_send: before_send)
54
51
 
55
- def initialize(app, agent:, series: 'rack', tags: {}, logger: nil)
56
52
  @app = app
57
- @tags = tags.freeze
58
- @agent = agent
59
- @series = series.to_s.freeze
60
53
  @logger = logger
61
54
  end
62
55
 
@@ -66,7 +59,7 @@ module Telegraf
66
59
  end
67
60
 
68
61
  rack_start = ::Rack::Utils.clock_time
69
- point = env[FIELD_NAME] = Point.new(@tags.dup, {})
62
+ point = env[FIELD_NAME] = Point.new(tags: @tags.dup)
70
63
  point.values[:queue_ms] = queue_ms if queue_ms
71
64
 
72
65
  begin
@@ -98,7 +91,7 @@ module Telegraf
98
91
  point.values[:request_ms] = \
99
92
  (::Rack::Utils.clock_time - rack_start) * 1000 # milliseconds
100
93
 
101
- @agent.write(@series, tags: point.tags, values: point.values)
94
+ _write(point, before_send_kwargs: {request: ::Rack::Request.new(env)})
102
95
  rescue StandardError => e
103
96
  (@logger || env[::Rack::RACK_LOGGER])&.error(e)
104
97
  end
@@ -48,12 +48,14 @@ module Telegraf
48
48
  # Connect URI or tuple
49
49
  config.telegraf.connect = ::Telegraf::Agent::DEFAULT_CONNECTION
50
50
  config.telegraf.tags = {}
51
+ config.telegraf.before_send = nil
51
52
 
52
53
  # Install Rack middlewares
53
54
  config.telegraf.rack = ::ActiveSupport::OrderedOptions.new
54
55
  config.telegraf.rack.enabled = true
55
56
  config.telegraf.rack.series = 'requests'
56
57
  config.telegraf.rack.tags = {}
58
+ config.telegraf.rack.before_send = nil
57
59
 
58
60
  # Install request instrumentation
59
61
  config.telegraf.instrumentation = true
@@ -67,29 +69,37 @@ module Telegraf
67
69
  config.telegraf.active_job.enabled = defined?(::ActiveJob)
68
70
  config.telegraf.active_job.series = 'active_job'
69
71
  config.telegraf.active_job.tags = {}
72
+ config.telegraf.active_job.before_send = nil
70
73
 
71
74
  # Install Sidekiq middleware
72
75
  config.telegraf.sidekiq = ::ActiveSupport::OrderedOptions.new
73
76
  config.telegraf.sidekiq.enabled = defined?(::Sidekiq)
74
77
  config.telegraf.sidekiq.series = 'sidekiq'
75
78
  config.telegraf.sidekiq.tags = {}
79
+ config.telegraf.sidekiq.before_send = nil
76
80
 
77
81
  initializer 'telegraf.agent' do |app|
78
82
  app.config.telegraf.agent ||= \
79
- ::Telegraf::Agent.new \
83
+ ::Telegraf::Agent.new(
80
84
  app.config.telegraf.connect,
85
+ before_send: app.config.telegraf.before_send,
81
86
  logger: Rails.logger,
82
- tags: app.config.telegraf.tags
87
+ tags: app.config.telegraf.tags,
88
+ )
83
89
  end
84
90
 
85
91
  initializer 'telegraf.rack' do |app|
86
92
  next unless app.config.telegraf.rack.enabled
87
93
 
88
- app.config.middleware.insert 0, Telegraf::Rack, \
94
+ app.config.middleware.insert(
95
+ 0,
96
+ Telegraf::Rack,
89
97
  agent: app.config.telegraf.agent,
98
+ before_send: app.config.telegraf.rack.before_send,
99
+ logger: Rails.logger,
90
100
  series: app.config.telegraf.rack.series,
91
101
  tags: app.config.telegraf.rack.tags,
92
- logger: Rails.logger
102
+ )
93
103
  end
94
104
 
95
105
  initializer 'telegraf.instrumentation' do |app|
@@ -128,6 +138,7 @@ module Telegraf
128
138
  'perform.active_job',
129
139
  Telegraf::ActiveJob.new(
130
140
  agent: app.config.telegraf.agent,
141
+ before_send: app.config.telegraf.active_job.before_send,
131
142
  series: app.config.telegraf.active_job.series,
132
143
  tags: app.config.telegraf.active_job.tags,
133
144
  ),
@@ -142,6 +153,7 @@ module Telegraf
142
153
  chain.add Telegraf::Sidekiq::Middleware, \
143
154
  app.config.telegraf.agent,
144
155
  {
156
+ before_send: app.config.telegraf.sidekiq.before_send,
145
157
  series: app.config.telegraf.sidekiq.series,
146
158
  tags: app.config.telegraf.sidekiq.tags,
147
159
  }
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Telegraf
4
+ class Serializer
5
+ QUOTE_SERIES = /[ ,]/.freeze
6
+ QUOTE_TAG_KEY = /[ ,=]/.freeze
7
+ QUOTE_TAG_VALUE = /[ ,=]/.freeze
8
+ QUOTE_FIELD_KEY = /[ ,="]/.freeze
9
+ QUOTE_FIELD_VALUE = /[\\"]/.freeze
10
+ QUOTE_REPLACE = /[\t\r\n]+/.freeze
11
+
12
+ def dump_all(points)
13
+ points
14
+ .each
15
+ .filter_map {|point| dump(point) }
16
+ .join("\n")
17
+ end
18
+
19
+ def dump(point)
20
+ series = quote(point[:series], QUOTE_SERIES)
21
+ return '' if series.empty?
22
+
23
+ values = point.fetch(:values).filter_map do |key, value|
24
+ k = quote(key.to_s, QUOTE_FIELD_KEY)
25
+ v = encode_value(value)
26
+ next if k.empty? || v.nil?
27
+
28
+ "#{k}=#{v}"
29
+ end
30
+ return '' if values.empty?
31
+
32
+ tags = point[:tags]&.filter_map do |key, value|
33
+ k = quote(key.to_s, QUOTE_TAG_KEY)
34
+ v = quote(value.to_s, QUOTE_TAG_VALUE)
35
+ next if k.empty? || v.empty?
36
+
37
+ "#{k}=#{v}"
38
+ end
39
+
40
+ StringIO.new.tap do |io|
41
+ io << series
42
+ io << ',' << tags.sort.join(',') if !tags.nil? && tags.any?
43
+ io << ' ' << values.sort.join(',')
44
+ end.string
45
+ end
46
+
47
+ private
48
+
49
+ def encode_value(val)
50
+ if val.nil?
51
+ nil
52
+ elsif val.is_a?(Integer)
53
+ "#{val}i"
54
+ elsif val.is_a?(Numeric)
55
+ if val.nan? || val.infinite?
56
+ nil
57
+ else
58
+ val.to_s
59
+ end
60
+ else
61
+ "\"#{quote(val.to_s, QUOTE_FIELD_VALUE)}\""
62
+ end
63
+ end
64
+
65
+ def quote(str, rule)
66
+ str
67
+ .encode('UTF-8', 'UTF-8', invalid: :replace, undef: :replace, replace: '')
68
+ .gsub(QUOTE_REPLACE, ' ')
69
+ .gsub(rule) {|c| "\\#{c}" }
70
+ end
71
+ end
72
+ end
@@ -37,51 +37,55 @@ module Telegraf
37
37
  # Only present for "normal" (async) jobs (with tag `type` of "job").
38
38
  #
39
39
  class Middleware
40
+ include ::Telegraf::Plugin
41
+
40
42
  def initialize(agent, options = {})
41
- @agent = agent
42
- @series = options.fetch(:series, 'sidekiq').to_str.freeze
43
- @tags = options.fetch(:tags, {}).to_hash.freeze
43
+ options[:series] ||= 'sidekiq'
44
+
45
+ super(
46
+ **options,
47
+ agent: agent
48
+ )
44
49
  end
45
50
 
46
51
  def call(worker, job, queue)
47
52
  job_start = ::Time.now.utc
48
53
 
49
- tags = {
50
- **@tags,
51
- type: 'job',
52
- errors: true,
53
- retry: job.key?('retried_at'),
54
- queue: queue,
55
- worker: worker.class.name,
56
- }
57
-
58
- values = {
59
- retry_count: job['retry_count'],
60
- }.compact
54
+ point = Point.new(
55
+ tags: {
56
+ **@tags,
57
+ type: 'job',
58
+ errors: true,
59
+ retry: job.key?('retried_at'),
60
+ queue: queue,
61
+ worker: worker.class.name,
62
+ },
63
+ values: {
64
+ retry_count: job['retry_count'],
65
+ }.compact,
66
+ )
61
67
 
62
68
  # The "enqueued_at" key is not present for scheduled jobs.
63
69
  # See https://github.com/mperham/sidekiq/wiki/Job-Format.
64
70
  if job.key?('enqueued_at')
65
71
  enqueued_at = ::Time.at(job['enqueued_at'].to_f).utc
66
- values[:queue_ms] = (job_start - enqueued_at) * 1000 # milliseconds
72
+ point.values[:queue_ms] = (job_start - enqueued_at) * 1000 # milliseconds
67
73
  end
68
74
 
69
75
  # The "at" key is only present for scheduled jobs.
70
- tags[:type] = 'scheduled_job' if job.key?('at')
76
+ point.tags[:type] = 'scheduled_job' if job.key?('at')
71
77
 
72
78
  begin
73
79
  yield
74
80
 
75
81
  # If we get here, this was a successful execution
76
- tags[:errors] = false
82
+ point.tags[:errors] = false
77
83
  ensure
78
84
  job_stop = ::Time.now.utc
79
85
 
80
- values[:app_ms] = (job_stop - job_start) * 1000 # milliseconds
86
+ point.values[:app_ms] = (job_stop - job_start) * 1000 # milliseconds
81
87
 
82
- @agent.write(
83
- @series, tags: tags, values: values,
84
- )
88
+ _write(point, before_send_kwargs: {worker: worker, job: job, queue: queue})
85
89
  end
86
90
  end
87
91
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Telegraf
4
4
  module VERSION
5
- MAJOR = 2
6
- MINOR = 1
7
- PATCH = 1
5
+ MAJOR = 3
6
+ MINOR = 0
7
+ PATCH = 0
8
8
  STAGE = nil
9
9
  STRING = [MAJOR, MINOR, PATCH, STAGE].compact.join('.').freeze
10
10
 
data/lib/telegraf.rb CHANGED
@@ -2,8 +2,7 @@
2
2
 
3
3
  require 'telegraf/version'
4
4
 
5
- require 'influxdb'
6
-
7
5
  module Telegraf
8
6
  require 'telegraf/agent'
7
+ require 'telegraf/plugin'
9
8
  end
data/telegraf.gemspec CHANGED
@@ -27,7 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) {|f| File.basename(f) }
28
28
  spec.require_paths = ['lib']
29
29
 
30
- spec.required_ruby_version = '>= 2.5'
31
- spec.add_dependency 'influxdb'
32
- spec.add_development_dependency 'bundler'
30
+ spec.required_ruby_version = '>= 2.7'
33
31
  end
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: telegraf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-23 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: influxdb
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
11
+ date: 2024-03-11 00:00:00.000000000 Z
12
+ dependencies: []
41
13
  description: Metric Reporter to local telegraf agent
42
14
  email:
43
15
  - jgraichen@altimos.de
@@ -65,13 +37,17 @@ files:
65
37
  - gemfiles/rails_6.0.gemfile
66
38
  - gemfiles/rails_6.1.gemfile
67
39
  - gemfiles/rails_7.0.gemfile
40
+ - gemfiles/sidekiq_6.gemfile
41
+ - gemfiles/sidekiq_7.gemfile
68
42
  - lib/telegraf.rb
69
43
  - lib/telegraf/active_job.rb
70
44
  - lib/telegraf/agent.rb
71
45
  - lib/telegraf/grape.rb
46
+ - lib/telegraf/plugin.rb
72
47
  - lib/telegraf/rack.rb
73
48
  - lib/telegraf/rails.rb
74
49
  - lib/telegraf/railtie.rb
50
+ - lib/telegraf/serializer.rb
75
51
  - lib/telegraf/sidekiq.rb
76
52
  - lib/telegraf/version.rb
77
53
  - renovate.json
@@ -89,14 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
65
  requirements:
90
66
  - - ">="
91
67
  - !ruby/object:Gem::Version
92
- version: '2.5'
68
+ version: '2.7'
93
69
  required_rubygems_version: !ruby/object:Gem::Requirement
94
70
  requirements:
95
71
  - - ">="
96
72
  - !ruby/object:Gem::Version
97
73
  version: '0'
98
74
  requirements: []
99
- rubygems_version: 3.3.7
75
+ rubygems_version: 3.5.6
100
76
  signing_key:
101
77
  specification_version: 4
102
78
  summary: Metric Reporter to local telegraf agent