greenhat 0.7.2 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -1
  3. data/lib/greenhat/accessors/gitlab.rb +1 -1
  4. data/lib/greenhat/accessors/grep.rb +1 -1
  5. data/lib/greenhat/archive.rb +3 -3
  6. data/lib/greenhat/cli.rb +2 -2
  7. data/lib/greenhat/entrypoint.rb +1 -1
  8. data/lib/greenhat/host.rb +2 -2
  9. data/lib/greenhat/paper/paper_helper.rb +1 -1
  10. data/lib/greenhat/reports/internal_methods.rb +2 -2
  11. data/lib/greenhat/reports/reports/errors.rb +3 -1
  12. data/lib/greenhat/reports/reports/full.rb +10 -0
  13. data/lib/greenhat/reports/reports/production_log_duration.rb +1 -0
  14. data/lib/greenhat/reports/shell_helper.rb +17 -6
  15. data/lib/greenhat/reports.rb +3 -3
  16. data/lib/greenhat/shell/args.rb +3 -3
  17. data/lib/greenhat/shell/field_helper.rb +1 -1
  18. data/lib/greenhat/shell/filter_help.rb +2 -1
  19. data/lib/greenhat/shell/log.rb +1 -1
  20. data/lib/greenhat/shell/query.rb +10 -4
  21. data/lib/greenhat/shell/reports.rb +10 -1
  22. data/lib/greenhat/shell/shell_helper.rb +20 -39
  23. data/lib/greenhat/shell.rb +2 -2
  24. data/lib/greenhat/thing/file_types.rb +23 -0
  25. data/lib/greenhat/thing/formatters/api_json.rb +11 -4
  26. data/lib/greenhat/thing/formatters/exporters.rb +1 -1
  27. data/lib/greenhat/thing/formatters/gitlab_status.rb +1 -1
  28. data/lib/greenhat/thing/formatters/identify_db.rb +2 -2
  29. data/lib/greenhat/thing/formatters/json.rb +6 -0
  30. data/lib/greenhat/thing/formatters/json_shellwords.rb +12 -5
  31. data/lib/greenhat/thing/formatters/kube_nginx.rb +10 -10
  32. data/lib/greenhat/thing/formatters/nginx.rb +10 -10
  33. data/lib/greenhat/thing/formatters/runner_log.rb +5 -5
  34. data/lib/greenhat/thing/formatters/syslog.rb +4 -4
  35. data/lib/greenhat/thing/formatters/time_json.rb +1 -1
  36. data/lib/greenhat/thing/formatters/time_space.rb +1 -1
  37. data/lib/greenhat/thing/history.rb +1 -1
  38. data/lib/greenhat/thing/info_format.rb +2 -2
  39. data/lib/greenhat/thing/kind.rb +5 -1
  40. data/lib/greenhat/thing/spinner.rb +1 -1
  41. data/lib/greenhat/version.rb +1 -1
  42. data/lib/greenhat/web/faststats.rb +1 -1
  43. data/lib/greenhat/web/helpers.rb +1 -1
  44. metadata +11 -81
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba6197971082cb194c319fd71d5353d6be2329445c6808cabed9b764a9ab74c7
4
- data.tar.gz: c319e5bbf5dd591a70ca1195d20dd0fd79c7642fde4b95f45c4f88da9f153c5f
3
+ metadata.gz: a519d68faaec2994665e8c6e442923578d6a0f165a2213f3a5ef0e7e45b65903
4
+ data.tar.gz: 1a9f905cf1d9f8738a1658f932b5d14d8ef9964a0bb2360a5438460330e868d1
5
5
  SHA512:
6
- metadata.gz: fb274b40665cebb795104e7eef72f968928e916a811146811b7607c4d048950291c540ac8d8eec3f1fe74acdb91a15e1acbd52c8d2bb69ce612c8e6f313bdde7
7
- data.tar.gz: 849ce3aa1d387ac0294b86b3bf75b3451eff3278bd229c2b43c960228c689425aa6ee7bbc9a7a1b26d100e072da537a88ad286e888bda76a219f0cd1341d4b7f
6
+ metadata.gz: 6e9f31443fdb9917069831fc89e39b97f198c3b298bb06b2331dc0788d2f7ca31e4ce65b1f69e0a89e82d6788e810fe0d344a5cb2c74b30aa53d3b7577442f96
7
+ data.tar.gz: 3534f35919122f6b01aaa1570429faf852dc4c91c3e170a55e693cc84207fa391cfb7ad2c85af4cca46a0d83adcbbfaa24ecf1db52bcfa76d08bf38d8c42ad83
data/README.md CHANGED
@@ -12,6 +12,8 @@ Experimental SOS and Log Parser for GitLab
12
12
 
13
13
  `apt-get install libarchive-tools`
14
14
 
15
+ Ruby 3.0 or later, including the headers (such as package `ruby-dev`)
16
+
15
17
  ## Installation
16
18
 
17
19
  ```
@@ -38,7 +40,7 @@ bundle exec rake
38
40
  - Update CHANGELOG
39
41
  - Increment `version.rb`
40
42
  - Create MR
41
- - Merge to Master
43
+ - Merge to `main`
42
44
 
43
45
  ```
44
46
  # Build and Push
@@ -46,6 +48,12 @@ bundle exec rake build
46
48
  gem push pkg/greenhat-1.x.x.gem
47
49
  ```
48
50
 
51
+ ## Dev Troubleshooting
52
+
53
+ ```
54
+ docker run -it -v ${PWD}:/app ruby:3.1.4 bash
55
+ ```
56
+
49
57
  ## Contributing
50
58
 
51
59
  Bug reports and merge requests are welcome on GitLab at https://gitlab.com/gitlab-com/support/toolbox/greenhat. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -73,7 +73,7 @@ module GreenHat
73
73
  end
74
74
  end
75
75
 
76
- table.render(:unicode, padding: [0, 1, 0, 1], indent: indent)
76
+ table.render(:unicode, padding: [0, 1, 0, 1], indent:)
77
77
  end
78
78
  # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
79
79
 
@@ -49,7 +49,7 @@ module GreenHat
49
49
  return
50
50
  end
51
51
 
52
- ShellHelper.show GreenHat::Paper.new(data: output, flags: flags).render
52
+ ShellHelper.show GreenHat::Paper.new(data: output, flags:).render
53
53
  end
54
54
 
55
55
  def self.find_things(files = [])
@@ -24,9 +24,9 @@ module GreenHat
24
24
  list = Find.find(path).reject { |x| File.directory?(x) || File.symlink?(x) }
25
25
 
26
26
  # Ignore Empty Files
27
- list.reject! { |x| File.size(x).zero? }
27
+ list.reject! { |x| File.empty?(x) }
28
28
 
29
- archive = Archive.new(name: archive_path, path: path)
29
+ archive = Archive.new(name: archive_path, path:)
30
30
  archive.save
31
31
 
32
32
  list.each do |file|
@@ -34,7 +34,7 @@ module GreenHat
34
34
  next if missing_command(file)
35
35
 
36
36
  # Thread.new do
37
- thing = archive.things_create(file: file)
37
+ thing = archive.things_create(file:)
38
38
  thing.setup
39
39
  # end
40
40
  end
data/lib/greenhat/cli.rb CHANGED
@@ -8,7 +8,7 @@ module GreenHat
8
8
  value ||= '' # Empty Start
9
9
 
10
10
  loop do
11
- line = reader.read_line(readline_notch, value: value)
11
+ line = reader.read_line(readline_notch, value:)
12
12
  value = '' # Remove Afterwards
13
13
 
14
14
  if reader.breaker
@@ -169,7 +169,7 @@ module GreenHat
169
169
  def self.did_you_mean
170
170
  dictionary = current_methods + current_submodules + cmd_list
171
171
 
172
- all = DidYouMean::SpellChecker.new(dictionary: dictionary).correct(cmd)
172
+ all = DidYouMean::SpellChecker.new(dictionary:).correct(cmd)
173
173
 
174
174
  if all.empty?
175
175
  puts [
@@ -12,7 +12,7 @@ module GreenHat
12
12
  load_files files
13
13
  Cli.run_command(args) if args.any? { |arg| Cli.run_command?(arg) }
14
14
 
15
- report_runner(args: args, files: files, raw: raw, flags: flags)
15
+ report_runner(args:, files:, raw:, flags:)
16
16
  post_args(flags)
17
17
  post_setup(flags)
18
18
 
data/lib/greenhat/host.rb CHANGED
@@ -152,7 +152,7 @@ class Host < Teron
152
152
  obj[headers[i]] = v
153
153
  end
154
154
  end
155
- { headers: headers, list: list }
155
+ { headers:, list: }
156
156
  end
157
157
 
158
158
  def systemctl_unit_files
@@ -161,7 +161,7 @@ class Host < Teron
161
161
 
162
162
  all = file.raw[1..-2].map do |x|
163
163
  unit, status = x.split
164
- { unit: unit, status: status }
164
+ { unit:, status: }
165
165
  end
166
166
 
167
167
  all.reject! { |x| x[:unit].nil? }
@@ -105,7 +105,7 @@ module GreenHat
105
105
  # --------------------------------------------------------------------------
106
106
  def render_array_table(entry)
107
107
  header, rows = entry
108
- table = TTY::Table.new(header: header, rows: rows)
108
+ table = TTY::Table.new(header:, rows:)
109
109
 
110
110
  LogBot.debug('Rendering Entries') if ENV['DEBUG']
111
111
  self.output = table.render(table_style, padding: [0, 1, 0, 1], multiline: true) do |renderer|
@@ -125,10 +125,10 @@ module GreenHat
125
125
  def show(value)
126
126
  if value.instance_of?(Array)
127
127
  value.each do |x|
128
- output.push GreenHat::Paper.new(data: x, flags: flags).render
128
+ output.push GreenHat::Paper.new(data: x, flags:).render
129
129
  end
130
130
  else
131
- output.push GreenHat::Paper.new(data: value, flags: flags).render
131
+ output.push GreenHat::Paper.new(data: value, flags:).render
132
132
  end
133
133
  end
134
134
 
@@ -26,7 +26,9 @@ entries = [
26
26
  stats: 'exception.class,exception.message,status' },
27
27
  { header: 'Gitaly', base: 'gitaly/current --level=error --truncate=99', stats: 'error' },
28
28
  { header: 'Praefect', base: 'praefect/current --level=error --truncate=99', stats: 'error' },
29
- { header: 'Pages', base: 'gitlab-pages/current --level=error', stats: 'error' }
29
+ { header: 'Pages', base: 'gitlab-pages/current --level=error', stats: 'error' },
30
+ { header: 'Geo', base: 'gitlab-rails/geo.log --severity=error', stats: 'message' },
31
+ { header: 'Elasticsearch', base: 'gitlab-rails/elasticsearch.log --severity=error', stats: 'message' }
30
32
  ]
31
33
 
32
34
  # Filter Logic
@@ -159,3 +159,13 @@ query_if_exists('gitlab-pages/current --level=error') do |data|
159
159
  color = data.count.zero? ? :green : :red
160
160
  indent("#{ljust('Pages:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
161
161
  end
162
+
163
+ query_if_exists 'gitlab-rails/geo.log --severity=error' do |data|
164
+ color = data.count.zero? ? :green : :red
165
+ indent("#{ljust('Geo:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
166
+ end
167
+
168
+ query_if_exists 'gitlab-rails/elasticsearch.log --severity=error' do |data|
169
+ color = data.count.zero? ? :green : :red
170
+ indent("#{ljust('Elasticsearch:', 14, :magenta)} #{data.count.to_s.pastel(color)}", 4)
171
+ end
@@ -15,6 +15,7 @@ fields = %w[
15
15
  db_replica_duration_s
16
16
  external_http_duration_s
17
17
  redis_cache_duration_s
18
+ queue_duration_s
18
19
  redis_shared_state_duration_s
19
20
  ]
20
21
 
@@ -4,14 +4,25 @@ module GreenHat
4
4
  module Reports
5
5
  # Make Running more consistent
6
6
  def self.run(file:, args:, flags:, raw_args:)
7
- report = GreenHat::Reports::Builder.new(file: file, args: args, flags: flags, raw_args: raw_args)
8
- output = Archive.all.map do |archive|
7
+ report = GreenHat::Reports::Builder.new(file:, args:, flags:, raw_args:)
8
+
9
+ # Fuzzy Match Archive Names
10
+ archives = Archive.all
11
+ if flags[:archive] && !flags[:archive].empty?
12
+ archives.select! do |a|
13
+ flags[:archive].any? do |x|
14
+ a.name.include? x.to_s
15
+ end
16
+ end
17
+ end
18
+
19
+ output = archives.map do |archive|
9
20
  runner = GreenHat::Reports::Runner.new(
10
- archive: archive,
21
+ archive:,
11
22
  store: report.store.clone,
12
- flags: flags,
13
- args: args,
14
- raw_args: raw_args
23
+ flags:,
24
+ args:,
25
+ raw_args:
15
26
  )
16
27
 
17
28
  runner.run!
@@ -31,10 +31,10 @@ module GreenHat
31
31
 
32
32
  output = Archive.all.map do |archive|
33
33
  runner = GreenHat::Reports::Runner.new(
34
- archive: archive,
34
+ archive:,
35
35
  store: store.clone,
36
- flags: flags,
37
- args: args
36
+ flags:,
37
+ args:
38
38
  )
39
39
 
40
40
  runner.run!
@@ -120,10 +120,10 @@ module GreenHat
120
120
  field = field.to_sym
121
121
 
122
122
  {
123
- field: field,
123
+ field:,
124
124
  value: arg_normalize(field, value),
125
- bang: bang,
126
- logic: logic
125
+ bang:,
126
+ logic:
127
127
  }
128
128
  end
129
129
  end
@@ -21,7 +21,7 @@ module GreenHat
21
21
  def self.filter_flags(word)
22
22
  if word.blank?
23
23
  puts 'Filter Options:'.pastel(:bright_blue)
24
- puts ShellHelper.field_table(filter_opts, 6)
24
+ puts ShellHelper.field_table(filter_opts)
25
25
  puts
26
26
 
27
27
  return []
@@ -201,7 +201,8 @@ module GreenHat
201
201
  table_style: [
202
202
  '--table_style'.pastel(:green),
203
203
  ' Renderer used for formatted output. basic, ascii, or unicode(default)',
204
- ' Ex: log filter --table_style=base'
204
+ ' Without any params this will result in basic',
205
+ ' Ex: log filter --table_style=basic'
205
206
  ],
206
207
 
207
208
  truncate: [
@@ -218,7 +218,7 @@ module GreenHat
218
218
 
219
219
  # Skip and Print Total if set
220
220
  if flags[:fields]
221
- ShellHelper.fields_print(results)
221
+ ShellHelper.fields_print(files)
222
222
  return true
223
223
  end
224
224
 
@@ -25,10 +25,13 @@ module GreenHat
25
25
  files.reject(&:blank?).map do |file|
26
26
  src = file.archive&.friendly_name || file&.name
27
27
  file.data.map do |entry|
28
+ # Some entries are nil?
29
+ next if entry.nil?
30
+
28
31
  bit = entry.clone
29
32
  bit[:src] = src
30
33
  bit
31
- end
34
+ end.compact
32
35
  end
33
36
  end
34
37
 
@@ -164,6 +167,9 @@ module GreenHat
164
167
  process_transform(flags[:transform], results) if flags.key? :transform
165
168
 
166
169
  results.select! do |row|
170
+ # Skip Integers?
171
+ # next if row.is_a? Integer
172
+
167
173
  args.send(flags.logic || :all?) do |arg|
168
174
  filter_row_key(row, arg, flags)
169
175
  end
@@ -185,7 +191,7 @@ module GreenHat
185
191
  results = filter_except(results, flags[:except]) if flags.key?(:except)
186
192
 
187
193
  # Remove Blank from either slice or except
188
- results.reject!(&:empty?)
194
+ results.reject!(&:blank?)
189
195
 
190
196
  # Sort / Reverse by default
191
197
  if flags.key?(:sort)
@@ -372,7 +378,7 @@ module GreenHat
372
378
  l95 = l95.round(flags.round) if flags.round
373
379
 
374
380
  {
375
- key: key,
381
+ key:,
376
382
  '99' => l99,
377
383
  '95' => l95,
378
384
  mean: flags.round ? values.mean.round(flags.round) : values.mean,
@@ -494,7 +500,7 @@ module GreenHat
494
500
  match
495
501
  end
496
502
  rescue StandardError => e
497
- LogBot.fatal('[Query] Filter Row Failure', message: e.message, backtrace: e.backtrace.first, row: row)
503
+ LogBot.fatal('[Query] Filter Row Failure', message: e.message, backtrace: e.backtrace.first, row:)
498
504
  false
499
505
  end
500
506
 
@@ -8,6 +8,15 @@ require 'greenhat/reports/shell_helper'
8
8
  module GreenHat
9
9
  # CLI Helper
10
10
  module Shell
11
+ # Make `report` a default top layer command
12
+ def self.report(_raw = ['default'])
13
+ # Move
14
+ Cli.move_shell Shell::Reports
15
+
16
+ # Run
17
+ Reports.default ['full']
18
+ end
19
+
11
20
  # Logs
12
21
  module Reports
13
22
  def self.auto_complete(_list, word)
@@ -48,7 +57,7 @@ module GreenHat
48
57
 
49
58
  run_list.each do |file|
50
59
  raw_args = list.reject { |x| file.include? x }
51
- GreenHat::ShellHelper::Reports.run(file: file, args: args, flags: flags, raw_args: raw_args)
60
+ GreenHat::ShellHelper::Reports.run(file:, args:, flags:, raw_args:)
52
61
  end
53
62
  end
54
63
  end
@@ -85,7 +85,7 @@ module GreenHat
85
85
  # Collect Class Objects for output
86
86
  def self.create_ledger(data, flags)
87
87
  data.map do |x|
88
- Paper.new(data: x, flags: flags)
88
+ Paper.new(data: x, flags:)
89
89
  end
90
90
  end
91
91
 
@@ -244,50 +244,31 @@ module GreenHat
244
244
  [output]
245
245
  end
246
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
247
+ # Table Printer Helper
248
+ def self.fields_print(files)
249
+ fields = ShellHelper.find_things(files).map(&:fields).flatten.uniq
254
250
 
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'
251
+ # truncate = (TTY::Screen.width - columns) / columns
252
+ # fields.map! { |f| f[0..truncate] }
253
+ puts ShellHelper.field_table(fields)
259
254
 
260
- # output = {}
261
- # output[:total] = results.count
262
- # output[:duration] = Query.calculate_duration(results)
255
+ # ShellHelper.fields_print(files)
256
+ end
263
257
 
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
258
+ # 5 Columns cause issues with resizing
259
+ def self.field_table(list, columns: 4)
260
+ return nil if list.empty?
270
261
 
271
- # # Hide empty results
272
- # output.reject! { |_k, v| v.blank? }
262
+ # Split list into groups based on columns
263
+ groups = list.each_slice((list.size / columns.to_f).ceil).to_a
273
264
 
274
- # render_table(output, flags)
275
- # end
265
+ # Max Width for Table
266
+ truncate = (TTY::Screen.width - groups.count) / groups.count
276
267
 
277
- # Table Printer Helper
278
- def self.fields_print(results)
279
- results.each do |k, v|
280
- puts k
281
- puts field_table(v.map(&:keys).flatten.uniq.sort)
282
- puts
268
+ # Process Truncation
269
+ groups.each do |group|
270
+ group.map! { |f| f[0..truncate]&.to_sym }
283
271
  end
284
- end
285
-
286
- def self.field_table(list, columns = 4)
287
- return nil if list.empty?
288
-
289
- # Keep Alphabetical Sort
290
- groups = list.each_slice((list.size / columns.to_f).round).to_a
291
272
 
292
273
  table = TTY::Table.new do |t|
293
274
  loop do
@@ -297,7 +278,7 @@ module GreenHat
297
278
  end
298
279
  end
299
280
 
300
- table.render(:unicode, padding: [0, 1, 0, 1])
281
+ table.render(:unicode, padding: [0, 1, 0, 1], resize: false)
301
282
  end
302
283
 
303
284
  # Unified Files Interface
@@ -59,11 +59,11 @@ module GreenHat
59
59
  file_list = Dir['/var/log/gitlab/*/current'] + Dir['/var/log/gitlab/*/*.log']
60
60
 
61
61
  file_list.each do |file|
62
- next if File.size(file).zero?
62
+ next if File.empty?(file)
63
63
 
64
64
  puts "- Loading #{file.pastel(:green)}"
65
65
 
66
- archive.things_create(file: file).setup
66
+ archive.things_create(file:).setup
67
67
  end
68
68
  end
69
69
 
@@ -920,6 +920,12 @@ module GreenHat
920
920
  /vmstat/
921
921
  ]
922
922
  },
923
+ 'date' => {
924
+ format: :raw,
925
+ pattern: [
926
+ /date/
927
+ ]
928
+ },
923
929
  'gitlab-kas/config' => {
924
930
  format: :raw,
925
931
  pattern: [
@@ -962,6 +968,12 @@ module GreenHat
962
968
  /rpm_verify/
963
969
  ]
964
970
  },
971
+ 'gitlab_system_status' => {
972
+ format: :raw,
973
+ pattern: [
974
+ /gitlab_system_status/
975
+ ]
976
+ },
965
977
  'gitlab-rails/application.log' => {
966
978
  format: :raw,
967
979
  pattern: [
@@ -989,6 +1001,13 @@ module GreenHat
989
1001
  %r{sidekiq/perf.data}
990
1002
  ]
991
1003
  },
1004
+ 'gitlab-rails/geo.log' => {
1005
+ format: :json,
1006
+ log: true,
1007
+ pattern: [
1008
+ %r{gitlab-rails/geo.log}
1009
+ ]
1010
+ },
992
1011
 
993
1012
  # ======================================================================
994
1013
  # KubeSoS TODO Section
@@ -1014,6 +1033,10 @@ module GreenHat
1014
1033
  'kubesos' => {
1015
1034
  format: :raw,
1016
1035
  pattern: [
1036
+ /license_info/,
1037
+ %r{etc/sshd_config},
1038
+ /btmp_size/,
1039
+ /user_uid/,
1017
1040
  /all_values.yaml/,
1018
1041
  %r{webservice.log/sidekiq_client.log},
1019
1042
  /chart-version/,
@@ -8,19 +8,26 @@ module GreenHat
8
8
  # Primarily for gitlab-rails/api_json.log
9
9
  def format_api_json
10
10
  self.result = raw.map do |row|
11
+ # Seeing regular edge cases where there is random new non-json
12
+ # at the beginning of a log / Attempt to save first entry
13
+ if row[0] != '{'
14
+ # Nothing to Escape Parse
15
+ next unless row.include?('{')
16
+
17
+ row = "{#{row.split('{', 2).last}"
18
+ end
19
+
11
20
  result = Oj.load row
12
21
 
13
22
  # Parsing Time
14
23
  format_time(result)
15
24
 
16
- # flatten_hash(result).sort.to_h
17
25
  result
18
26
  rescue StandardError => e
19
27
  # TODO: Background Logger?
20
- e.message
21
- LogBot.warn('JSON Parse', e.message)
28
+ LogBot.warn('[API JSON] JSON Parse', "#{e.message}: #{row.inspect}")
22
29
  next
23
- end
30
+ end.compact
24
31
 
25
32
  :ok
26
33
  end
@@ -31,7 +31,7 @@ module GreenHat
31
31
  # Breakout
32
32
  method, path, protocol, status, bytes = request.gsub('"', '').split(' ', 5)
33
33
 
34
- result.merge!(method: method, path: path, protocol: protocol, status: status, bytes: bytes)
34
+ result.merge!(method:, path:, protocol:, status:, bytes:)
35
35
 
36
36
  else
37
37
  result[:msg] = msg
@@ -10,7 +10,7 @@ module GreenHat
10
10
  status, service, pid_uptime = entry.split(': ')
11
11
 
12
12
  {
13
- status: status,
13
+ status:,
14
14
  name: service,
15
15
  pid_uptime: pid_uptime.chomp
16
16
  }
@@ -16,9 +16,9 @@ module GreenHat
16
16
 
17
17
  level, _a, _b, msg = output.split(' ', 4)
18
18
  {
19
- time: time,
19
+ time:,
20
20
  i: level_abrv,
21
- level: level,
21
+ level:,
22
22
  message: msg
23
23
  }
24
24
  rescue StandardError => e
@@ -14,6 +14,9 @@ module GreenHat
14
14
  { message: row }
15
15
  end
16
16
 
17
+ # Skip bad results
18
+ next if result.nil?
19
+
17
20
  # Parsing Time / Recusrive is really slow
18
21
  format_time(result)
19
22
 
@@ -47,6 +50,9 @@ module GreenHat
47
50
 
48
51
  # Loop through potential fields and parse as needed
49
52
  def format_time(result)
53
+ # Don't format integers
54
+ # return if result.is_a? Integer
55
+
50
56
  format_time_fields.each do |field|
51
57
  result[field] = format_time_parse(result[field]) if result.key?(field)
52
58
  rescue StandardError => e
@@ -7,11 +7,7 @@ module GreenHat
7
7
  # ==========================================================================
8
8
  def format_json_shell
9
9
  self.result = raw.map do |row|
10
- result = begin
11
- Oj.load row
12
- rescue EncodingError
13
- json_shellwords_fallback row
14
- end
10
+ result = format_json_row(row)
15
11
 
16
12
  # Parsing Time
17
13
  format_time(result)
@@ -25,6 +21,17 @@ module GreenHat
25
21
  :ok
26
22
  end
27
23
 
24
+ # Simplify Map Loop / Short Circuit for weird entries
25
+ def format_json_row(row)
26
+ return { message: row } if row[0] != '{' && !row.include?('{')
27
+
28
+ begin
29
+ Oj.load row
30
+ rescue EncodingError
31
+ json_shellwords_fallback row
32
+ end
33
+ end
34
+
28
35
  def json_shellwords_fallback(row)
29
36
  result = Shellwords.split(row).each_with_object({}) do |x, h|
30
37
  key, value = x.split('=')
@@ -18,16 +18,16 @@ module GreenHat
18
18
 
19
19
  {
20
20
  remote_addr: ip,
21
- remote_user: remote_user,
22
- method: method,
23
- path: path,
24
- status: status,
25
- bytes: bytes,
26
- http_version: http_version,
27
- http_referer: http_referer,
28
- http_user_agent: http_user_agent,
29
- gzip_ratio: gzip_ratio,
30
- time: time
21
+ remote_user:,
22
+ method:,
23
+ path:,
24
+ status:,
25
+ bytes:,
26
+ http_version:,
27
+ http_referer:,
28
+ http_user_agent:,
29
+ gzip_ratio:,
30
+ time:
31
31
  }
32
32
 
33
33
  # Fall back for malformed logs
@@ -21,16 +21,16 @@ module GreenHat
21
21
 
22
22
  {
23
23
  remote_addr: ip,
24
- remote_user: remote_user,
25
- method: method,
26
- path: path,
27
- status: status,
28
- bytes: bytes,
29
- http_version: http_version,
30
- http_referer: http_referer,
31
- http_user_agent: http_user_agent,
32
- gzip_ratio: gzip_ratio,
33
- time: time
24
+ remote_user:,
25
+ method:,
26
+ path:,
27
+ status:,
28
+ bytes:,
29
+ http_version:,
30
+ http_referer:,
31
+ http_user_agent:,
32
+ gzip_ratio:,
33
+ time:
34
34
  }
35
35
  rescue StandardError => e
36
36
  LogBot.warn('NGINX Parse', e.message)
@@ -23,11 +23,11 @@ module GreenHat
23
23
 
24
24
  entry = {
25
25
  time: format_time_parse("#{month} #{day} #{time}"),
26
- device: device,
27
- service: service,
28
- message: message,
29
- pid: pid,
30
- row: row # Insert full row for different timestamp formats
26
+ device:,
27
+ service:,
28
+ message:,
29
+ pid:,
30
+ row: # Insert full row for different timestamp formats
31
31
  }
32
32
 
33
33
  # Remove Empty Keys
@@ -22,10 +22,10 @@ module GreenHat
22
22
 
23
23
  {
24
24
  time: format_time_parse("#{month} #{day} #{time}"),
25
- device: device,
26
- service: service,
27
- message: message,
28
- pid: pid
25
+ device:,
26
+ service:,
27
+ message:,
28
+ pid:
29
29
  }
30
30
 
31
31
  # Return everything incase of error
@@ -14,7 +14,7 @@ module GreenHat
14
14
  result = begin
15
15
  Oj.load msg
16
16
  rescue StandardError
17
- { msg: msg }
17
+ { msg: }
18
18
  end
19
19
 
20
20
  result.time = time
@@ -11,7 +11,7 @@ module GreenHat
11
11
 
12
12
  {
13
13
  time: Time.parse(time),
14
- msg: msg
14
+ msg:
15
15
  }
16
16
  end
17
17
  end
@@ -34,7 +34,7 @@ module GreenHat
34
34
  end
35
35
 
36
36
  def self.add(name, type)
37
- files[name] = { type: type, time: expire }
37
+ files[name] = { type:, time: expire }
38
38
 
39
39
  write
40
40
  end
@@ -103,7 +103,7 @@ module GreenHat
103
103
  obj[headers[i]] = v
104
104
  end
105
105
  end
106
- { headers: headers, list: list }
106
+ { headers:, list: }
107
107
  end
108
108
 
109
109
  def manifest_json_format
@@ -150,7 +150,7 @@ module GreenHat
150
150
 
151
151
  all = info.systemctl_unit_files[1..-2].map do |x|
152
152
  unit, status = x.split
153
- { unit: unit, status: status }
153
+ { unit:, status: }
154
154
  end
155
155
  all.reject! { |x| x[:unit].nil? }
156
156
  all.sort_by(&:unit)
@@ -44,7 +44,11 @@ module GreenHat
44
44
  end
45
45
 
46
46
  def check_oj_parse?(first_line)
47
- Oj.load(first_line)
47
+ result = Oj.load(first_line)
48
+
49
+ # Extra Validation (Oj is being more generous than we want)
50
+ return false if result.is_a? Integer
51
+
48
52
  true
49
53
  rescue StandardError
50
54
  false
@@ -9,7 +9,7 @@ module GreenHat
9
9
  @spinner = TTY::Spinner.new(
10
10
  "#{time.pastel(:bright_black)} - [:spinner] :title", hide_cursor: true, success_mark: '✔'.pastel(:green)
11
11
  )
12
- @spinner.update(title: title)
12
+ @spinner.update(title:)
13
13
 
14
14
  # Don't Auto spin when debug output is happening
15
15
  @spinner.auto_spin unless ENV['DEBUG']
@@ -1,3 +1,3 @@
1
1
  module GreenHat
2
- VERSION = '0.7.2'.freeze
2
+ VERSION = '0.7.4'.freeze
3
3
  end
@@ -29,7 +29,7 @@ module WebHelpers
29
29
 
30
30
  # Handle Short Results
31
31
  top = results.dig(kind, :stats).sort_by { |_k, v| v[:duration] }
32
- top = top.size >= 10 ? top[-10..] : top
32
+ top = top[-10..] if top.size >= 10
33
33
 
34
34
  top.to_h.map do |k, v|
35
35
  count_perc = percent(v[:count], count)
@@ -150,7 +150,7 @@ module WebHelpers
150
150
  data = default_index.clone
151
151
  data.transform_values! { |_y| [] } # Ensure Uniq
152
152
  list[stack] = {
153
- name: stack, data: data
153
+ name: stack, data:
154
154
  }
155
155
  end
156
156
 
metadata CHANGED
@@ -1,101 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: greenhat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davin Walker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-03 00:00:00.000000000 Z
11
+ date: 2024-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: amazing_print
14
+ name: actionview
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '6.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.14'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.14'
55
- - !ruby/object:Gem::Dependency
56
- name: minitest-reporters
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.4'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.4'
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '13.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '13.0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '1.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '1.0'
26
+ version: '6.1'
97
27
  - !ruby/object:Gem::Dependency
98
- name: actionview
28
+ name: activesupport
99
29
  requirement: !ruby/object:Gem::Requirement
100
30
  requirements:
101
31
  - - "~>"
@@ -109,19 +39,19 @@ dependencies:
109
39
  - !ruby/object:Gem::Version
110
40
  version: '6.1'
111
41
  - !ruby/object:Gem::Dependency
112
- name: activesupport
42
+ name: amazing_print
113
43
  requirement: !ruby/object:Gem::Requirement
114
44
  requirements:
115
45
  - - "~>"
116
46
  - !ruby/object:Gem::Version
117
- version: '6.1'
47
+ version: '1.3'
118
48
  type: :runtime
119
49
  prerelease: false
120
50
  version_requirements: !ruby/object:Gem::Requirement
121
51
  requirements:
122
52
  - - "~>"
123
53
  - !ruby/object:Gem::Version
124
- version: '6.1'
54
+ version: '1.3'
125
55
  - !ruby/object:Gem::Dependency
126
56
  name: chartkick
127
57
  requirement: !ruby/object:Gem::Requirement
@@ -609,14 +539,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
609
539
  requirements:
610
540
  - - ">="
611
541
  - !ruby/object:Gem::Version
612
- version: 2.7.5
542
+ version: '3'
613
543
  required_rubygems_version: !ruby/object:Gem::Requirement
614
544
  requirements:
615
545
  - - ">="
616
546
  - !ruby/object:Gem::Version
617
547
  version: '0'
618
548
  requirements: []
619
- rubygems_version: 3.1.6
549
+ rubygems_version: 3.3.26
620
550
  signing_key:
621
551
  specification_version: 4
622
552
  summary: GitLab SOS Tool