greenhat 0.3.2 → 0.3.6
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 -3
- data/lib/greenhat/accessors/gitlab.rb +30 -1
- data/lib/greenhat/accessors/memory.rb +1 -1
- data/lib/greenhat/archive.rb +11 -2
- data/lib/greenhat/cli.rb +37 -0
- data/lib/greenhat/host.rb +25 -37
- data/lib/greenhat/shell/args.rb +22 -9
- data/lib/greenhat/shell/faststats.rb +23 -3
- data/lib/greenhat/shell/field_helper.rb +1 -1
- data/lib/greenhat/shell/filter_help.rb +232 -9
- data/lib/greenhat/shell/log.rb +153 -9
- data/lib/greenhat/shell/markdown.rb +352 -0
- data/lib/greenhat/shell/old_search_helper.rb +54 -0
- data/lib/greenhat/shell/page.rb +1 -1
- data/lib/greenhat/shell/pipe.rb +31 -0
- data/lib/greenhat/shell/platform.rb +28 -0
- data/lib/greenhat/shell/report.rb +106 -25
- data/lib/greenhat/shell/shell_helper.rb +114 -106
- data/lib/greenhat/shell.rb +7 -0
- data/lib/greenhat/thing/file_types.rb +126 -7
- data/lib/greenhat/thing/formatters/json.rb +4 -0
- data/lib/greenhat/thing/formatters/kube_json.rb +36 -0
- data/lib/greenhat/thing/formatters/kube_nginx.rb +48 -0
- data/lib/greenhat/thing/formatters/kube_webservice.rb +51 -0
- data/lib/greenhat/thing/formatters/nginx.rb +6 -2
- data/lib/greenhat/thing/formatters/registry.rb +47 -0
- data/lib/greenhat/thing/formatters/time_space.rb +0 -16
- data/lib/greenhat/thing/helpers.rb +12 -0
- data/lib/greenhat/thing.rb +10 -0
- data/lib/greenhat/version.rb +1 -1
- data/lib/greenhat/views/api.slim +55 -0
- data/lib/greenhat/views/chart.slim +42 -0
- data/lib/greenhat/views/chart_template.slim +31 -0
- data/lib/greenhat/views/chartkick.js +21 -0
- data/lib/greenhat/views/css.slim +47 -0
- data/lib/greenhat/views/gitaly.slim +53 -0
- data/lib/greenhat/views/headers.slim +16 -0
- data/lib/greenhat/views/index-old.slim +51 -0
- data/lib/greenhat/views/index.slim +14 -14
- data/lib/greenhat/views/info.slim +17 -18
- data/lib/greenhat/views/production.slim +55 -0
- data/lib/greenhat/views/sidekiq.slim +55 -0
- data/lib/greenhat/views/time.slim +63 -0
- data/lib/greenhat/views/workhorse.slim +16 -0
- data/lib/greenhat/web/api.rb +94 -0
- data/lib/greenhat/web/chartkick_shim.rb +14 -0
- data/lib/greenhat/web/faststats.rb +44 -0
- data/lib/greenhat/web/gitaly.rb +65 -0
- data/lib/greenhat/web/helpers.rb +198 -0
- data/lib/greenhat/web/production.rb +104 -0
- data/lib/greenhat/web/sidekiq.rb +73 -0
- data/lib/greenhat/web/stats_helpers.rb +74 -0
- data/lib/greenhat/web/time.rb +36 -0
- data/lib/greenhat/web/workhorse.rb +43 -0
- data/lib/greenhat/web.rb +63 -19
- data/lib/greenhat.rb +1 -0
- metadata +73 -2
@@ -103,7 +103,8 @@ module GreenHat
|
|
103
103
|
StringColor.do(key, entry)
|
104
104
|
end
|
105
105
|
|
106
|
-
|
106
|
+
# Stats truncation handled separately
|
107
|
+
if flags[:truncate] && !flags[:stats]
|
107
108
|
entry_truncate(formatted_entry, flags[:truncate])
|
108
109
|
else
|
109
110
|
formatted_entry
|
@@ -150,8 +151,21 @@ module GreenHat
|
|
150
151
|
format_table_entry(flags, val)
|
151
152
|
end
|
152
153
|
|
154
|
+
# Internal Query Helper
|
155
|
+
# query = 'gitlab-rails/application_json.log --message!="Cannot obtain an exclusive lease" --severity=error'
|
156
|
+
# ShellHelper.filter_internal(query)
|
157
|
+
def self.filter_internal(search = '')
|
158
|
+
files, flags, args = Args.parse(Shellwords.split(search))
|
159
|
+
flags[:combine] = true
|
160
|
+
|
161
|
+
# Default to everything
|
162
|
+
files = Thing.all.map(&:name) if files.empty?
|
163
|
+
|
164
|
+
ShellHelper.filter_start(files, flags, args)
|
165
|
+
end
|
166
|
+
|
153
167
|
# Main Entry Point for Filtering
|
154
|
-
def self.filter_start(files, flags, args)
|
168
|
+
def self.filter_start(files, flags = {}, args = {})
|
155
169
|
# Convert to Things
|
156
170
|
logs = ShellHelper.find_things(files, flags).select(&:processed?)
|
157
171
|
|
@@ -167,11 +181,17 @@ module GreenHat
|
|
167
181
|
|
168
182
|
# Include Total Count in Name
|
169
183
|
results = ShellHelper.filter(log.data, flags, args)
|
184
|
+
duration = calculate_duration(results)
|
185
|
+
|
170
186
|
title = [
|
171
187
|
log.friendly_name,
|
172
188
|
" #{results.count}".pastel(:bright_black)
|
189
|
+
|
173
190
|
]
|
174
191
|
|
192
|
+
# Append Duration
|
193
|
+
title.push(" #{duration.pastel(:cyan, :dim)}") unless duration.blank?
|
194
|
+
|
175
195
|
# Save unless empty
|
176
196
|
obj[title.join] = results unless results.count.zero?
|
177
197
|
|
@@ -180,6 +200,31 @@ module GreenHat
|
|
180
200
|
end
|
181
201
|
end
|
182
202
|
|
203
|
+
def self.calculate_duration(results)
|
204
|
+
only_with_time = results.select(&:time)
|
205
|
+
|
206
|
+
# If slice is used ignore
|
207
|
+
return nil if only_with_time.empty?
|
208
|
+
|
209
|
+
sorted = only_with_time.map(&:time).sort
|
210
|
+
humanize_time(sorted.first, sorted.last)
|
211
|
+
end
|
212
|
+
|
213
|
+
# Replace TimeDifference with https://stackoverflow.com/a/4136485/1678507
|
214
|
+
def self.humanize_time(time_start, time_end, increments = 2)
|
215
|
+
miliseconds = (time_end - time_start) * 1000
|
216
|
+
|
217
|
+
list = [[1000, :ms], [60, :s], [60, :m], [24, :h]].map do |count, name|
|
218
|
+
next unless miliseconds.positive?
|
219
|
+
|
220
|
+
miliseconds, n = miliseconds.divmod(count)
|
221
|
+
|
222
|
+
"#{n.to_i}#{name}" unless n.to_i.zero?
|
223
|
+
end
|
224
|
+
|
225
|
+
list.compact.reverse[0..increments - 1].join(' ')
|
226
|
+
end
|
227
|
+
|
183
228
|
# Filter Logic
|
184
229
|
# TODO: Simplify
|
185
230
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
@@ -189,7 +234,7 @@ module GreenHat
|
|
189
234
|
# Experimenting with deep clone
|
190
235
|
results = Marshal.load(Marshal.dump(data))
|
191
236
|
results.select! do |row|
|
192
|
-
args.send(flags.logic) do |arg|
|
237
|
+
args.send(flags.logic || :all?) do |arg|
|
193
238
|
filter_row_key(row, arg, flags)
|
194
239
|
end
|
195
240
|
end
|
@@ -255,7 +300,6 @@ module GreenHat
|
|
255
300
|
end
|
256
301
|
|
257
302
|
# Filter Start and End Times
|
258
|
-
# rubocop:disable Metrics/MethodLength
|
259
303
|
# TODO: This is a bit icky, simplify/dry
|
260
304
|
def self.filter_time(results, flags)
|
261
305
|
if flags.key?(:start)
|
@@ -292,7 +336,6 @@ module GreenHat
|
|
292
336
|
|
293
337
|
results
|
294
338
|
end
|
295
|
-
# rubocop:enable Metrics/MethodLength
|
296
339
|
|
297
340
|
def self.filter_except(results, except)
|
298
341
|
# Avoid Empty Results
|
@@ -368,7 +411,10 @@ module GreenHat
|
|
368
411
|
|
369
412
|
# Loop through Stats, Separate Hash/Tables
|
370
413
|
stats.map do |field|
|
371
|
-
occurrences = filter_count_occurrences(results, field)
|
414
|
+
occurrences = filter_count_occurrences(results, field, flags)
|
415
|
+
|
416
|
+
# Use Truncate For Long Keys
|
417
|
+
occurrences.transform_keys! { |key| key.to_s[0..flags[:truncate]] } if flags[:truncate]
|
372
418
|
|
373
419
|
# Total Occurences
|
374
420
|
total = occurrences.values.sum
|
@@ -387,13 +433,6 @@ module GreenHat
|
|
387
433
|
# Append Header / Total with field name
|
388
434
|
output.unshift([field.to_s.pastel(:bright_black), total])
|
389
435
|
|
390
|
-
# Use Truncate For Long Keys
|
391
|
-
if flags[:truncate]
|
392
|
-
output.map! do |key, value|
|
393
|
-
[key.to_s[0..flags[:truncate]], value]
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
436
|
# Format
|
398
437
|
output.to_h
|
399
438
|
end
|
@@ -405,10 +444,17 @@ module GreenHat
|
|
405
444
|
end
|
406
445
|
|
407
446
|
# Helper to Count occurrences
|
408
|
-
def self.filter_count_occurrences(results, field)
|
447
|
+
def self.filter_count_occurrences(results, field, flags = {})
|
409
448
|
results.each_with_object(Hash.new(0)) do |entry, counts|
|
410
449
|
if entry.key? field
|
411
|
-
|
450
|
+
# Rounding in pagination breaks stats
|
451
|
+
key = if flags.key?(:round) && entry[field].numeric?
|
452
|
+
entry[field].to_f.round(flags.round)
|
453
|
+
else
|
454
|
+
entry[field]
|
455
|
+
end
|
456
|
+
|
457
|
+
counts[key] += 1
|
412
458
|
else
|
413
459
|
counts['None'.pastel(:bright_black)] += 1
|
414
460
|
end
|
@@ -426,48 +472,83 @@ module GreenHat
|
|
426
472
|
end
|
427
473
|
|
428
474
|
# Break out filter row logic into separate method
|
429
|
-
|
430
475
|
def self.filter_row_key(row, arg, flags)
|
431
476
|
# Ignore Other Logic if Field isn't even included / Full Text Searching
|
432
477
|
return false unless row.key?(arg[:field]) || arg[:field] == :text
|
433
478
|
|
434
479
|
# Sensitivity Check / Check for Match / Full Text Searching
|
435
|
-
|
436
|
-
|
437
|
-
else
|
438
|
-
filter_row_entry(row[arg.field].to_s, arg, flags)
|
439
|
-
end
|
480
|
+
search_data = arg[:field] == :text ? row : row[arg.field]
|
481
|
+
match = filter_row_entry(search_data.to_s, arg, flags)
|
440
482
|
|
441
483
|
# Pivot of off include vs exclude
|
442
484
|
if arg.bang
|
443
|
-
!
|
485
|
+
!match
|
444
486
|
else
|
445
|
-
|
487
|
+
match
|
446
488
|
end
|
447
489
|
end
|
448
490
|
|
449
491
|
# Field Partial / Case / Exact search
|
450
492
|
def self.filter_row_entry(entry, arg, flags)
|
451
493
|
# Exact Matching / Unless doing full text search
|
452
|
-
return entry
|
494
|
+
return entry == arg.value.to_s if flags.key?(:exact) && arg.field != :text
|
453
495
|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
496
|
+
# Cast to String/Integer Helper
|
497
|
+
entry, value = filter_entry_cast(entry, arg, flags)
|
498
|
+
|
499
|
+
entry.send(arg.logic, value)
|
500
|
+
end
|
501
|
+
|
502
|
+
# Handle casting to strings or integers
|
503
|
+
def self.filter_entry_cast(entry, arg, flags)
|
504
|
+
# Cast to String
|
505
|
+
value = arg.value.to_s
|
506
|
+
|
507
|
+
case arg.logic
|
508
|
+
when :include?
|
509
|
+
|
510
|
+
# Exact Case argument
|
511
|
+
unless flags.key?(:case)
|
512
|
+
entry.downcase!
|
513
|
+
value.downcase!
|
514
|
+
end
|
515
|
+
when :>=, :<=
|
516
|
+
entry = entry.to_i if entry.numeric?
|
517
|
+
value = value.to_i if value&.numeric?
|
458
518
|
end
|
519
|
+
|
520
|
+
[entry, value]
|
521
|
+
end
|
522
|
+
|
523
|
+
def self.filter_entry_logic(entry, arg)
|
524
|
+
entry.send(arg.logic, arg.value)
|
459
525
|
end
|
460
526
|
|
461
527
|
# Total Count Helper
|
462
|
-
def self.total_count(results)
|
463
|
-
results.
|
528
|
+
def self.total_count(results, flags)
|
529
|
+
results.map do |k, v|
|
464
530
|
puts k
|
465
|
-
puts "Total: #{v.count.to_s.pastel(:blue)}"
|
531
|
+
# puts "Total: #{v.count.to_s.pastel(:blue)}"
|
532
|
+
# puts "Time Covered: #{calculate_duration(v).pastel(:cyan)}"
|
533
|
+
|
534
|
+
output = {}
|
535
|
+
output[:total] = v.count
|
536
|
+
output[:duration] = calculate_duration(v)
|
537
|
+
|
538
|
+
# Sort / Get first and Last
|
539
|
+
list = v.select(&:time).map(&:time)
|
540
|
+
unless list.blank?
|
541
|
+
output[:start] = list.first
|
542
|
+
output[:end] = list.last
|
543
|
+
end
|
544
|
+
|
545
|
+
puts render_table(output, flags)
|
546
|
+
|
466
547
|
puts
|
467
548
|
end
|
468
549
|
end
|
469
550
|
|
470
|
-
#
|
551
|
+
# Table Printer Helper
|
471
552
|
def self.fields_print(results)
|
472
553
|
results.each do |k, v|
|
473
554
|
puts k
|
@@ -531,7 +612,7 @@ module GreenHat
|
|
531
612
|
return file if file.instance_of?(Thing)
|
532
613
|
|
533
614
|
if flags.fuzzy_file_match
|
534
|
-
Thing.all.select { |x| x.name.include? file }
|
615
|
+
Thing.all.select { |x| x.name.include?(file) || x.type.include?(file) }
|
535
616
|
else
|
536
617
|
Thing.where name: file
|
537
618
|
end
|
@@ -543,62 +624,6 @@ module GreenHat
|
|
543
624
|
things
|
544
625
|
end
|
545
626
|
|
546
|
-
# Main Entry Point for Searching
|
547
|
-
# def self.search_start(log_list, filter_type, args, opts)
|
548
|
-
def self.search_start(files, flags, args)
|
549
|
-
# Convert to Things
|
550
|
-
logs = ShellHelper.find_things(files, flags)
|
551
|
-
|
552
|
-
logs.each_with_object({}) do |log, obj|
|
553
|
-
# Ignore Empty Results / No Thing
|
554
|
-
next if log&.data.blank?
|
555
|
-
|
556
|
-
obj[log.friendly_name] = ShellHelper.search(log.data, flags, args)
|
557
|
-
|
558
|
-
obj
|
559
|
-
end
|
560
|
-
end
|
561
|
-
|
562
|
-
# Generic Search Helper / String/Regex
|
563
|
-
def self.search(data, flags = {}, args = {})
|
564
|
-
results = data.clone.flatten.compact
|
565
|
-
results.select! do |row|
|
566
|
-
args.send(flags.logic) do |arg|
|
567
|
-
search_row(row, arg, flags)
|
568
|
-
end
|
569
|
-
end
|
570
|
-
|
571
|
-
# Strip Results if Slice is defined
|
572
|
-
results.map! { |row| row.slice(*flags[:slice]) } if flags[:slice]
|
573
|
-
|
574
|
-
# Strip Results if Except is defined
|
575
|
-
results.map! { |row| row.except(*flags[:except]) } if flags[:except]
|
576
|
-
|
577
|
-
# Remove Blank from either slice or except
|
578
|
-
results.reject!(&:empty?)
|
579
|
-
|
580
|
-
results
|
581
|
-
end
|
582
|
-
|
583
|
-
# Break out filter row logic into separate method
|
584
|
-
def self.search_row(row, arg, flags)
|
585
|
-
# Sensitivity Check / Check for Match
|
586
|
-
included = filter_row_entry(row.to_s, arg, flags)
|
587
|
-
|
588
|
-
# Pivot of off include vs exclude
|
589
|
-
if arg.bang
|
590
|
-
!included
|
591
|
-
else
|
592
|
-
included
|
593
|
-
end
|
594
|
-
end
|
595
|
-
|
596
|
-
# TODO: Remove?
|
597
|
-
# Color Reader Helper
|
598
|
-
# def self.pastel
|
599
|
-
# @pastel ||= Pastel.new
|
600
|
-
# end
|
601
|
-
|
602
627
|
# Number Helper
|
603
628
|
# https://gitlab.com/zedtux/human_size_to_number/-/blob/master/lib/human_size_to_number/helper.rb
|
604
629
|
def self.human_size_to_number(string)
|
@@ -620,23 +645,6 @@ module GreenHat
|
|
620
645
|
number.round
|
621
646
|
end
|
622
647
|
|
623
|
-
# TODO: Needed?
|
624
|
-
def self.filter_and(data, params = {})
|
625
|
-
result = data.clone.flatten.compact
|
626
|
-
params.each do |k, v|
|
627
|
-
result.select! do |row|
|
628
|
-
if row.key? k.to_sym
|
629
|
-
row[k.to_sym].include? v
|
630
|
-
else
|
631
|
-
false
|
632
|
-
end
|
633
|
-
end
|
634
|
-
next
|
635
|
-
end
|
636
|
-
|
637
|
-
result
|
638
|
-
end
|
639
|
-
|
640
648
|
# General Helper for `show`
|
641
649
|
def self.common_opts
|
642
650
|
puts 'Common Options'.pastel(:blue)
|
data/lib/greenhat/shell.rb
CHANGED
@@ -43,6 +43,13 @@ module GreenHat
|
|
43
43
|
/dmesg/
|
44
44
|
]
|
45
45
|
},
|
46
|
+
'lets-encrypt/renewal' => {
|
47
|
+
format: :bracket_log,
|
48
|
+
log: true,
|
49
|
+
pattern: [
|
50
|
+
%r{lets-encrypt/renewal}
|
51
|
+
]
|
52
|
+
},
|
46
53
|
'repmgrd/current' => {
|
47
54
|
format: :bracket_log,
|
48
55
|
log: true,
|
@@ -87,6 +94,12 @@ module GreenHat
|
|
87
94
|
/getenforce/
|
88
95
|
]
|
89
96
|
},
|
97
|
+
'geo-logcursor/current' => {
|
98
|
+
format: :raw,
|
99
|
+
pattern: [
|
100
|
+
%r{geo-logcursor/current}
|
101
|
+
]
|
102
|
+
},
|
90
103
|
'gitaly/current' => {
|
91
104
|
format: :json_shell,
|
92
105
|
log: true,
|
@@ -225,7 +238,8 @@ module GreenHat
|
|
225
238
|
format: :json,
|
226
239
|
log: true,
|
227
240
|
pattern: [
|
228
|
-
%r{gitlab-rails/audit_json.log}
|
241
|
+
%r{gitlab-rails/audit_json.log},
|
242
|
+
%r{webservice.log/audit_json.log}
|
229
243
|
]
|
230
244
|
},
|
231
245
|
'gitlab-rails/auth.log' => {
|
@@ -336,6 +350,20 @@ module GreenHat
|
|
336
350
|
%r{nginx/current}
|
337
351
|
]
|
338
352
|
},
|
353
|
+
'nginx-ingress.log' => {
|
354
|
+
format: :kube_nginx,
|
355
|
+
log: true,
|
356
|
+
pattern: [
|
357
|
+
/nginx-ingress.log/
|
358
|
+
]
|
359
|
+
},
|
360
|
+
'nginx/access.log' => {
|
361
|
+
format: :nginx,
|
362
|
+
log: true,
|
363
|
+
pattern: [
|
364
|
+
%r{nginx/access.log}
|
365
|
+
]
|
366
|
+
},
|
339
367
|
'nginx/gitlab_pages_access.log' => {
|
340
368
|
format: :nginx,
|
341
369
|
log: true,
|
@@ -422,7 +450,7 @@ module GreenHat
|
|
422
450
|
]
|
423
451
|
},
|
424
452
|
'registry/current' => {
|
425
|
-
format: :
|
453
|
+
format: :time_registry,
|
426
454
|
log: true,
|
427
455
|
pattern: [
|
428
456
|
%r{registry/current},
|
@@ -444,16 +472,18 @@ module GreenHat
|
|
444
472
|
},
|
445
473
|
'puma/puma_stderr.log' => {
|
446
474
|
format: :raw,
|
447
|
-
log:
|
475
|
+
log: false,
|
448
476
|
pattern: [
|
449
|
-
%r{puma/puma_stderr.log}
|
477
|
+
%r{puma/puma_stderr.log},
|
478
|
+
%r{webservice.log/puma.stderr.log}
|
450
479
|
]
|
451
480
|
},
|
452
481
|
'puma/puma_stdout.log' => {
|
453
482
|
format: :json,
|
454
483
|
log: true,
|
455
484
|
pattern: [
|
456
|
-
%r{puma/puma_stdout.log}
|
485
|
+
%r{puma/puma_stdout.log},
|
486
|
+
%r{webservice.log/puma.stdout.log}
|
457
487
|
]
|
458
488
|
},
|
459
489
|
'gitlab-pages/current' => {
|
@@ -529,6 +559,20 @@ module GreenHat
|
|
529
559
|
%r{unicorn/current}
|
530
560
|
]
|
531
561
|
},
|
562
|
+
'unicorn_stats' => {
|
563
|
+
format: :time_space,
|
564
|
+
log: true,
|
565
|
+
pattern: [
|
566
|
+
/unicorn_stats/
|
567
|
+
]
|
568
|
+
},
|
569
|
+
'unicorn/unicorn_stdout.log' => {
|
570
|
+
format: :raw,
|
571
|
+
log: true,
|
572
|
+
pattern: [
|
573
|
+
%r{unicorn/unicorn_stdout.log}
|
574
|
+
]
|
575
|
+
},
|
532
576
|
'running_swappiness' => {
|
533
577
|
format: :raw,
|
534
578
|
pattern: [
|
@@ -566,6 +610,7 @@ module GreenHat
|
|
566
610
|
log: true,
|
567
611
|
pattern: [
|
568
612
|
%r{sidekiq/current},
|
613
|
+
/sidekiq_current/,
|
569
614
|
%r{sidekiq/@.*}
|
570
615
|
]
|
571
616
|
},
|
@@ -629,6 +674,12 @@ module GreenHat
|
|
629
674
|
/uname/
|
630
675
|
]
|
631
676
|
},
|
677
|
+
'gitlab_socket_stats' => {
|
678
|
+
format: :gitlab_socket_stats,
|
679
|
+
pattern: [
|
680
|
+
/gitlab_socket_stats/
|
681
|
+
]
|
682
|
+
},
|
632
683
|
'uptime' => {
|
633
684
|
format: :raw,
|
634
685
|
pattern: [
|
@@ -745,13 +796,15 @@ module GreenHat
|
|
745
796
|
'gitlab-rails/application.log' => {
|
746
797
|
format: :raw,
|
747
798
|
pattern: [
|
748
|
-
%r{gitlab-rails/application.log}
|
799
|
+
%r{gitlab-rails/application.log},
|
800
|
+
%r{webservice.log/application.log}
|
749
801
|
]
|
750
802
|
},
|
751
803
|
'gitlab-rails/production.log' => {
|
752
804
|
format: :raw,
|
753
805
|
pattern: [
|
754
|
-
%r{gitlab-rails/production.log}
|
806
|
+
%r{gitlab-rails/production.log},
|
807
|
+
%r{webservice.log/production.log}
|
755
808
|
]
|
756
809
|
},
|
757
810
|
'gitlab/version-manifest.txt' => {
|
@@ -765,6 +818,72 @@ module GreenHat
|
|
765
818
|
pattern: [
|
766
819
|
%r{sidekiq/perf.data}
|
767
820
|
]
|
821
|
+
},
|
822
|
+
|
823
|
+
# ======================================================================
|
824
|
+
# KubeSoS TODO Section
|
825
|
+
# Things I am going to shortcut and set to raw for now
|
826
|
+
# ======================================================================
|
827
|
+
# Attempted Parsing
|
828
|
+
'kubesos_json' => {
|
829
|
+
log: true,
|
830
|
+
format: :kube_json,
|
831
|
+
pattern: [
|
832
|
+
/gitaly.log/
|
833
|
+
]
|
834
|
+
},
|
835
|
+
|
836
|
+
'kube_webservice' => {
|
837
|
+
log: false,
|
838
|
+
format: :kube_webservice,
|
839
|
+
pattern: [
|
840
|
+
/^webservice\.log$/
|
841
|
+
]
|
842
|
+
},
|
843
|
+
|
844
|
+
'kubesos' => {
|
845
|
+
format: :raw,
|
846
|
+
pattern: [
|
847
|
+
/all_values.yaml/,
|
848
|
+
%r{webservice.log/sidekiq_client.log},
|
849
|
+
/chart-version/,
|
850
|
+
/configmaps/,
|
851
|
+
/describe_deployments/,
|
852
|
+
/describe_ingress/,
|
853
|
+
/describe_nodes/,
|
854
|
+
/describe_pods/,
|
855
|
+
/describe_pv/,
|
856
|
+
/describe_pvc/,
|
857
|
+
/events/,
|
858
|
+
/get_deployments/,
|
859
|
+
/get_endpoints/,
|
860
|
+
/get_jobs/,
|
861
|
+
/get_pods/,
|
862
|
+
/get_pv/,
|
863
|
+
/get_pvc/,
|
864
|
+
/get_services/,
|
865
|
+
/gitaly.log/,
|
866
|
+
/gitlab-exporter.log/,
|
867
|
+
/gitlab-pages.log/,
|
868
|
+
/gitlab-shell.log/,
|
869
|
+
/grafana.log/,
|
870
|
+
/helm-version/,
|
871
|
+
/kubectl-check/,
|
872
|
+
/migrations.log/,
|
873
|
+
/minio.log/,
|
874
|
+
/nfs-client-provisioner.log/,
|
875
|
+
/operator.log/,
|
876
|
+
/postgresql.log/,
|
877
|
+
/prometheus.log/,
|
878
|
+
/redis.log/,
|
879
|
+
/registry.log/,
|
880
|
+
/secrets/,
|
881
|
+
/sidekiq.log/,
|
882
|
+
/task-runner.log/,
|
883
|
+
/top_nodes/,
|
884
|
+
/top_pods/,
|
885
|
+
/user_supplied_values.yaml/
|
886
|
+
]
|
768
887
|
}
|
769
888
|
}
|
770
889
|
end
|
@@ -43,6 +43,10 @@ module GreenHat
|
|
43
43
|
# Check for Common Fields
|
44
44
|
def format_json_time(result)
|
45
45
|
result.time = format_time_parse(result.time) if result.key? :time
|
46
|
+
|
47
|
+
# If timestamp exists but time doesn't, add time
|
48
|
+
result.time = format_time_parse(result.timestamp) if result.key?(:timestamp) && !result.key?(:time)
|
49
|
+
|
46
50
|
result.created_at = format_time_parse(result.created_at) if result.key? :created_at
|
47
51
|
result.enqueued_at = format_time_parse(result.enqueued_at) if result.key? :enqueued_at
|
48
52
|
rescue StandardError => e
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Top
|
2
|
+
module GreenHat
|
3
|
+
# Log
|
4
|
+
module Formatters
|
5
|
+
# ==========================================================================
|
6
|
+
# K8s logs seem to have a lot of non-json entries
|
7
|
+
# Extract all json, ignore everything else
|
8
|
+
# ==========================================================================
|
9
|
+
def format_kube_json
|
10
|
+
self.result = raw.map do |row|
|
11
|
+
# Skip all non-json
|
12
|
+
next unless row.first == '{'
|
13
|
+
|
14
|
+
result = begin
|
15
|
+
Oj.load row
|
16
|
+
rescue EncodingError
|
17
|
+
puts
|
18
|
+
next
|
19
|
+
end
|
20
|
+
|
21
|
+
# Parsing Time
|
22
|
+
format_json_traverse result
|
23
|
+
|
24
|
+
result.sort.to_h
|
25
|
+
rescue StandardError => e
|
26
|
+
# TODO: Background Logger?
|
27
|
+
e.message
|
28
|
+
LogBot.warn('JSON Parse', e.message)
|
29
|
+
next
|
30
|
+
end.compact
|
31
|
+
|
32
|
+
:ok
|
33
|
+
end
|
34
|
+
# =========================================================================
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Top
|
2
|
+
module GreenHat
|
3
|
+
# Log
|
4
|
+
module Formatters
|
5
|
+
# ==========================================================================
|
6
|
+
# Formatters
|
7
|
+
# ==========================================================================
|
8
|
+
def format_kube_nginx
|
9
|
+
self.result = raw.map do |row|
|
10
|
+
ip, _sym, remote_user, rest = row.split(' ', 4)
|
11
|
+
|
12
|
+
time, rest = rest.split(']', 2)
|
13
|
+
time = Time.strptime(time, '[%d/%b/%Y:%H:%M:%S %z')
|
14
|
+
|
15
|
+
verb, status, bytes, http_referer, http_user_agent, gzip_ratio = Shellwords.split(rest)
|
16
|
+
|
17
|
+
method, path, http_version = verb.split
|
18
|
+
|
19
|
+
{
|
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
|
31
|
+
}
|
32
|
+
|
33
|
+
# Fall back for malformed logs
|
34
|
+
rescue StandardError
|
35
|
+
{ message: row }
|
36
|
+
end
|
37
|
+
|
38
|
+
:ok
|
39
|
+
end
|
40
|
+
|
41
|
+
# rubocop:disable Layout/LineLength
|
42
|
+
# NGINX Conf: /var/opt/gitlab/nginx/conf/nginx.conf
|
43
|
+
# log_format gitlab_access '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent" $gzip_ratio';
|
44
|
+
# rubocop:enable Layout/LineLength
|
45
|
+
|
46
|
+
# ==========================================================================
|
47
|
+
end
|
48
|
+
end
|