puma-plugin-statsd 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +23 -8
  4. data/lib/puma/plugin/statsd.rb +64 -68
  5. metadata +48 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed64454a76b4776e4362b9e149ecaa09f9212c4482e5c4e6d2a1a2a33fc06c80
4
- data.tar.gz: e5ad995a36ee4ae265ff02a07172ede4f1614e5263777293e81bc620ed2013fd
3
+ metadata.gz: 3e2328d05d42da5a0259a1db34e06d577b80640c055601c4689581a9ffdc3d66
4
+ data.tar.gz: e69455947064fb8fd3ce30af4d5a97853e0511f0998d11f424924b0fcfe2452f
5
5
  SHA512:
6
- metadata.gz: 924aec321ac03bff296515886d8e2ad67e111c6ad769be6a97732a51c45fa26179b0d2dea815f5351e3e5d844ecc6b6a7c684b0cbc643b6ff33f86a9f6d1c0d3
7
- data.tar.gz: 0da8be2a3781dd14c6804054f7698eb7840c2dd3d7515b8ad9c7e642636f1231bd000570e4b7eff9497730d98add97e6948283fa0d7c57ead73fc4573c261a84
6
+ metadata.gz: 885de8a9ccc13c7f1bb95fe160b18c27e204fe71d68fc13e75024cba27ff83f235b1a7876e4b37bb3482987583962eccf7d2cef3d051fba3b48a7c452145bfce
7
+ data.tar.gz: 7560d10e03f50ad938408e735026ecec85b8542c79a3e394d1cc8c5250521875c16b5e56e6401776262a6e2ea9aeaafb3b589792b49562c92b0744044a3f8392
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # CHANGELOG
2
+
3
+ ## 0.1.0 2019-07-06
4
+
5
+ * The statsd port is now configurable
6
+ * Support puma 4.x
7
+
8
+ ## 0.0.1 2018-07-17
9
+
10
+ Initial Release
data/README.md CHANGED
@@ -10,8 +10,6 @@ that puma can provide:
10
10
  * puma.pool_capacity
11
11
  * puma.max_threads
12
12
 
13
- Puma already natively supports [socket activation][socket-activation].
14
-
15
13
  [puma]: https://github.com/puma/puma
16
14
  [statsd]: https://github.com/etsy/statsd
17
15
 
@@ -39,14 +37,14 @@ plugin :statsd
39
37
 
40
38
  ## Usage
41
39
 
42
- Ensure you have an environment variable set that points to a statsd host, then boot your puma app as usual
40
+ Ensure you have an environment variable set that points to a statsd host, then boot your puma app as usual. Optionally you may specify a port (default is 8125).
43
41
 
44
42
  ```
45
43
  STATSD_HOST=127.0.0.1 bundle exec puma
46
44
  ```
47
45
 
48
46
  ```
49
- STATSD_HOST=127.0.0.1 MY_POD_NAME=foo bundle exec puma
47
+ STATSD_HOST=127.0.0.1 STATSD_PORT=9125 bundle exec puma
50
48
  ```
51
49
 
52
50
  ### Datadog Integration
@@ -58,7 +56,7 @@ Should you be reporting the puma metrics to a dogstatsd server, you can set
58
56
  tags via the following two environment variables.
59
57
 
60
58
  `MY_POD_NAME` adds a `pod_name` tag to the metrics. The `MY_POD_NAME`
61
- environment variable is recommended in th datadog kubernetes setup
59
+ environment variable is recommended in the datadog kubernetes setup
62
60
  documentation, and for puma apps deployed to kubernetes it's very helpful to
63
61
  have the option to report on specific pods.
64
62
 
@@ -89,12 +87,29 @@ env:
89
87
  Bug reports and pull requests are welcome on GitHub at
90
88
  https://github.com/yob/puma-plugin-statsd.
91
89
 
90
+ ## Testing the data being sent to statsd
91
+
92
+ Start a pretend statsd server that listens for UDP packets on port 8125:
93
+
94
+ ruby devtools/statsd-to-stdout.rb
95
+
96
+ Start puma:
97
+
98
+ STATSD_HOST=127.0.0.1 bundle exec puma devtools/config.ru --config devtools/puma-config.rb
99
+
100
+ Throw some traffic at it, either with curl or a tool like ab:
101
+
102
+ curl http://127.0.0.1:9292/
103
+ ab -n 10000 -c 20 http://127.0.0.1:9292/
104
+
105
+ Watch the output of the UDP server process - you should see statsd data printed to stdout.
106
+
92
107
  ## Acknowledgements
93
108
 
94
- This gem is a fork of the excellent [puma-plugin-statsd][puma-plugin-statsd] by
95
- Sam Cochran.
109
+ This gem is a fork of the excellent [puma-plugin-systemd][puma-plugin-systemd] by
110
+ Samuel Cochran.
96
111
 
97
- [puma-plugin-statsd]: https://github.com/sj26/puma-plugin-systemd
112
+ [puma-plugin-systemd]: https://github.com/sj26/puma-plugin-systemd
98
113
 
99
114
  Other puma plugins that were helpful references:
100
115
 
@@ -1,90 +1,90 @@
1
1
  # coding: utf-8, frozen_string_literal: true
2
-
3
2
  require "json"
4
- require 'socket'
5
3
  require "puma"
6
4
  require "puma/plugin"
5
+ require 'socket'
7
6
 
7
+ class StatsdConnector
8
+ ENV_NAME = "STATSD_HOST"
9
+ STATSD_TYPES = { count: 'c', gauge: 'g' }
8
10
 
9
- Puma::Plugin.create do
10
-
11
- class Statsd
12
- ENV_NAME = "STATSD_HOST"
13
- STATSD_PORT = 8125
14
- STATSD_TYPES = { count: 'c', gauge: 'g' }
11
+ attr_reader :host, :port
15
12
 
16
- attr_reader :host
13
+ def initialize
14
+ @host = ENV.fetch(ENV_NAME, nil)
15
+ @port = ENV.fetch("STATSD_PORT", 8125)
16
+ end
17
17
 
18
- def initialize
19
- @host = ENV.fetch(ENV_NAME, nil)
20
- end
18
+ def enabled?
19
+ !!host
20
+ end
21
21
 
22
- def enabled?
23
- !!host
22
+ def send(metric_name:, value:, type:, tags: {})
23
+ data = "#{metric_name}:#{value}|#{STATSD_TYPES.fetch(type)}"
24
+ if tags.any?
25
+ tag_str = tags.map { |k,v| "#{k}:#{v}" }.join(",")
26
+ data = "#{data}|##{tag_str}"
24
27
  end
25
28
 
26
- def send(metric_name:, value:, type:, tags: {})
27
- data = "#{metric_name}:#{value}|#{STATSD_TYPES.fetch(type)}"
28
- if tags.any?
29
- tag_str = tags.map { |k,v| "#{k}:#{v}" }.join(",")
30
- data = "#{data}|##{tag_str}"
31
- end
32
-
33
- UDPSocket.new.send(data, 0, host, STATSD_PORT)
34
- end
29
+ socket = UDPSocket.new
30
+ socket.send(data, 0, host, port)
31
+ ensure
32
+ socket.close
35
33
  end
34
+ end
36
35
 
37
- # Wrap puma's stats in a safe API
38
- class PumaStats
39
- def initialize(stats)
40
- @stats = stats
41
- end
36
+ # Wrap puma's stats in a safe API
37
+ class PumaStats
38
+ def initialize(stats)
39
+ @stats = stats
40
+ end
42
41
 
43
- def clustered?
44
- @stats.has_key? "workers"
45
- end
42
+ def clustered?
43
+ @stats.has_key? "workers"
44
+ end
46
45
 
47
- def workers
48
- @stats.fetch("workers", 1)
49
- end
46
+ def workers
47
+ @stats.fetch("workers", 1)
48
+ end
50
49
 
51
- def booted_workers
52
- @stats.fetch("booted_workers", 1)
53
- end
50
+ def booted_workers
51
+ @stats.fetch("booted_workers", 1)
52
+ end
54
53
 
55
- def running
56
- if clustered?
57
- @stats["worker_status"].map { |s| s["last_status"].fetch("running", 0) }.inject(0, &:+)
58
- else
59
- @stats.fetch("running", 0)
60
- end
54
+ def running
55
+ if clustered?
56
+ @stats["worker_status"].map { |s| s["last_status"].fetch("running", 0) }.inject(0, &:+)
57
+ else
58
+ @stats.fetch("running", 0)
61
59
  end
60
+ end
62
61
 
63
- def backlog
64
- if clustered?
65
- @stats["worker_status"].map { |s| s["last_status"].fetch("backlog", 0) }.inject(0, &:+)
66
- else
67
- @stats.fetch("backlog", 0)
68
- end
62
+ def backlog
63
+ if clustered?
64
+ @stats["worker_status"].map { |s| s["last_status"].fetch("backlog", 0) }.inject(0, &:+)
65
+ else
66
+ @stats.fetch("backlog", 0)
69
67
  end
68
+ end
70
69
 
71
- def pool_capacity
72
- if clustered?
73
- @stats["worker_status"].map { |s| s["last_status"].fetch("pool_capacity", 0) }.inject(0, &:+)
74
- else
75
- @stats.fetch("pool_capacity", 0)
76
- end
70
+ def pool_capacity
71
+ if clustered?
72
+ @stats["worker_status"].map { |s| s["last_status"].fetch("pool_capacity", 0) }.inject(0, &:+)
73
+ else
74
+ @stats.fetch("pool_capacity", 0)
77
75
  end
76
+ end
78
77
 
79
- def max_threads
80
- if clustered?
81
- @stats["worker_status"].map { |s| s["last_status"].fetch("max_threads", 0) }.inject(0, &:+)
82
- else
83
- @stats.fetch("max_threads", 0)
84
- end
78
+ def max_threads
79
+ if clustered?
80
+ @stats["worker_status"].map { |s| s["last_status"].fetch("max_threads", 0) }.inject(0, &:+)
81
+ else
82
+ @stats.fetch("max_threads", 0)
85
83
  end
86
84
  end
85
+ end
87
86
 
87
+ Puma::Plugin.create do
88
88
  # Puma creates the plugin when encountering `plugin` in the config.
89
89
  def initialize(loader)
90
90
  @loader = loader
@@ -94,12 +94,12 @@ Puma::Plugin.create do
94
94
  def start(launcher)
95
95
  @launcher = launcher
96
96
 
97
- @statsd = Statsd.new
97
+ @statsd = ::StatsdConnector.new
98
98
  if @statsd.enabled?
99
99
  @launcher.events.debug "statsd: enabled (host: #{@statsd.host})"
100
100
  register_hooks
101
101
  else
102
- @launcher.events.debug "statsd: not enabled (no #{Statsd::ENV_NAME} env var found)"
102
+ @launcher.events.debug "statsd: not enabled (no #{StatsdConnector::ENV_NAME} env var found)"
103
103
  end
104
104
  end
105
105
 
@@ -113,10 +113,6 @@ Puma::Plugin.create do
113
113
  JSON.parse(Puma.stats)
114
114
  end
115
115
 
116
- def stats
117
- PumaStats.new(fetch_stats)
118
- end
119
-
120
116
  def tags
121
117
  tags = {}
122
118
  if ENV.has_key?("MY_POD_NAME")
@@ -134,6 +130,7 @@ Puma::Plugin.create do
134
130
  loop do
135
131
  @launcher.events.debug "statsd: notify statsd"
136
132
  begin
133
+ stats = ::PumaStats.new(fetch_stats)
137
134
  @statsd.send(metric_name: "puma.workers", value: stats.workers, type: :gauge, tags: tags)
138
135
  @statsd.send(metric_name: "puma.booted_workers", value: stats.booted_workers, type: :gauge, tags: tags)
139
136
  @statsd.send(metric_name: "puma.running", value: stats.running, type: :gauge, tags: tags)
@@ -147,5 +144,4 @@ Puma::Plugin.create do
147
144
  end
148
145
  end
149
146
  end
150
-
151
147
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma-plugin-statsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Healy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-17 00:00:00.000000000 Z
11
+ date: 2019-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: puma
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.12'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '3.12'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: json
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -42,30 +48,30 @@ dependencies:
42
48
  name: bundler
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
- - - "~>"
51
+ - - ">="
46
52
  - !ruby/object:Gem::Version
47
- version: '1.13'
53
+ version: '0'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
- - - "~>"
58
+ - - ">="
53
59
  - !ruby/object:Gem::Version
54
- version: '1.13'
60
+ version: '0'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rake
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - "~>"
65
+ - - ">="
60
66
  - !ruby/object:Gem::Version
61
- version: '10.0'
67
+ version: '0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - "~>"
72
+ - - ">="
67
73
  - !ruby/object:Gem::Version
68
- version: '10.0'
74
+ version: '0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: minitest
71
77
  requirement: !ruby/object:Gem::Requirement
@@ -80,12 +86,41 @@ dependencies:
80
86
  - - "~>"
81
87
  - !ruby/object:Gem::Version
82
88
  version: '5.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: sinatra
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rack
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
83
117
  description:
84
118
  email: james@yob.id.au
85
119
  executables: []
86
120
  extensions: []
87
121
  extra_rdoc_files: []
88
122
  files:
123
+ - CHANGELOG.md
89
124
  - MIT-LICENSE
90
125
  - README.md
91
126
  - lib/puma/plugin/statsd.rb
@@ -108,8 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
143
  - !ruby/object:Gem::Version
109
144
  version: '0'
110
145
  requirements: []
111
- rubyforge_project:
112
- rubygems_version: 2.7.6
146
+ rubygems_version: 3.0.1
113
147
  signing_key:
114
148
  specification_version: 4
115
149
  summary: Send puma metrics to statsd via a background thread