greenhat 0.6.2 → 0.6.3
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 +4 -4
- data/lib/greenhat/accessors/disk.rb +42 -6
- data/lib/greenhat/accessors/gitlab.rb +1 -1
- data/lib/greenhat/cli.rb +0 -2
- data/lib/greenhat/reports/internal_methods.rb +1 -0
- data/lib/greenhat/reports/reports/full.rb +7 -0
- data/lib/greenhat/reports/reports/full_markdown.rb +140 -0
- data/lib/greenhat/reports/shell_helper.rb +11 -0
- data/lib/greenhat/settings.rb +2 -2
- data/lib/greenhat/shell/gitlab.rb +1 -2
- data/lib/greenhat/shell/query.rb +1 -1
- data/lib/greenhat/shell/reports.rb +14 -0
- data/lib/greenhat/shell/shell_helper.rb +31 -17
- data/lib/greenhat/shell.rb +12 -0
- data/lib/greenhat/thing/file_types.rb +24 -0
- data/lib/greenhat/thing/formatters/gitlab_ctl_tail.rb +1 -1
- data/lib/greenhat/thing/formatters/gitlab_status.rb +1 -1
- data/lib/greenhat/thing/formatters/kube_webservice.rb +1 -1
- data/lib/greenhat/version.rb +1 -1
- metadata +3 -3
- data/lib/greenhat/shell/report.rb +0 -415
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abf4296d91fa1a63e0858e1a1ee0bc461668a6839d7ffb7ab6fbaeadae035dc1
|
4
|
+
data.tar.gz: c7134e262cabb6c1873dc92e56ca6318cef9c64abb4573646228ee52c36be60e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ea40f3c0fc24c35722631e61ad489bd1b9eabd2d6453669e2b56476a5e1c4c883d181d062794023555598da608a69615d4f10f0bfd0c8a75bccf6e0faed8189
|
7
|
+
data.tar.gz: 9b947cdfc641164da1ed4d76df4e9739a01ad29a8120bc3485a534b7a0274beb3965c07dc275004e0a3320341844a00031b480e984835e91610edf77b70bf3e4
|
@@ -11,7 +11,7 @@ module GreenHat
|
|
11
11
|
x.slice(key)
|
12
12
|
end
|
13
13
|
|
14
|
-
list.map(&:values).flatten.max_by(&:size).size +
|
14
|
+
list.map(&:values).flatten.max_by(&:size).size + 5
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.padding(disks, keys = %i[mounted_on size used avail])
|
@@ -29,6 +29,44 @@ module GreenHat
|
|
29
29
|
things
|
30
30
|
end
|
31
31
|
|
32
|
+
def self.report_output(data, filter = %w[tmpfs loop])
|
33
|
+
output = []
|
34
|
+
|
35
|
+
disks = data.sort_by { |x| x.use.to_i }.reverse
|
36
|
+
disks.reject! { |x| filter.any? { |y| x.filesystem.include? y } }
|
37
|
+
pad_mount, pad_size, pad_used, pad_avail = GreenHat::Disk.padding(disks)
|
38
|
+
|
39
|
+
output << [
|
40
|
+
'Mount'.ljust(pad_mount).pastel(:blue),
|
41
|
+
'Size'.ljust(pad_size).pastel(:magenta),
|
42
|
+
'Used'.ljust(pad_used).pastel(:cyan),
|
43
|
+
'Avail'.ljust(pad_avail).pastel(:white),
|
44
|
+
'% Use'.ljust(pad_avail).pastel(:green)
|
45
|
+
].join
|
46
|
+
|
47
|
+
disks.map do |disk|
|
48
|
+
# Pretty Disk Use
|
49
|
+
use = [
|
50
|
+
disk.use.rjust(5).ljust(5).pastel(:green),
|
51
|
+
' ['.pastel(:blue),
|
52
|
+
('=' * (disk.use.to_i / 2)).pastel(:green),
|
53
|
+
' ' * (50 - (disk.use.to_i / 2)),
|
54
|
+
']'.pastel(:blue)
|
55
|
+
].join
|
56
|
+
|
57
|
+
# Whole Thing
|
58
|
+
output << [
|
59
|
+
disk.mounted_on.ljust(pad_mount).pastel(:blue),
|
60
|
+
disk[:size].to_s.ljust(pad_size).pastel(:magenta),
|
61
|
+
disk.used.to_s.ljust(pad_used).pastel(:cyan),
|
62
|
+
disk.avail.to_s.ljust(pad_avail).pastel(:white),
|
63
|
+
use
|
64
|
+
].join
|
65
|
+
end
|
66
|
+
|
67
|
+
output.join("\n ")
|
68
|
+
end
|
69
|
+
|
32
70
|
# Unified Output Handler
|
33
71
|
def self.format_output(file, name = false, limit = nil, filter = %w[tmpfs loop])
|
34
72
|
output = []
|
@@ -79,13 +117,11 @@ module GreenHat
|
|
79
117
|
end
|
80
118
|
|
81
119
|
# Unified Output Handler
|
82
|
-
def self.markdown_format(
|
120
|
+
def self.markdown_format(data, _name = false, limit = nil, filter = %w[tmpfs loop])
|
83
121
|
output = []
|
84
122
|
|
85
|
-
output << file.friendly_name if name
|
86
|
-
|
87
123
|
# Reject TMPFS
|
88
|
-
disks =
|
124
|
+
disks = data.sort_by { |x| x.use.to_i }.reverse
|
89
125
|
|
90
126
|
# Filter
|
91
127
|
disks.reject! { |x| filter.any? { |y| x.filesystem.include? y } }
|
@@ -115,7 +151,7 @@ module GreenHat
|
|
115
151
|
].join
|
116
152
|
end
|
117
153
|
|
118
|
-
output
|
154
|
+
output.join("\n")
|
119
155
|
end
|
120
156
|
# =
|
121
157
|
end
|
@@ -26,7 +26,7 @@ module GreenHat
|
|
26
26
|
|
27
27
|
def self.identify_node(archive)
|
28
28
|
gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }&.data&.keys
|
29
|
-
hostname = archive.things.find { |x| x.type == 'hostname' }.data.first
|
29
|
+
hostname = archive.things.find { |x| x.type == 'hostname' }.data.first.chomp
|
30
30
|
|
31
31
|
{
|
32
32
|
host: hostname,
|
data/lib/greenhat/cli.rb
CHANGED
@@ -169,8 +169,6 @@ module GreenHat
|
|
169
169
|
def self.did_you_mean
|
170
170
|
dictionary = current_methods + current_submodules + cmd_list
|
171
171
|
|
172
|
-
# all.select! { |x| x.include? cmd }
|
173
|
-
|
174
172
|
all = DidYouMean::SpellChecker.new(dictionary: dictionary).correct(cmd)
|
175
173
|
|
176
174
|
if all.empty?
|
@@ -0,0 +1,140 @@
|
|
1
|
+
quiet!
|
2
|
+
|
3
|
+
puts '**OS**'
|
4
|
+
br
|
5
|
+
|
6
|
+
puts '```'
|
7
|
+
cat 'hostname' do |data|
|
8
|
+
"Hostname: #{data.join}"
|
9
|
+
end
|
10
|
+
|
11
|
+
info 'etc/os-release' do |data|
|
12
|
+
ident = "[#{data.ID}] "
|
13
|
+
pretty_name = data.PRETTY_NAME
|
14
|
+
" Distro: #{ident} #{pretty_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
cat 'uname' do |data|
|
18
|
+
value, build = data.first.split[2].split('-')
|
19
|
+
build = "(#{build})"
|
20
|
+
" Kernel: #{value} #{build}"
|
21
|
+
end
|
22
|
+
|
23
|
+
cat 'uptime' do |data|
|
24
|
+
init = data.join.split(', load average').first.strip.split('up ', 2).last
|
25
|
+
" Uptime: #{init}"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Load Average
|
29
|
+
info 'lscpu' do |data|
|
30
|
+
uptime = archive.thing? 'uptime'
|
31
|
+
return unless uptime
|
32
|
+
|
33
|
+
cpu_count = data['CPU(s)'].to_i
|
34
|
+
intervals = uptime.data.first.split('load average: ', 2).last.split(', ').map(&:to_f)
|
35
|
+
|
36
|
+
intervals_text = intervals.map do |interval|
|
37
|
+
value = percent(interval, cpu_count)
|
38
|
+
[
|
39
|
+
interval,
|
40
|
+
' (',
|
41
|
+
"#{value}%",
|
42
|
+
')'
|
43
|
+
].join
|
44
|
+
end
|
45
|
+
|
46
|
+
" LoadAvg: [CPU #{cpu_count}] #{intervals_text.join(', ')}"
|
47
|
+
end
|
48
|
+
puts '```'
|
49
|
+
|
50
|
+
br
|
51
|
+
puts '**Memory**'
|
52
|
+
br
|
53
|
+
|
54
|
+
puts '```'
|
55
|
+
info('free_m', false) do |data|
|
56
|
+
free = data.first
|
57
|
+
|
58
|
+
unless free.total.blank?
|
59
|
+
size = number_to_human_size(free.total.to_i * (1024**2))
|
60
|
+
puts " #{ljust('Total', 12)} #{size}"
|
61
|
+
end
|
62
|
+
|
63
|
+
unless free.used.blank?
|
64
|
+
size = number_to_human_size(free.used.to_i * (1024**2))
|
65
|
+
|
66
|
+
puts " #{ljust('Used', 12)} #{size}"
|
67
|
+
end
|
68
|
+
|
69
|
+
unless free.free.blank?
|
70
|
+
size = number_to_human_size(free.free.to_i * (1024**2))
|
71
|
+
puts " #{ljust('Free', 12)} #{size}"
|
72
|
+
end
|
73
|
+
|
74
|
+
unless free.available.blank?
|
75
|
+
size = number_to_human_size(free.available.to_i * (1024**2))
|
76
|
+
puts " #{ljust('Available', 12)} #{size}"
|
77
|
+
end
|
78
|
+
|
79
|
+
# br
|
80
|
+
# data.map { |x| GreenHat::Memory.memory_row x }.each do |row|
|
81
|
+
# puts row
|
82
|
+
# end
|
83
|
+
end
|
84
|
+
puts '```'
|
85
|
+
|
86
|
+
br
|
87
|
+
puts '**Disks**'
|
88
|
+
br
|
89
|
+
|
90
|
+
puts '```'
|
91
|
+
info 'df_hT' do |data|
|
92
|
+
GreenHat::Disk.markdown_format(data, false, 3)
|
93
|
+
end
|
94
|
+
puts '```'
|
95
|
+
|
96
|
+
br
|
97
|
+
puts '**GitLab**'
|
98
|
+
info 'gitlab/version-manifest.json' do |data|
|
99
|
+
"Version: #{data.build_version}"
|
100
|
+
end
|
101
|
+
|
102
|
+
br
|
103
|
+
|
104
|
+
info 'gitlab_status' do
|
105
|
+
GreenHat::GitLab.services_markdown(archive)
|
106
|
+
end
|
107
|
+
|
108
|
+
br
|
109
|
+
puts '**Errors**'
|
110
|
+
br
|
111
|
+
|
112
|
+
puts '```'
|
113
|
+
query 'gitlab-rails/production_json.log --status=500' do |data|
|
114
|
+
ljust('Production', 14) + data.count.to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
query 'gitlab-rails/application_json.log --message!="Cannot obtain an exclusive lease" --severity=error' do |data|
|
118
|
+
ljust('Application', 14) + data.count.to_s
|
119
|
+
end
|
120
|
+
|
121
|
+
query 'sidekiq/current --severity=error' do |data|
|
122
|
+
ljust('Sidekiq', 14) + data.count.to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
query 'gitlab-rails/api_json.log --status=500' do |data|
|
126
|
+
ljust('API', 14) + data.count.to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
query 'gitaly/current --level=error' do |data|
|
130
|
+
ljust('Gitaly', 14) + data.count.to_s
|
131
|
+
end
|
132
|
+
|
133
|
+
query 'gitlab-workhorse/current --level=error' do |data|
|
134
|
+
ljust('Workhorse', 14) + data.count.to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
query 'gitlab-rails/exceptions_json.log' do |data|
|
138
|
+
ljust('Exceptions', 14) + data.count.to_s
|
139
|
+
end
|
140
|
+
puts '```'
|
@@ -29,6 +29,17 @@ module GreenHat
|
|
29
29
|
path = "#{File.dirname(__FILE__)}/reports"
|
30
30
|
Dir["#{path}/*.rb"] + Dir["#{GreenHat::Settings.reports_dir}/*.rb"]
|
31
31
|
end
|
32
|
+
|
33
|
+
# Collect everything from Built-in and local reports
|
34
|
+
def self.auto_complete_list
|
35
|
+
path = "#{File.dirname(__FILE__)}/reports"
|
36
|
+
list = Dir["#{path}/*.rb"] + Dir["#{GreenHat::Settings.reports_dir}/*.rb"]
|
37
|
+
|
38
|
+
list.map do |entry|
|
39
|
+
File.basename(entry, '.rb')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# --
|
32
43
|
end
|
33
44
|
end
|
34
45
|
end
|
data/lib/greenhat/settings.rb
CHANGED
@@ -82,8 +82,8 @@ module GreenHat
|
|
82
82
|
# rubocop:enable Style/GuardClause
|
83
83
|
|
84
84
|
def self.start
|
85
|
-
|
86
|
-
|
85
|
+
FileUtils.mkdir_p dir
|
86
|
+
FileUtils.mkdir_p reports_dir
|
87
87
|
|
88
88
|
# Load User Settings
|
89
89
|
settings_load
|
@@ -35,7 +35,7 @@ module GreenHat
|
|
35
35
|
results = Archive.all.map { |x| GitLab.identify_node(x) }
|
36
36
|
|
37
37
|
GitLab.node_types.each do |entry|
|
38
|
-
list = results.select { |x| (x.services & entry.pattern).any? }.map(&:host).join(
|
38
|
+
list = results.select { |x| (x.services & entry.pattern).any? }.map(&:host).join("\n")
|
39
39
|
next if list.blank?
|
40
40
|
|
41
41
|
puts entry.name.pastel(:bright_green)
|
@@ -88,7 +88,6 @@ module GreenHat
|
|
88
88
|
"#{service.status}:",
|
89
89
|
service.name.ljust(pad).pastel(color),
|
90
90
|
"#{service.pid_uptime};".ljust(pad)
|
91
|
-
|
92
91
|
]
|
93
92
|
end
|
94
93
|
|
data/lib/greenhat/shell/query.rb
CHANGED
@@ -215,7 +215,7 @@ module GreenHat
|
|
215
215
|
results = filter_pluck(results, flags[:pluck]) if flags.key?(:pluck)
|
216
216
|
|
217
217
|
# Total Counter
|
218
|
-
|
218
|
+
results = ShellHelper.total_count(results, flags) if flags.key?(:total)
|
219
219
|
|
220
220
|
results
|
221
221
|
end
|
@@ -10,6 +10,20 @@ module GreenHat
|
|
10
10
|
module Shell
|
11
11
|
# Logs
|
12
12
|
module Reports
|
13
|
+
def self.auto_complete(_list, word)
|
14
|
+
matches = GreenHat::ShellHelper::Reports.auto_complete_list.select do |x|
|
15
|
+
x.include? word
|
16
|
+
end
|
17
|
+
|
18
|
+
if matches.count > 1
|
19
|
+
puts "#{'Report Options:'.pastel(:bright_blue)} #{matches.join(' ').pastel(:bright_green)}"
|
20
|
+
|
21
|
+
Cli.common_substr(matches.map(&:to_s))
|
22
|
+
elsif matches.count == 1
|
23
|
+
matches.first
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
13
27
|
# Easy Show All
|
14
28
|
def self.ls(raw = [])
|
15
29
|
filter, _flags, _args = Args.parse(raw)
|
@@ -224,22 +224,6 @@ module GreenHat
|
|
224
224
|
|
225
225
|
# Total Count Helper
|
226
226
|
def self.total_count(results, flags)
|
227
|
-
# Support Combine Helper
|
228
|
-
# TODO I Believe this should be removed now
|
229
|
-
# total_count_hash(results, flags) if results.instance_of? Hash
|
230
|
-
|
231
|
-
total_count_array(results, flags) if results.instance_of? Array
|
232
|
-
end
|
233
|
-
|
234
|
-
# Hash Iteration
|
235
|
-
def self.total_count_hash(results, flags)
|
236
|
-
results.flat_map do |k, values|
|
237
|
-
[k, total_count_array(values, flags)]
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
# List Calculation
|
242
|
-
def self.total_count_array(results, flags)
|
243
227
|
# Option to only return the count
|
244
228
|
return results.count if flags[:total] == 'simple'
|
245
229
|
|
@@ -257,9 +241,39 @@ module GreenHat
|
|
257
241
|
# Hide empty results
|
258
242
|
output.reject! { |_k, v| v.blank? }
|
259
243
|
|
260
|
-
|
244
|
+
[output]
|
261
245
|
end
|
262
246
|
|
247
|
+
# TODO: Clean up -- Verify these aren't needed
|
248
|
+
# Hash Iteration
|
249
|
+
# def self.total_count_hash(results, flags)
|
250
|
+
# results.flat_map do |k, values|
|
251
|
+
# [k, total_count_array(values, flags)]
|
252
|
+
# end
|
253
|
+
# end
|
254
|
+
|
255
|
+
# List Calculation
|
256
|
+
# def self.total_count_array(results, flags)
|
257
|
+
# # Option to only return the count
|
258
|
+
# return results.count if flags[:total] == 'simple'
|
259
|
+
|
260
|
+
# output = {}
|
261
|
+
# output[:total] = results.count
|
262
|
+
# output[:duration] = Query.calculate_duration(results)
|
263
|
+
|
264
|
+
# # Sort / Get first and Last
|
265
|
+
# list = results.select(&:time).map(&:time)
|
266
|
+
# unless list.blank?
|
267
|
+
# output[:start] = list.first
|
268
|
+
# output[:end] = list.last
|
269
|
+
# end
|
270
|
+
|
271
|
+
# # Hide empty results
|
272
|
+
# output.reject! { |_k, v| v.blank? }
|
273
|
+
|
274
|
+
# render_table(output, flags)
|
275
|
+
# end
|
276
|
+
|
263
277
|
# Table Printer Helper
|
264
278
|
def self.fields_print(results)
|
265
279
|
results.each do |k, v|
|
data/lib/greenhat/shell.rb
CHANGED
@@ -89,6 +89,18 @@ module GreenHat
|
|
89
89
|
Shell::Cat.default ['uptime']
|
90
90
|
end
|
91
91
|
|
92
|
+
def self.ip_address
|
93
|
+
Shell::Cat.default ['ip_address']
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.ifconfig
|
97
|
+
Shell::Cat.default ['ifconfig']
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.gitlab_rb
|
101
|
+
Shell::Cat.default ['gitlab/gitlab.rb', '--page']
|
102
|
+
end
|
103
|
+
|
92
104
|
def self.hostname
|
93
105
|
Shell::Cat.default ['hostname']
|
94
106
|
end
|
@@ -18,6 +18,18 @@ module GreenHat
|
|
18
18
|
module FileTypes
|
19
19
|
def types
|
20
20
|
{
|
21
|
+
'ifconfig' => {
|
22
|
+
format: :raw,
|
23
|
+
pattern: [
|
24
|
+
/ifconfig/
|
25
|
+
]
|
26
|
+
},
|
27
|
+
'ip_address' => {
|
28
|
+
format: :raw,
|
29
|
+
pattern: [
|
30
|
+
/ip_address/
|
31
|
+
]
|
32
|
+
},
|
21
33
|
'cpuinfo' => {
|
22
34
|
format: :raw,
|
23
35
|
pattern: [
|
@@ -103,6 +115,12 @@ module GreenHat
|
|
103
115
|
/getenforce/
|
104
116
|
]
|
105
117
|
},
|
118
|
+
'gitlab.rb' => {
|
119
|
+
format: :raw,
|
120
|
+
pattern: [
|
121
|
+
%r{gitlab/gitlab.rb}
|
122
|
+
]
|
123
|
+
},
|
106
124
|
'geo-logcursor/current' => {
|
107
125
|
format: :raw,
|
108
126
|
pattern: [
|
@@ -707,6 +725,12 @@ module GreenHat
|
|
707
725
|
%r{gitlab-rails/gitlab-rails-db-migrate.*}
|
708
726
|
]
|
709
727
|
},
|
728
|
+
'rpm_verify' => {
|
729
|
+
format: :raw,
|
730
|
+
pattern: [
|
731
|
+
/rpm_verify/
|
732
|
+
]
|
733
|
+
},
|
710
734
|
'tainted' => {
|
711
735
|
format: :raw,
|
712
736
|
pattern: [
|
data/lib/greenhat/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: greenhat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Davin Walker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: amazing_print
|
@@ -478,6 +478,7 @@ files:
|
|
478
478
|
- lib/greenhat/reports/reports/errors.rb
|
479
479
|
- lib/greenhat/reports/reports/faststats.rb
|
480
480
|
- lib/greenhat/reports/reports/full.rb
|
481
|
+
- lib/greenhat/reports/reports/full_markdown.rb
|
481
482
|
- lib/greenhat/reports/runner.rb
|
482
483
|
- lib/greenhat/reports/shared.rb
|
483
484
|
- lib/greenhat/reports/shell_helper.rb
|
@@ -503,7 +504,6 @@ files:
|
|
503
504
|
- lib/greenhat/shell/platform.rb
|
504
505
|
- lib/greenhat/shell/process.rb
|
505
506
|
- lib/greenhat/shell/query.rb
|
506
|
-
- lib/greenhat/shell/report.rb
|
507
507
|
- lib/greenhat/shell/reports.rb
|
508
508
|
- lib/greenhat/shell/shell_helper.rb
|
509
509
|
- lib/greenhat/thing.rb
|
@@ -1,415 +0,0 @@
|
|
1
|
-
# Deprecated in favor of reports module
|
2
|
-
# TODO: Remove
|
3
|
-
# module GreenHat
|
4
|
-
# # Root Level Shell / Report Helper
|
5
|
-
# module Shell
|
6
|
-
# def self.report(raw)
|
7
|
-
|
8
|
-
# _files, flags, _args = Args.parse(raw)
|
9
|
-
|
10
|
-
# archives = if flags.archive
|
11
|
-
# Archive.all.select do |archive|
|
12
|
-
# flags.archive.any? { |x| archive.name.include? x.to_s }
|
13
|
-
# end
|
14
|
-
# else
|
15
|
-
# Archive.all
|
16
|
-
# end
|
17
|
-
|
18
|
-
# output = archives.map { |x| x.report(flags) }.map(&:show).flatten
|
19
|
-
|
20
|
-
# flags[:page] = true if flags.full && !flags.raw
|
21
|
-
|
22
|
-
# ShellHelper.show(output, flags)
|
23
|
-
# end
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
|
27
|
-
# module GreenHat
|
28
|
-
# # Report Generator Helper
|
29
|
-
#
|
30
|
-
# class Report
|
31
|
-
# include ActionView::Helpers::NumberHelper
|
32
|
-
|
33
|
-
# attr_accessor :archive, :flags, :host, :os_release, :selinux_status, :cpu, :uname,
|
34
|
-
# :timedatectl, :uptime, :meminfo, :gitlab_manifest, :gitlab_status,
|
35
|
-
# :production_log, :api_log, :sidekiq_log,
|
36
|
-
# :exceptions_log, :gitaly_log, :free_m, :disk_free
|
37
|
-
|
38
|
-
# # Find Needed Files for Report
|
39
|
-
#
|
40
|
-
# def initialize(archive, flags)
|
41
|
-
# self.archive = archive
|
42
|
-
# self.flags = flags
|
43
|
-
# self.host = archive.things.find { |x| x.name == 'hostname' }
|
44
|
-
# self.os_release = archive.things.find { |x| x.name == 'etc/os-release' }
|
45
|
-
# self.selinux_status = archive.things.find { |x| x.name == 'sestatus' }
|
46
|
-
# self.cpu = archive.things.find { |x| x.name == 'lscpu' }
|
47
|
-
# self.uname = archive.things.find { |x| x.name == 'uname' }
|
48
|
-
# self.timedatectl = archive.things.find { |x| x.name == 'timedatectl' }
|
49
|
-
# self.uptime = archive.things.find { |x| x.name == 'uptime' }
|
50
|
-
# self.meminfo = archive.things.find { |x| x.name == 'meminfo' }
|
51
|
-
# self.free_m = archive.things.find { |x| x.name == 'free_m' }
|
52
|
-
# self.gitlab_manifest = archive.things.find { |x| x.name == 'gitlab/version-manifest.json' }
|
53
|
-
# self.gitlab_status = archive.things.find { |x| x.name == 'gitlab_status' }
|
54
|
-
# self.production_log = archive.things.find { |x| x.name == 'gitlab-rails/production_json.log' }
|
55
|
-
# self.api_log = archive.things.find { |x| x.name == 'gitlab-rails/api_json.log' }
|
56
|
-
# self.exceptions_log = archive.things.find { |x| x.name == 'gitlab-rails/exceptions_json.log' }
|
57
|
-
# self.gitaly_log = archive.things.find { |x| x.name == 'gitaly/current' }
|
58
|
-
# self.sidekiq_log = archive.things.find { |x| x.name == 'sidekiq/current' }
|
59
|
-
# self.disk_free = archive.things.find { |x| x.name == 'df_hT' }
|
60
|
-
# end
|
61
|
-
|
62
|
-
# def show
|
63
|
-
# output = [
|
64
|
-
# archive.friendly_name.pastel(:blue)
|
65
|
-
# ]
|
66
|
-
|
67
|
-
# # OS
|
68
|
-
# output << 'OS'.pastel(:bright_yellow)
|
69
|
-
# output << hostname if host
|
70
|
-
# output << distro if os_release
|
71
|
-
# output << selinux if selinux_status
|
72
|
-
# # output << arch if cpu
|
73
|
-
# output << kernel if uname
|
74
|
-
# output << sys_time if timedatectl
|
75
|
-
# output << sys_uptime if uptime
|
76
|
-
# output << load_average if uptime && cpu
|
77
|
-
# output << ''
|
78
|
-
|
79
|
-
# # Memory
|
80
|
-
# if meminfo || free_m
|
81
|
-
# output << 'Memory'.pastel(:bright_yellow)
|
82
|
-
# output << memory_perc if meminfo
|
83
|
-
# output << memory_free if free_m
|
84
|
-
# output << ''
|
85
|
-
# end
|
86
|
-
|
87
|
-
# # Disk
|
88
|
-
# if disk_free
|
89
|
-
# output << disks
|
90
|
-
# output << ''
|
91
|
-
# end
|
92
|
-
|
93
|
-
# # Gitlab
|
94
|
-
# output << 'GitLab'.pastel(:bright_yellow) if gitlab_manifest
|
95
|
-
# output << gitlab_version if gitlab_manifest
|
96
|
-
# output << gitlab_services if gitlab_status
|
97
|
-
# output << title('Errors') if production_log || api_log || sidekiq_log
|
98
|
-
# output << production_errors if production_log
|
99
|
-
# output << application_errors if archive.thing?('gitlab-rails/application_json.log')
|
100
|
-
# output << sidekiq_errors if sidekiq_log
|
101
|
-
# output << api_errors if api_log
|
102
|
-
# output << exception_errors if exceptions_log
|
103
|
-
# output << gitaly_errors if gitaly_log
|
104
|
-
# output << workhorse_errors if archive.thing?('gitlab-workhorse/current')
|
105
|
-
|
106
|
-
# full(output) if flags.full
|
107
|
-
|
108
|
-
# # Final Space / Return
|
109
|
-
# output << ''
|
110
|
-
# output
|
111
|
-
# end
|
112
|
-
# # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
|
113
|
-
|
114
|
-
# def full(output)
|
115
|
-
# output << ''
|
116
|
-
# output << 'FastStats Top'
|
117
|
-
# Shell::Faststats.top(['--raw'], true).each { |x| output << x } # Page Row Helper
|
118
|
-
# output << ''
|
119
|
-
|
120
|
-
# output << 'FastStats Errors'
|
121
|
-
# Shell::Faststats.errors(['--raw'], true).each { |x| output << x } # Page Row Helper
|
122
|
-
# output << ''
|
123
|
-
# end
|
124
|
-
|
125
|
-
# def exception_errors
|
126
|
-
# count = exceptions_log.data.count
|
127
|
-
# color = count.zero? ? :green : :red
|
128
|
-
|
129
|
-
# [
|
130
|
-
# title(' Exception', :bright_red, 18),
|
131
|
-
# count.to_s.pastel(color)
|
132
|
-
# ].join
|
133
|
-
# end
|
134
|
-
|
135
|
-
# def workhorse_errors
|
136
|
-
# results = ShellHelper.filter_internal([
|
137
|
-
# 'gitlab-workhorse/current',
|
138
|
-
# '--level=error',
|
139
|
-
# "--archive=#{archive.name}"
|
140
|
-
# ].join(' '))
|
141
|
-
|
142
|
-
# color = results.count.zero? ? :green : :red
|
143
|
-
|
144
|
-
# [
|
145
|
-
# title(' Workhorse', :bright_red, 18),
|
146
|
-
# results.count.to_s.pastel(color)
|
147
|
-
# ].join
|
148
|
-
# end
|
149
|
-
|
150
|
-
# def gitaly_errors
|
151
|
-
# count = gitaly_log.data.count { |x| x.level == 'error' }
|
152
|
-
# color = count.zero? ? :green : :red
|
153
|
-
|
154
|
-
# [
|
155
|
-
# title(' Gitaly', :bright_red, 18),
|
156
|
-
# count.to_s.pastel(color)
|
157
|
-
# ].join
|
158
|
-
# end
|
159
|
-
|
160
|
-
# def production_errors
|
161
|
-
# count = production_log.data.count { |x| x.status == 500 }
|
162
|
-
# color = count.zero? ? :green : :red
|
163
|
-
|
164
|
-
# [
|
165
|
-
# title(' Production', :bright_red, 18),
|
166
|
-
# count.to_s.pastel(color)
|
167
|
-
# ].join
|
168
|
-
# end
|
169
|
-
|
170
|
-
# def api_errors
|
171
|
-
# count = api_log.data.count { |x| x.status == 500 }
|
172
|
-
# color = count.zero? ? :green : :red
|
173
|
-
|
174
|
-
# [
|
175
|
-
# title(' API', :bright_red, 18),
|
176
|
-
# count.to_s.pastel(color)
|
177
|
-
# ].join
|
178
|
-
# end
|
179
|
-
|
180
|
-
# def application_errors
|
181
|
-
# results = ShellHelper.filter_internal([
|
182
|
-
# 'gitlab-rails/application_json.log',
|
183
|
-
# '--message!="Cannot obtain an exclusive lease"',
|
184
|
-
# '--severity=error',
|
185
|
-
# "--archive=#{archive.name}"
|
186
|
-
# ].join(' '))
|
187
|
-
|
188
|
-
# count = results.count { |x| x&.severity == 'ERROR' }
|
189
|
-
# color = count.zero? ? :green : :red
|
190
|
-
|
191
|
-
# [
|
192
|
-
# title(' Application', :bright_red, 18),
|
193
|
-
# count.to_s.pastel(color)
|
194
|
-
# ].join
|
195
|
-
# end
|
196
|
-
|
197
|
-
# def sidekiq_errors
|
198
|
-
# count = sidekiq_log.data.count { |x| x&.severity == 'ERROR' }
|
199
|
-
# color = count.zero? ? :green : :red
|
200
|
-
|
201
|
-
# [
|
202
|
-
# title(' Sidekiq', :bright_red, 18),
|
203
|
-
# count.to_s.pastel(color)
|
204
|
-
# ].join
|
205
|
-
# end
|
206
|
-
|
207
|
-
# def gitlab_services
|
208
|
-
# [
|
209
|
-
# title('Services'),
|
210
|
-
# "\n ",
|
211
|
-
# GitLab.services(archive, 3)
|
212
|
-
# ].join
|
213
|
-
# rescue StandardError => e
|
214
|
-
# LogBot.fatal('GitLab Services', message: e.message, backtrace: e.backtrace.first)
|
215
|
-
# end
|
216
|
-
|
217
|
-
# def gitlab_version
|
218
|
-
# [
|
219
|
-
# title('Version'),
|
220
|
-
# gitlab_manifest.data.build_version
|
221
|
-
# ].join
|
222
|
-
# end
|
223
|
-
|
224
|
-
# def hostname
|
225
|
-
# [
|
226
|
-
# title('Hostname'),
|
227
|
-
# host.data.first
|
228
|
-
# ].join
|
229
|
-
# end
|
230
|
-
|
231
|
-
# def distro
|
232
|
-
# [
|
233
|
-
# title('Distro'),
|
234
|
-
# "[#{os_release.data.ID}] ".pastel(:bright_black),
|
235
|
-
# os_release.data.PRETTY_NAME
|
236
|
-
# ].join
|
237
|
-
# end
|
238
|
-
|
239
|
-
# def selinux
|
240
|
-
# return nil if selinux_status.data.nil?
|
241
|
-
|
242
|
-
# status = selinux_status.data['SELinux status']
|
243
|
-
# status_color = status == 'enabled' ? :green : :red
|
244
|
-
|
245
|
-
# [
|
246
|
-
# title('SeLinux'),
|
247
|
-
# status.pastel(status_color),
|
248
|
-
# ' (',
|
249
|
-
# selinux_status.data['Current mode'],
|
250
|
-
# ')'
|
251
|
-
# ].join
|
252
|
-
# end
|
253
|
-
|
254
|
-
# def arch
|
255
|
-
# [
|
256
|
-
# title('Arch'),
|
257
|
-
# cpu.data.Architecture
|
258
|
-
# ].join
|
259
|
-
# end
|
260
|
-
|
261
|
-
# def kernel
|
262
|
-
# # TODO: Better way to consistently get uname info?
|
263
|
-
# value, build = uname.data.first.split[2].split('-')
|
264
|
-
# [
|
265
|
-
# title('Kernel'),
|
266
|
-
# value,
|
267
|
-
# " (#{build})".pastel(:bright_black)
|
268
|
-
# ].join
|
269
|
-
# end
|
270
|
-
|
271
|
-
# # Helper for finding if NTP is enabled
|
272
|
-
# def ntp_keys
|
273
|
-
# [
|
274
|
-
# 'Network time on', 'NTP enabled', 'NTP service', 'System clock synchronized'
|
275
|
-
# ]
|
276
|
-
# end
|
277
|
-
|
278
|
-
# def sys_time
|
279
|
-
# # Ignore if Empty
|
280
|
-
# return false if timedatectl.data.nil?
|
281
|
-
|
282
|
-
# ntp_statuses = timedatectl.data.slice(*ntp_keys).values.compact
|
283
|
-
|
284
|
-
# enabled = %w[active yes] & ntp_statuses
|
285
|
-
# ntp_status = ntp_statuses.first
|
286
|
-
# ntp_color = enabled.empty? ? :red : :green
|
287
|
-
|
288
|
-
# # Fall Back
|
289
|
-
# ntp_status ||= 'unknown'
|
290
|
-
|
291
|
-
# [
|
292
|
-
# title('Sys Time'),
|
293
|
-
# timedatectl.data['Local time'],
|
294
|
-
# ' (ntp: '.pastel(:bright_black),
|
295
|
-
# ntp_status.pastel(ntp_color),
|
296
|
-
# ')'.pastel(:bright_black)
|
297
|
-
# ].join
|
298
|
-
# end
|
299
|
-
|
300
|
-
# # Strip/Simplify Uptime
|
301
|
-
# def sys_uptime
|
302
|
-
# init = uptime.data.first.split(', load average').first.strip
|
303
|
-
|
304
|
-
# [
|
305
|
-
# title('Uptime'),
|
306
|
-
# init.split('up ', 2).last
|
307
|
-
# ].join
|
308
|
-
# end
|
309
|
-
|
310
|
-
# def load_average
|
311
|
-
# cpu_count = cpu.data['CPU(s)'].to_i
|
312
|
-
# intervals = uptime.data.first.split('load average: ', 2).last.split(', ').map(&:to_f)
|
313
|
-
|
314
|
-
# # Generate Colorized Text for Output
|
315
|
-
# intervals_text = intervals.map do |interval|
|
316
|
-
# value = percent(interval, cpu_count)
|
317
|
-
# color = value > 100 ? :red : :green
|
318
|
-
# [
|
319
|
-
# interval,
|
320
|
-
# ' (',
|
321
|
-
# "#{value}%".pastel(color),
|
322
|
-
# ')'
|
323
|
-
# ].join
|
324
|
-
# end
|
325
|
-
|
326
|
-
# [
|
327
|
-
# title('LoadAvg'),
|
328
|
-
# "[CPU #{cpu_count}] ".pastel(:bright_white),
|
329
|
-
# intervals_text.join(', ')
|
330
|
-
# ].join
|
331
|
-
# end
|
332
|
-
|
333
|
-
# def memory_perc
|
334
|
-
# total = ShellHelper.human_size_to_number(meminfo.data['MemTotal'])
|
335
|
-
# free = ShellHelper.human_size_to_number(meminfo.data['MemFree'])
|
336
|
-
# used = percent((total - free), total)
|
337
|
-
|
338
|
-
# [
|
339
|
-
# title('Usage'),
|
340
|
-
# ' ['.pastel(:bright_black),
|
341
|
-
# '='.pastel(:green) * (used / 2),
|
342
|
-
# ' ' * (50 - (used / 2)),
|
343
|
-
# ']'.pastel(:bright_black),
|
344
|
-
# " #{100 - percent(free, total)}%".pastel(:green) # Inverse
|
345
|
-
# ].join
|
346
|
-
# end
|
347
|
-
|
348
|
-
# def memory_free
|
349
|
-
# free = free_m.data.find { |x| x.kind == 'Mem' }
|
350
|
-
|
351
|
-
# return unless free
|
352
|
-
|
353
|
-
# formatted_mem = free_m.data.map { |x| GreenHat::Memory.memory_row x }
|
354
|
-
|
355
|
-
# output = []
|
356
|
-
# unless free.total.blank?
|
357
|
-
# output << title('Total', :cyan, 14)
|
358
|
-
# output << number_to_human_size(free.total.to_i * (1024**2))
|
359
|
-
# output << "\n"
|
360
|
-
# end
|
361
|
-
|
362
|
-
# unless free.total.blank?
|
363
|
-
# output << title('Used', :yellow, 14)
|
364
|
-
# output << number_to_human_size(free.used.to_i * (1024**2))
|
365
|
-
# output << "\n"
|
366
|
-
# end
|
367
|
-
|
368
|
-
# unless free.total.blank?
|
369
|
-
# output << title('Free', :blue, 14)
|
370
|
-
# output << number_to_human_size(free.free.to_i * (1024**2))
|
371
|
-
# output << "\n"
|
372
|
-
# end
|
373
|
-
|
374
|
-
# unless free.total.blank?
|
375
|
-
# output << title('Available', :green, 14)
|
376
|
-
# output << number_to_human_size(free.available.to_i * (1024**2))
|
377
|
-
# output << "\n"
|
378
|
-
# end
|
379
|
-
|
380
|
-
# output << "\n"
|
381
|
-
# output << formatted_mem.map { |x| x.prepend ' ' * 2 }.join("\n")
|
382
|
-
|
383
|
-
# output.join
|
384
|
-
# rescue StandardError => e
|
385
|
-
# LogBot.fatal('Memory', message: e.message, backtrace: e.backtrace.first)
|
386
|
-
# end
|
387
|
-
|
388
|
-
# def disks
|
389
|
-
# # GreenHat::Disk.df({archive: []})
|
390
|
-
# file = GreenHat::Disk.df({ archive: [archive.name] })
|
391
|
-
|
392
|
-
# disk_list = GreenHat::Disk.format_output(file.first, false, 3)
|
393
|
-
|
394
|
-
# # Preapre / Indent List
|
395
|
-
# [
|
396
|
-
# 'Disks'.pastel(:bright_yellow) + ' (Top % Usage)'.pastel(:bright_black),
|
397
|
-
# "\n",
|
398
|
-
# disk_list.each { |x| x.prepend(' ' * 4) }.join("\n")
|
399
|
-
# ].join
|
400
|
-
# end
|
401
|
-
|
402
|
-
# # ----------------------------
|
403
|
-
# # Helpers
|
404
|
-
# # ----------------------------
|
405
|
-
# def percent(value, total)
|
406
|
-
# ((value / total.to_f) * 100).round
|
407
|
-
# end
|
408
|
-
|
409
|
-
# # Helper to Make Cyan Titles
|
410
|
-
# def title(name, color = :cyan, ljust = 12)
|
411
|
-
# " #{name}:".ljust(ljust).pastel(color)
|
412
|
-
# end
|
413
|
-
# end
|
414
|
-
# # rubocop:enable Metrics/ClassLength
|
415
|
-
# end
|