puma-status 1.0 → 1.4

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
  SHA256:
3
- metadata.gz: 2f95a656741b1b1aafddb43954a144399db944b78ca6384e9ec77cc0783ca750
4
- data.tar.gz: a1b2f9addd173d84404bb94e26ec38522586d72fca0e190562d86d9a3e95b92a
3
+ metadata.gz: 22bea1d3a501185590a81878994456d75a4c5375794221bdeb51b3283d65cceb
4
+ data.tar.gz: a2670a54fdd6c4dae1040c59882f969ba1aff3487076d75962e2fa105da32b59
5
5
  SHA512:
6
- metadata.gz: a44a39a95544ba5a9cd42b4e87ac2409a5b0c3623dad6af622c7a589be755c91ab26af03daf7a7304d2ba0da8e9a216a6a850dd5409e7f75d8eee2e5a6c79a23
7
- data.tar.gz: a344489b4164ff044ff37ac39b4cfaab7a9f4ea74fe2c1cc12a6c124d3804a94260423c2be8ca12d02b42f30754a30f630de8bf93cd723a12385a6b7dad211a6
6
+ metadata.gz: '09d1cfd981ee0c5092e9bda66009e2a4b517f3bfe3987559cfb571a9a4aa0c880e6ca45061cbd0a0c8bbc5016d2a11ba3410facc67b9924ab7643512110b2711'
7
+ data.tar.gz: 023b10377d8567d59c3b75028c4cd54c2f3db12d686bcf41d5a6fcd69aabf45c6e5a89b3c956afa8e98d7ec696c5ef85801fd6a8625adf6b9d42a1aea9a584fc
data/lib/core.rb CHANGED
@@ -3,13 +3,14 @@ require 'json'
3
3
  require 'net_x/http_unix'
4
4
  require 'openssl'
5
5
  require 'time'
6
+ require 'open3'
6
7
  require_relative 'stats'
7
8
 
8
9
  def get_stats(state_file_path)
9
10
  puma_state = YAML.load_file(state_file_path)
10
11
 
11
12
  uri = URI.parse(puma_state["control_url"])
12
-
13
+
13
14
  address = if uri.scheme =~ /unix/i
14
15
  [uri.scheme, '://', uri.host, uri.path].join
15
16
  else
@@ -19,7 +20,7 @@ def get_stats(state_file_path)
19
20
  client = NetX::HTTPUnix.new(address, uri.port)
20
21
 
21
22
  if uri.scheme =~ /ssl/i
22
- client.use_ssl = true
23
+ client.use_ssl = true
23
24
  client.verify_mode = OpenSSL::SSL::VERIFY_NONE if ENV['SSL_NO_VERIFY'] == '1'
24
25
  end
25
26
 
@@ -32,10 +33,26 @@ def get_stats(state_file_path)
32
33
  hydrate_stats(stats, puma_state, state_file_path)
33
34
  end
34
35
 
36
+ def get_memory_from_top(raw_memory)
37
+ case raw_memory[-1].downcase
38
+ when 'g'
39
+ (raw_memory[0...-1].to_f*1024).to_i
40
+ when 'm'
41
+ raw_memory[0...-1].to_i
42
+ else
43
+ raw_memory.to_i/1024
44
+ end
45
+ end
46
+
47
+ PID_COLUMN = 0
48
+ MEM_COLUMN = 5
49
+ CPU_COLUMN = 8
50
+ OPEN3_STDOUT = 1
51
+
35
52
  def get_top_stats(pids)
36
53
  pids.each_slice(19).inject({}) do |res, pids19|
37
- top_result = `top -b -n 1 -p #{pids19.join(',')} | tail -n #{pids19.length}`
38
- top_result.split("\n").map { |row| r = row.split(' '); [r[0].to_i, r[5].to_i/1024, r[8].to_f] }
54
+ top_result = Open3.popen3({ 'LC_ALL' => 'C' }, "top -b -n 1 -p #{pids19.map(&:to_i).join(',')}")[OPEN3_STDOUT].read
55
+ top_result.split("\n").last(pids19.length).map { |row| r = row.split(' '); [r[PID_COLUMN].to_i, get_memory_from_top(r[MEM_COLUMN]), r[CPU_COLUMN].to_f] }
39
56
  .inject(res) { |hash, row| hash[row[0]] = { mem: row[1], pcpu: row[2] }; hash }
40
57
  res
41
58
  end
@@ -65,7 +82,7 @@ def format_stats(stats)
65
82
  if stats.booting?
66
83
  master_line += " #{warn("booting")}"
67
84
  else
68
- master_line += " | Load: #{color(75, 50, stats.load, asciiThreadLoad(stats.running_threads, stats.max_threads))}"
85
+ master_line += " | Load: #{color(75, 50, stats.load, asciiThreadLoad(stats.running_threads, stats.spawned_threads, stats.max_threads))}"
69
86
  master_line += " | Req: #{stats.requests_count}" if stats.requests_count
70
87
  end
71
88
 
@@ -77,7 +94,7 @@ def format_stats(stats)
77
94
  elsif wstats.killed?
78
95
  worker_line += " #{error("killed")}"
79
96
  else
80
- worker_line += " | Load: #{color(75, 50, wstats.load, asciiThreadLoad(wstats.running_threads, wstats.max_threads))}"
97
+ worker_line += " | Load: #{color(75, 50, wstats.load, asciiThreadLoad(wstats.running_threads, wstats.spawned_threads, wstats.max_threads))}"
81
98
  worker_line += " | Phase: #{error(wstats.phase)}" if wstats.phase != stats.phase
82
99
  worker_line += " | Req: #{wstats.requests_count}" if wstats.requests_count
83
100
  worker_line += " Queue: #{error(wstats.backlog.to_s)}" if wstats.backlog > 0
data/lib/helpers.rb CHANGED
@@ -29,11 +29,16 @@ def color(critical, warn, value, str = nil)
29
29
  colorize(str, color_level)
30
30
  end
31
31
 
32
- def asciiThreadLoad(idx, total)
32
+ def asciiThreadLoad(running, spawned, total)
33
33
  full = "█"
34
- empty= "░"
34
+ half= "░"
35
+ empty = " "
35
36
 
36
- "#{idx}[#{full*idx}#{empty*(total-idx)}]#{total}"
37
+ full_count = running
38
+ half_count = [spawned - running, 0].max
39
+ empty_count = total - half_count - full_count
40
+
41
+ "#{running}[#{full*full_count}#{half*half_count}#{empty*empty_count}]#{total}"
37
42
  end
38
43
 
39
44
  def seconds_to_human(seconds)
@@ -44,8 +49,10 @@ def seconds_to_human(seconds)
44
49
  #=> 23h59m
45
50
  #=> 1d 0h
46
51
  #=> 24d
47
-
48
- if seconds < 60*60
52
+
53
+ if seconds <= 0
54
+ "--m--s"
55
+ elsif seconds < 60*60
49
56
  "#{(seconds/60).to_s.rjust(2, ' ')}m#{(seconds%60).to_s.rjust(2, ' ')}s"
50
57
  elsif seconds >= 60*60*1 && seconds < 60*60*24
51
58
  "#{(seconds/(60*60*1)).to_s.rjust(2, ' ')}h#{((seconds%(60*60*1))/60).to_s.rjust(2, ' ')}m"
data/lib/puma-status.rb CHANGED
@@ -17,11 +17,21 @@ def run
17
17
  begin
18
18
  debug "State file: #{state_file_path}"
19
19
  format_stats(get_stats(state_file_path))
20
- rescue Errno::ENOENT
21
- errors << "#{warn(state_file_path)} doesn't exists"
20
+ rescue Errno::ENOENT => e
21
+ if e.message =~ /#{state_file_path}/
22
+ errors << "#{warn(state_file_path)} doesn't exists"
23
+ elsif e.message =~ /connect\(2\) for [^\/]/
24
+ errors << "#{warn("Relative Unix socket")}: the Unix socket of the control app has a relative path. Please, ensure you are running from the same folder has puma."
25
+ else
26
+ errors << "#{error(state_file_path)} an unhandled error occured: #{e.inspect}"
27
+ end
22
28
  nil
23
- rescue Errno::EISDIR
24
- errors << "#{warn(state_file_path)} isn't a state file"
29
+ rescue Errno::EISDIR => e
30
+ if e.message =~ /#{state_file_path}/
31
+ errors << "#{warn(state_file_path)} isn't a state file"
32
+ else
33
+ errors << "#{error(state_file_path)} an unhandled error occured: #{e.inspect}"
34
+ end
25
35
  nil
26
36
  rescue => e
27
37
  errors << "#{error(state_file_path)} an unhandled error occured: #{e.inspect}"
data/lib/stats.rb CHANGED
@@ -41,10 +41,12 @@ class Stats
41
41
  @wstats.dig('last_status', 'running') || @wstats['running'] || 0
42
42
  end
43
43
  alias :total_threads :running
44
+ alias :spawned_threads :running
44
45
 
45
46
  def max_threads
46
47
  @wstats.dig('last_status', 'max_threads') || @wstats['max_threads'] || 0
47
48
  end
49
+ alias :total_threads :max_threads
48
50
 
49
51
  def pool_capacity
50
52
  @wstats.dig('last_status', 'pool_capacity') || @wstats['pool_capacity'] || 0
@@ -123,6 +125,10 @@ class Stats
123
125
  workers.reduce(0) { |total, wstats| total + wstats.running_threads }
124
126
  end
125
127
 
128
+ def spawned_threads
129
+ workers.reduce(0) { |total, wstats| total + wstats.spawned_threads }
130
+ end
131
+
126
132
  def max_threads
127
133
  workers.reduce(0) { |total, wstats| total + wstats.max_threads }
128
134
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma-status
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.0'
4
+ version: '1.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoann Lecuyer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-07-14 00:00:00.000000000 Z
@@ -94,8 +94,8 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.9'
97
- description:
98
- email:
97
+ description:
98
+ email:
99
99
  executables:
100
100
  - puma-status
101
101
  extensions: []
@@ -111,7 +111,7 @@ homepage: https://github.com/ylecuyer/puma-status
111
111
  licenses:
112
112
  - MIT
113
113
  metadata: {}
114
- post_install_message:
114
+ post_install_message:
115
115
  rdoc_options: []
116
116
  require_paths:
117
117
  - lib
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  version: '0'
128
128
  requirements: []
129
129
  rubygems_version: 3.0.0
130
- signing_key:
130
+ signing_key:
131
131
  specification_version: 4
132
132
  summary: Command-line tool for puma to display information about running request/process
133
133
  test_files: []