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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +23 -8
- data/lib/puma/plugin/statsd.rb +64 -68
- metadata +48 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e2328d05d42da5a0259a1db34e06d577b80640c055601c4689581a9ffdc3d66
|
4
|
+
data.tar.gz: e69455947064fb8fd3ce30af4d5a97853e0511f0998d11f424924b0fcfe2452f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 885de8a9ccc13c7f1bb95fe160b18c27e204fe71d68fc13e75024cba27ff83f235b1a7876e4b37bb3482987583962eccf7d2cef3d051fba3b48a7c452145bfce
|
7
|
+
data.tar.gz: 7560d10e03f50ad938408e735026ecec85b8542c79a3e394d1cc8c5250521875c16b5e56e6401776262a6e2ea9aeaafb3b589792b49562c92b0744044a3f8392
|
data/CHANGELOG.md
ADDED
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
|
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
|
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-
|
95
|
-
|
109
|
+
This gem is a fork of the excellent [puma-plugin-systemd][puma-plugin-systemd] by
|
110
|
+
Samuel Cochran.
|
96
111
|
|
97
|
-
[puma-plugin-
|
112
|
+
[puma-plugin-systemd]: https://github.com/sj26/puma-plugin-systemd
|
98
113
|
|
99
114
|
Other puma plugins that were helpful references:
|
100
115
|
|
data/lib/puma/plugin/statsd.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
13
|
+
def initialize
|
14
|
+
@host = ENV.fetch(ENV_NAME, nil)
|
15
|
+
@port = ENV.fetch("STATSD_PORT", 8125)
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def enabled?
|
19
|
+
!!host
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
# Wrap puma's stats in a safe API
|
37
|
+
class PumaStats
|
38
|
+
def initialize(stats)
|
39
|
+
@stats = stats
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
def clustered?
|
43
|
+
@stats.has_key? "workers"
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
def workers
|
47
|
+
@stats.fetch("workers", 1)
|
48
|
+
end
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
def booted_workers
|
51
|
+
@stats.fetch("booted_workers", 1)
|
52
|
+
end
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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 =
|
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 #{
|
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
|
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:
|
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: '
|
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: '
|
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: '
|
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: '
|
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
|
-
|
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
|