greenhat 0.7.2 → 0.7.4

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.
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