greenhat 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +64 -0
  3. data/bin/greenhat +12 -0
  4. data/lib/greenhat.rb +80 -0
  5. data/lib/greenhat/accessors/disk.rb +27 -0
  6. data/lib/greenhat/accessors/logs/production.rb +41 -0
  7. data/lib/greenhat/accessors/logs/sidekiq.rb +41 -0
  8. data/lib/greenhat/accessors/memory.rb +46 -0
  9. data/lib/greenhat/accessors/network.rb +8 -0
  10. data/lib/greenhat/accessors/process.rb +8 -0
  11. data/lib/greenhat/archive.rb +108 -0
  12. data/lib/greenhat/cli.rb +448 -0
  13. data/lib/greenhat/host.rb +182 -0
  14. data/lib/greenhat/logbot.rb +86 -0
  15. data/lib/greenhat/pry_helpers.rb +51 -0
  16. data/lib/greenhat/settings.rb +51 -0
  17. data/lib/greenhat/shell.rb +92 -0
  18. data/lib/greenhat/shell/cat.rb +125 -0
  19. data/lib/greenhat/shell/disk.rb +68 -0
  20. data/lib/greenhat/shell/faststats.rb +195 -0
  21. data/lib/greenhat/shell/gitlab.rb +45 -0
  22. data/lib/greenhat/shell/help.rb +15 -0
  23. data/lib/greenhat/shell/helper.rb +514 -0
  24. data/lib/greenhat/shell/log.rb +344 -0
  25. data/lib/greenhat/shell/memory.rb +31 -0
  26. data/lib/greenhat/shell/network.rb +12 -0
  27. data/lib/greenhat/shell/process.rb +12 -0
  28. data/lib/greenhat/shell/report.rb +319 -0
  29. data/lib/greenhat/thing.rb +121 -0
  30. data/lib/greenhat/thing/file_types.rb +705 -0
  31. data/lib/greenhat/thing/formatters/api_json.rb +34 -0
  32. data/lib/greenhat/thing/formatters/bracket_log.rb +44 -0
  33. data/lib/greenhat/thing/formatters/clean_raw.rb +23 -0
  34. data/lib/greenhat/thing/formatters/colon_split_strip.rb +12 -0
  35. data/lib/greenhat/thing/formatters/dotenv.rb +10 -0
  36. data/lib/greenhat/thing/formatters/format.rb +12 -0
  37. data/lib/greenhat/thing/formatters/free_m.rb +29 -0
  38. data/lib/greenhat/thing/formatters/gitlab_ctl_tail.rb +51 -0
  39. data/lib/greenhat/thing/formatters/gitlab_status.rb +26 -0
  40. data/lib/greenhat/thing/formatters/json.rb +63 -0
  41. data/lib/greenhat/thing/formatters/json_shellwords.rb +44 -0
  42. data/lib/greenhat/thing/formatters/multiline_json.rb +10 -0
  43. data/lib/greenhat/thing/formatters/raw.rb +18 -0
  44. data/lib/greenhat/thing/formatters/shellwords.rb +23 -0
  45. data/lib/greenhat/thing/formatters/table.rb +26 -0
  46. data/lib/greenhat/thing/formatters/time_json.rb +21 -0
  47. data/lib/greenhat/thing/formatters/time_shellwords.rb +28 -0
  48. data/lib/greenhat/thing/formatters/time_space.rb +36 -0
  49. data/lib/greenhat/thing/helpers.rb +71 -0
  50. data/lib/greenhat/thing/history.rb +51 -0
  51. data/lib/greenhat/thing/info_format.rb +193 -0
  52. data/lib/greenhat/thing/kind.rb +97 -0
  53. data/lib/greenhat/thing/spinner.rb +52 -0
  54. data/lib/greenhat/thing/super_log.rb +102 -0
  55. data/lib/greenhat/tty/custom_line.rb +29 -0
  56. data/lib/greenhat/tty/line.rb +326 -0
  57. data/lib/greenhat/tty/reader.rb +110 -0
  58. data/lib/greenhat/version.rb +3 -0
  59. data/lib/greenhat/views/css.slim +126 -0
  60. data/lib/greenhat/views/disk_free.slim +18 -0
  61. data/lib/greenhat/views/index.slim +51 -0
  62. data/lib/greenhat/views/info.slim +39 -0
  63. data/lib/greenhat/views/manifest.slim +22 -0
  64. data/lib/greenhat/views/memory.slim +18 -0
  65. data/lib/greenhat/views/netstat.slim +20 -0
  66. data/lib/greenhat/views/process.slim +21 -0
  67. data/lib/greenhat/views/systemctl.slim +40 -0
  68. data/lib/greenhat/views/ulimit.slim +15 -0
  69. data/lib/greenhat/web.rb +46 -0
  70. metadata +476 -0
@@ -0,0 +1,86 @@
1
+ # Log Helper
2
+ module LogBot
3
+ # For Amazing Print
4
+ def self.settings
5
+ { ruby19_syntax: true, multiline: false }
6
+ end
7
+
8
+ def self.output(name, message, level, duration = nil)
9
+ time = Time.now.to_s.colorize(:light_black)
10
+ output = time
11
+ output += " #{color_level(level)}"
12
+ output += " - #{name.to_s.colorize(:light_blue)} "
13
+ output += "(#{duration.round(2)}) ".colorize(:magenta) if duration
14
+
15
+ output += ' '
16
+ if message
17
+ output += case message
18
+ when String then message
19
+ else
20
+ message.ai(settings)
21
+ end
22
+ end
23
+
24
+ puts output unless ENV['TESTING']
25
+ end
26
+
27
+ def self.color_level(level)
28
+ case level
29
+ when :debug
30
+ level.to_s.upcase.colorize(:light_cyan)
31
+ when :info
32
+ level.to_s.upcase.colorize(:cyan)
33
+ when :warn
34
+ level.to_s.upcase.colorize(:yellow)
35
+ when :error
36
+ level.to_s.upcase.colorize(:light_red)
37
+ when :fatal
38
+ level.to_s.upcase.colorize(:red)
39
+ end
40
+ end
41
+
42
+ def self.info(name, message = nil, level = :info)
43
+ output(name, message, level)
44
+ end
45
+
46
+ def self.debug(name, message = nil, level = :debug)
47
+ output(name, message, level)
48
+ end
49
+
50
+ def self.warn(name, message = nil, level = :warn)
51
+ output(name, message, level)
52
+ end
53
+
54
+ def self.error(name, message = nil, level = :error)
55
+ output(name, message, level)
56
+ end
57
+
58
+ def self.fatal(name, message = nil, level = :fatal)
59
+ output(name, message, level)
60
+ end
61
+
62
+ def self.do(name, message = nil, level = nil)
63
+ began_at = clock_time
64
+
65
+ level ||= :info
66
+ result = yield
67
+
68
+ duration = (clock_time - began_at).round(3)
69
+
70
+ output(name, message, level, duration)
71
+
72
+ result
73
+ end
74
+
75
+ def self.measure
76
+ began_at = clock_time
77
+ result = yield
78
+ duration = (clock_time - began_at).round(3)
79
+ [result, duration]
80
+ end
81
+
82
+ # From Rack Time
83
+ def self.clock_time
84
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
85
+ end
86
+ end
@@ -0,0 +1,51 @@
1
+ def show(data)
2
+ pastel = Pastel.new
3
+ TTY::Pager.page do |pager|
4
+ data.each do |e|
5
+ table = TTY::Table.new(header: e.keys, rows: [e], orientation: :vertical)
6
+ # do some work with the line
7
+
8
+ output = table.render(:unicode, multiline: false) do |renderer|
9
+ renderer.border.style = :cyan
10
+ # renderer.filter = ->(val, row_index, col_index) do
11
+ # val.ai
12
+ # end
13
+
14
+ renderer.filter = lambda { |val, _row_index, col_index|
15
+ puts val.class unless val.instance_of? String
16
+ if col_index == 1
17
+ if val.numeric?
18
+ pastel.red.blue(val)
19
+ else
20
+ val
21
+ end
22
+ else
23
+ val
24
+ end
25
+ # .ai(raw: true).gsub('"','')
26
+ }
27
+ end
28
+
29
+ pager.write("\n#{output}") # write line to the pager
30
+ end
31
+ end
32
+ end
33
+
34
+ def filter(data, params = {})
35
+ result = data.clone
36
+ params.each do |k, v|
37
+ result.select! do |row|
38
+ if row.key? k.to_sym
39
+ row[k.to_sym].include? v
40
+ else
41
+ false
42
+ end
43
+ end
44
+ end
45
+
46
+ result
47
+ end
48
+
49
+ def version
50
+ Thing.find_by(name: 'gitlab_version_manifest_json').data.build_version
51
+ end
@@ -0,0 +1,51 @@
1
+ # Top level namespace
2
+ module GreenHat
3
+ # Helper for all things user environment / settings / history
4
+ module Settings
5
+ def self.settings
6
+ @settings ||= {
7
+ history: []
8
+ }
9
+ end
10
+
11
+ def self.start
12
+ Dir.mkdir dir unless Dir.exist? dir
13
+
14
+ # CMD History Loading / Tracking
15
+ File.write(cmd_file, "\n") unless File.exist? cmd_file
16
+ end
17
+
18
+ def self.dir
19
+ "#{ENV['HOME']}/.greenhat"
20
+ end
21
+
22
+ # ----------------------------------
23
+ # Command History
24
+ def self.cmd_history
25
+ "#{dir}/cmd_history"
26
+ end
27
+
28
+ def self.cmd_file
29
+ "#{dir}/cmd_history"
30
+ end
31
+
32
+ def self.cmd_history_clean
33
+ File.read(cmd_file).split("\n")
34
+ end
35
+
36
+ def self.cmd_write
37
+ File.write(cmd_file, cmd_history_clean.join("\n"))
38
+ end
39
+
40
+ def self.cmd_add(line)
41
+ File.write(cmd_file, line, File.size(cmd_file), mode: 'a')
42
+ end
43
+
44
+ # ----------------------------------
45
+
46
+ # File Load History
47
+ def self.history_file
48
+ "#{dir}/file_history"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,92 @@
1
+ module GreenHat
2
+ # Root Level Shell
3
+ module Shell
4
+ def self.pry
5
+ binding.pry
6
+ end
7
+
8
+ def self.df
9
+ Disk.df
10
+ end
11
+
12
+ def self.ps
13
+ Process.ps
14
+ end
15
+
16
+ def self.netstat
17
+ Network.netstat
18
+ end
19
+
20
+ def self.free
21
+ Memory.free
22
+ end
23
+
24
+ def self.load_local
25
+ return false unless TTY::Prompt.new.yes?('Load local Omnibus GitLab Instance files?')
26
+
27
+ archive_path = "#{$TMP}/#{Time.now.to_i}_local"
28
+ Dir.mkdir(archive_path)
29
+ # archive = Archive.new(name: 'local')
30
+ archive = Archive.new(name: archive_path, path: archive_path)
31
+
32
+ file_list = Dir['/var/log/gitlab/*/current'] + Dir['/var/log/gitlab/*/*.log']
33
+
34
+ file_list.each do |file|
35
+ next if File.size(file).zero?
36
+
37
+ puts "- Loading #{file.colorize(:green)}"
38
+
39
+ archive.things_create(file: file).setup
40
+ end
41
+ end
42
+
43
+ def self.debug
44
+ ENV['DEBUG'] = if ENV['DEBUG']
45
+ puts "Debug #{'Off'.colorize(:red)}"
46
+ nil
47
+ else
48
+ puts "Debug #{'On'.colorize(:green)}"
49
+ 'true'
50
+ end
51
+ end
52
+
53
+ def self.uptime
54
+ Shell::Cat.default ['uptime']
55
+ end
56
+
57
+ def self.hostname
58
+ Shell::Cat.default ['hostname']
59
+ end
60
+
61
+ def self.uname
62
+ Shell::Cat.default ['uname']
63
+ end
64
+
65
+ def self.history_clear
66
+ File.write(GreenHat::Cli.history_file, "\n")
67
+ end
68
+
69
+ def self.history
70
+ File.read(GreenHat::Cli.history_file).split("\n").each_with_index do |line, i|
71
+ puts "#{i.to_s.ljust(3).colorize(:magenta)} #{line}"
72
+ end
73
+ end
74
+
75
+ def self.ls
76
+ GreenHat::Cli.help
77
+ end
78
+
79
+ def self.ll
80
+ GreenHat::Cli.help
81
+ end
82
+
83
+ def self.about
84
+ puts "#{'GreenHat'.colorize(:green)}: #{GreenHat::VERSION.colorize(:blue)}"
85
+ puts ' - https://gitlab.com/gitlab-com/support/toolbox/greenhat'.colorize(:cyan)
86
+ end
87
+ end
88
+ end
89
+
90
+ # Load All Sub Files
91
+ require_all "#{File.dirname(__FILE__)}/accessors"
92
+ require_all "#{File.dirname(__FILE__)}/shell"
@@ -0,0 +1,125 @@
1
+ module GreenHat
2
+ # CLI Helper
3
+ module Shell
4
+ # Common File Reader File
5
+ module Cat
6
+ # rubocop:disable Metrics/MethodLength
7
+ def self.help
8
+ puts "\u2500".colorize(:cyan) * 20
9
+ puts "#{'Cat'.colorize(:yellow)} All the files"
10
+ puts "\u2500".colorize(:cyan) * 20
11
+ puts 'Print raw file by just entering the file name'
12
+ puts
13
+
14
+ puts 'Common Options'.colorize(:blue)
15
+ puts ' --raw'.colorize(:green)
16
+ puts ' Do not use less/paging'
17
+ puts
18
+ puts ' --archive'.colorize(:green)
19
+ puts ' Limit to specific archvie name (inclusive). Matching SOS tar.gz name'
20
+ puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
21
+ puts ' cat mount --archive=dev-gitlab_202106221546'
22
+ puts
23
+
24
+ puts 'Commands'.colorize(:blue)
25
+ puts 'ls'.colorize(:green)
26
+ puts ' List available files'
27
+ puts ' Options'
28
+ puts ' -a, --all, show all files including source'
29
+ puts
30
+
31
+ puts '<file names+>'.colorize(:green)
32
+ puts ' Print any file names'
33
+ puts ' Ex: `free_m`'
34
+ puts ' Ex: `ps mount --raw`'
35
+ puts
36
+
37
+ puts "#{'show'.colorize(:green)} <file names>"
38
+ puts ' Attempt to print formatted output'
39
+ puts ' Ex: show `free_m`'
40
+
41
+ puts '--archive'.colorize(:green)
42
+ puts ' Limit to specific archvie name (inclusive). Matching SOS tar.gz name'
43
+ puts ' Ex: --archive=dev-gitlab_20210622154626, --archive=202106,202107'
44
+ puts
45
+ end
46
+ # rubocop:enable Metrics/MethodLength
47
+
48
+ # ========================================================================
49
+ # Default
50
+ # ========================================================================
51
+ def self.default(file_list)
52
+ # Extract Args
53
+ file_list, _opts, args = ShellHelper.param_parse(file_list)
54
+
55
+ # Prepare Log List
56
+ file_list = ShellHelper.prepare_list(file_list, Thing.all)
57
+
58
+ # Convert to Things
59
+ files = ShellHelper.find_things(file_list, args)
60
+
61
+ results = ShellHelper.file_process(files) do |file|
62
+ [
63
+ file.friendly_name,
64
+ file.output(false),
65
+ "\n"
66
+ ]
67
+ end
68
+
69
+ ShellHelper.show(results.flatten, args)
70
+ end
71
+
72
+ # ========================================================================
73
+ # Show Attempted Formatting
74
+ # ========================================================================
75
+ def self.show(file_list)
76
+ # Extract Args
77
+ file_list, _opts, args = ShellHelper.param_parse(file_list)
78
+
79
+ # Prepare Log List
80
+ file_list = ShellHelper.prepare_list(file_list, Thing.all)
81
+
82
+ # Convert to Things
83
+ files = ShellHelper.find_things(file_list, args)
84
+
85
+ results = ShellHelper.file_process(files) do |file|
86
+ [
87
+ file.friendly_name,
88
+ file.output(false),
89
+ "\n"
90
+ ]
91
+ end
92
+
93
+ ShellHelper.show(results.flatten, args)
94
+ end
95
+
96
+ # List Files Helpers
97
+ def self.list(args = [])
98
+ all = false
99
+ all = true if args.include?('-a') || args.include?('--all')
100
+
101
+ files = Thing.all
102
+
103
+ # Sort
104
+ files.sort_by!(&:name)
105
+
106
+ # Short & Uniq
107
+ files.uniq!(&:name) unless all
108
+
109
+ # Print
110
+ files.each do |log|
111
+ if all
112
+ puts "- #{log.friendly_name}"
113
+ else
114
+ puts "- #{log.name.colorize(:yellow)}"
115
+ end
116
+ end
117
+ end
118
+
119
+ def self.ls(args = [])
120
+ list(args)
121
+ end
122
+ # ------------------------------------------------------------------------
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,68 @@
1
+ module GreenHat
2
+ # CLI Helper
3
+ module Shell
4
+ # Logs
5
+ module Disk
6
+ # Alias
7
+ def self.ls
8
+ Cli.help
9
+ end
10
+
11
+ # Easy Show All
12
+ def self.df
13
+ ShellHelper.file_output GreenHat::Disk.df
14
+ end
15
+
16
+ # rubocop:disable Metrics/MethodLength,Metrics/BlockLength
17
+ def self.free
18
+ GreenHat::Disk.df.each do |file|
19
+ # Reject TMPFS
20
+ puts file.friendly_name
21
+ disks = file.data.sort_by { |x| x.use.to_i }.reverse.reject { |x| x.filesystem.include? 'tmpfs' }
22
+
23
+ # pad_mount = GreenHat::Disk.max_padding(disks, :mounted_on)
24
+ # pad_size = GreenHat::Disk.max_padding(disks, :size)
25
+ # pad_used = GreenHat::Disk.max_padding(disks, :used)
26
+ # pad_avail = GreenHat::Disk.max_padding(disks, :avail)
27
+
28
+ pad_mount, pad_size, pad_used, pad_avail = GreenHat::Disk.padding(disks)
29
+
30
+ # Headers
31
+ puts [
32
+ 'Mount'.ljust(pad_mount).colorize(:blue),
33
+ 'Size'.ljust(pad_size).colorize(:magenta),
34
+ 'Used'.ljust(pad_used).colorize(:cyan),
35
+ 'Avail'.ljust(pad_avail).colorize(:white),
36
+ '% Use'.ljust(pad_avail).colorize(:green)
37
+ ].join
38
+
39
+ # Table Summary
40
+ disks.map do |disk|
41
+ # Pretty Disk Use
42
+ use = [
43
+ disk.use.rjust(5).ljust(5).colorize(:green),
44
+ ' ['.colorize(:blue),
45
+ ('=' * (disk.use.to_i / 2)).colorize(:green),
46
+ ' ' * (50 - disk.use.to_i / 2),
47
+ ']'.colorize(:blue)
48
+ ].join
49
+
50
+ # Whole Thing
51
+ puts [
52
+ disk.mounted_on.ljust(pad_mount).colorize(:blue),
53
+ disk[:size].to_s.ljust(pad_size).colorize(:magenta),
54
+ disk.used.to_s.ljust(pad_used).colorize(:cyan),
55
+ disk.avail.to_s.ljust(pad_avail).colorize(:white),
56
+ use
57
+ ].join
58
+ end
59
+
60
+ # File End Loop / Break
61
+ puts
62
+ end
63
+ end
64
+ # rubocop:enable Metrics/MethodLength,Metrics/BlockLength
65
+ # ------------------------------------------------------------------------
66
+ end
67
+ end
68
+ end