sensu-plugins-puma 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e0f983857efdf659eb67057528e9d77c147ee12
4
- data.tar.gz: 742496cb03278b1862041b692e1b93319af0121c
3
+ metadata.gz: 42e1211d4781f6c859884577e4b58fc5fbd05bee
4
+ data.tar.gz: 5deaa8958edd9599b415c791946441249d4b5813
5
5
  SHA512:
6
- metadata.gz: b66dea7f27ef420e7f89b9392b80a47a295028e06b1a52c279c41eeeda27404bf5c0d50a1ca8a2201216669a63d9816a8d355e305e459caa91947d3c7a08a492
7
- data.tar.gz: e066256365d9445d94807f507e80a1b99e497bbfdc46a8787909065322399bbf65c8170522b2a2d7e8b7e738c05b395c30e41ac7847bdf0155690f0eb93969d6
6
+ metadata.gz: 782d65b459af28c86f857b4359beedac711f51decc9694180cad44c89aadf778157531c84f907d13126d6ae0a9cf6a0f1968c9b8d51aeb5b548b23006ea42dc3
7
+ data.tar.gz: 02567ef91947ebcba62f08c8d05d9fa00955b75c4cb157dd423b72b3afdabc8ad5de3a4ec59a0331e4611cc9b22fd31dbfff25f19bf93a5068084ebc7b68fb99
@@ -1,10 +1,30 @@
1
1
  # Change Log
2
2
  This project adheres to [Semantic Versioning](http://semver.org/).
3
3
 
4
- This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachangelog.com/)
4
+ This CHANGELOG follows the format listed listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md)
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [2.0.0] - 2017-09-30
9
+ ### Breaking Change
10
+ - updated `sensu-plugin` dependency to 2.x (@majormoses)
11
+
12
+ ### Changed
13
+ - updated changelog guideline location (@majormoses)
14
+
15
+ ### Fixed
16
+ - pr template spelling (@majormoses)
17
+
18
+ ### Added
19
+ - Support for Puma v3 state files (@dnd)
20
+ - Parsing of stats output with multiple workers (@dnd)
21
+ - Ability to pass `--control-url` and `--auth-token` directly instead of state file (@dnd)
22
+ - Support for connecting to control servers running on TCP ports (@dnd)
23
+ - Add `--gc-stats` flag to allow collecting GC stats (@dnd)
24
+
25
+ ### Removed
26
+ - Dependency on `puma`
27
+
8
28
  ## [1.0.0] - 2017-06-25
9
29
  ### Added
10
30
  - Support for Ruby 2.3 and 2.4 (@eheydrick)
@@ -31,8 +51,8 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
31
51
  ### Added
32
52
  - initial release
33
53
 
34
- [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-puma/compare/1.0.0...HEAD
54
+ [Unreleased]: https://github.com/sensu-plugins/sensu-plugins-puma/compare/2.0.0...HEAD
55
+ [2.0.0]: https://github.com/sensu-plugins/sensu-plugins-puma/compare/1.0.0...2.0.0
35
56
  [1.0.0]: https://github.com/sensu-plugins/sensu-plugins-puma/compare/0.0.3...1.0.0
36
57
  [0.0.3]: https://github.com/sensu-plugins/sensu-plugins-puma/compare/0.0.2...0.0.3
37
58
  [0.0.2]: https://github.com/sensu-plugins/sensu-plugins-puma/compare/0.0.1...0.0.2
38
-
@@ -29,9 +29,7 @@
29
29
  require 'sensu-plugin/metric/cli'
30
30
 
31
31
  require 'json'
32
- require 'puma/configuration'
33
- require 'socket'
34
- require 'yaml'
32
+ require 'sensu-plugins-puma'
35
33
 
36
34
  class PumaMetrics < Sensu::Plugin::Metric::CLI::Graphite
37
35
  option :scheme,
@@ -46,26 +44,77 @@ class PumaMetrics < Sensu::Plugin::Metric::CLI::Graphite
46
44
  long: '--state-file SOCKET',
47
45
  default: '/tmp/puma.state'
48
46
 
49
- def puma_options
50
- @puma_options ||= begin
51
- return nil unless File.exist?(config[:state_file])
52
- YAML.load_file(config[:state_file])['config'].options
53
- end
54
- end
47
+ option :control_auth_token,
48
+ description: 'The auth token to connect to the control server with',
49
+ long: '--auth-token TOKEN'
55
50
 
56
- def puma_stats
57
- stats = Socket.unix(puma_options[:control_url].gsub('unix://', '')) do |socket|
58
- socket.print("GET /stats?token=#{puma_options[:control_auth_token]} HTTP/1.0\r\n\r\n")
59
- socket.read
60
- end
51
+ option :control_url,
52
+ description: 'The control_url the puma control server is listening on',
53
+ long: '--control-url PATH'
61
54
 
62
- JSON.parse(stats.split("\r\n").last)
55
+ option :gc_stats,
56
+ description: 'Collect GC stats. Only available for Puma >= v3.10.0',
57
+ long: '--gc-stats',
58
+ boolean: true,
59
+ default: false
60
+
61
+ def puma_ctl
62
+ @puma_ctl ||= PumaCtl.new(
63
+ state_file: config[:state_file],
64
+ control_auth_token: config[:control_auth_token],
65
+ control_url: config[:control_url]
66
+ )
63
67
  end
64
68
 
65
69
  def run
66
- puma_stats.map do |k, v|
67
- output "#{config[:scheme]}.#{k}", v
70
+ timestamp = Time.now.to_i
71
+ stats = puma_ctl.stats
72
+ metrics = {}
73
+ worker_status = stats.delete('worker_status')
74
+
75
+ if worker_status
76
+ metrics = parse_worker_stats(metrics, worker_status)
77
+ end
78
+
79
+ metrics.merge!(stats)
80
+
81
+ begin
82
+ metrics = parse_gc_stats(metrics, puma_ctl.gc_stats) if config[:gc_stats]
83
+ rescue PumaCtl::UnknownCommand
84
+ unknown 'Control server does not support the `gc-stats` command'
85
+ end
86
+
87
+ metrics.map do |k, v|
88
+ output "#{config[:scheme]}.#{k}", v, timestamp
68
89
  end
69
90
  ok
70
91
  end
92
+
93
+ private
94
+
95
+ def parse_gc_stats(metrics, gc_stats)
96
+ gc_stats.map do |k, v|
97
+ metrics["gc.#{k}"] = v
98
+ end
99
+ metrics
100
+ end
101
+
102
+ def parse_worker_stats(metrics, worker_status)
103
+ backlog = 0
104
+ running = 0
105
+ worker_status.each do |worker|
106
+ idx = worker.delete('index')
107
+ last_status = worker.delete('last_status')
108
+ backlog += (worker['backlog'] = last_status['backlog'])
109
+ running += (worker['running'] = last_status['running'])
110
+ worker.map do |k, v|
111
+ v = Time.parse(v).to_i if k == 'last_checkin'
112
+ metrics["worker.#{idx}.#{k}"] = v
113
+ end
114
+ end
115
+
116
+ metrics['backlog'] = backlog
117
+ metrics['running'] = running
118
+ metrics
119
+ end
71
120
  end
@@ -1 +1,2 @@
1
1
  require 'sensu-plugins-puma/version'
2
+ require 'sensu-plugins-puma/puma_ctl'
@@ -0,0 +1,84 @@
1
+ require 'json'
2
+ require 'socket'
3
+ require 'yaml'
4
+
5
+ class PumaCtl
6
+ class UnknownCommand < StandardError; end
7
+
8
+ attr_reader :state_file
9
+
10
+ def initialize(state_file: '/tmp/puma.state', control_auth_token: nil, control_url: nil)
11
+ @state_file = state_file
12
+ @control_auth_token = control_auth_token
13
+ @control_url = control_url
14
+ end
15
+
16
+ def control_auth_token
17
+ @control_auth_token ||= puma_options[:control_auth_token]
18
+ end
19
+
20
+ def control_url
21
+ @control_url ||= puma_options[:control_url]
22
+ end
23
+
24
+ def puma_options
25
+ @puma_options ||= begin
26
+ return nil unless File.exist?(state_file)
27
+ state = load_puma_state(state_file)
28
+
29
+ if state.key?('config')
30
+ # state is < v3.0.0
31
+ opts = state['config']['options']
32
+ { control_url: opts[:control_url], control_auth_token: opts[:control_auth_token] }
33
+ else
34
+ # state is >= v3.0.0
35
+ { control_url: state['control_url'], control_auth_token: state['control_auth_token'] }
36
+ end
37
+ end
38
+ end
39
+
40
+ def gc_stats
41
+ send_socket_command('gc-stats')
42
+ end
43
+
44
+ def stats
45
+ send_socket_command('stats')
46
+ end
47
+
48
+ private
49
+
50
+ def control_socket
51
+ type = nil
52
+ args = []
53
+ case control_url
54
+ when /^unix:\/\//
55
+ type = :unix
56
+ args = [control_url.gsub('unix://', '')]
57
+ when /^tcp:\/\//
58
+ type = :tcp
59
+ args = control_url.gsub('tcp://', '').split(':')
60
+ else
61
+ return nil
62
+ end
63
+
64
+ Socket.send(type, *args) do |socket|
65
+ yield socket
66
+ end
67
+ end
68
+
69
+ def load_puma_state(path)
70
+ raw = File.read(path)
71
+ sanitized = raw.gsub(/!ruby\/object:.*$/, '')
72
+ YAML.load(sanitized)
73
+ end
74
+
75
+ def send_socket_command(cmd)
76
+ out = control_socket do |socket|
77
+ socket.print("GET /#{cmd}?token=#{control_auth_token} HTTP/1.0\r\n\r\n")
78
+ result = socket.read
79
+ raise UnknownCommand, cmd if result =~ /^HTTP\/1.0 404/
80
+ result
81
+ end
82
+ JSON.parse(out.split("\r\n").last)
83
+ end
84
+ end
@@ -1,6 +1,6 @@
1
1
  module SensuPluginsPuma
2
2
  module Version
3
- MAJOR = 1
3
+ MAJOR = 2
4
4
  MINOR = 0
5
5
  PATCH = 0
6
6
 
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu-plugins-puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sensu-Plugins and contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-26 00:00:00.000000000 Z
11
+ date: 2017-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: puma
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '='
18
- - !ruby/object:Gem::Version
19
- version: 2.11.3
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '='
25
- - !ruby/object:Gem::Version
26
- version: 2.11.3
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: sensu-plugin
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - "~>"
32
18
  - !ruby/object:Gem::Version
33
- version: '1.2'
19
+ version: '2.0'
34
20
  type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
24
  - - "~>"
39
25
  - !ruby/object:Gem::Version
40
- version: '1.2'
26
+ version: '2.0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: bundler
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +164,7 @@ files:
178
164
  - README.md
179
165
  - bin/metrics-puma.rb
180
166
  - lib/sensu-plugins-puma.rb
167
+ - lib/sensu-plugins-puma/puma_ctl.rb
181
168
  - lib/sensu-plugins-puma/version.rb
182
169
  homepage: https://github.com/sensu-plugins/sensu-plugins-puma
183
170
  licenses:
@@ -205,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
192
  version: '0'
206
193
  requirements: []
207
194
  rubyforge_project:
208
- rubygems_version: 2.4.5
195
+ rubygems_version: 2.6.13
209
196
  signing_key:
210
197
  specification_version: 4
211
198
  summary: Sensu plugins for puma