-
Notifications
You must be signed in to change notification settings - Fork 17
Y2logs analyzer #149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
jreidinger
wants to merge
7
commits into
master
Choose a base branch
from
y2logs_analyzer
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+180
−0
Draft
Y2logs analyzer #149
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
cf8a636
initial version of analyze logs script
jreidinger 5fd969a
add options including help and logger
jreidinger 910e419
force arguments
jreidinger 3e095f3
logs in which module is called at least once
jreidinger b92fc55
add info about number of analyzed logs
jreidinger 0a1d241
add there also product detection
jreidinger bd05a14
Chagnes from review
jreidinger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| #! /usr/bin/ruby | ||
|
|
||
| require "tmpdir" | ||
| require "cheetah" | ||
| require "yaml" | ||
| require "optionparser" | ||
|
|
||
| def unpack_file(file) | ||
| case file | ||
| when /\.gz$/ | ||
| Cheetah.run("gzip", "-d", file) | ||
| file[/(.*).gz$/, 1] | ||
| when /\.bz2?$/ | ||
| Cheetah.run("bzip2", "-d", file) | ||
| file[/(.*).bz2?$/, 1] | ||
| when /\.xz$/ | ||
| Cheetah.run("xz", "-d", file) | ||
| file[/(.*).xz$/, 1] | ||
| when /\.7z$/ | ||
| Cheetah.run("7z", "e", file) | ||
| file[/(.*).7z$/, 1] | ||
| else | ||
| file | ||
| end | ||
| end | ||
|
|
||
| def set_mod_ui(result, mod, ui) | ||
| result[:modules] ||= {} | ||
| result[:modules][mod.to_sym] ||= {} | ||
| result[:modules][mod.to_sym][:count] ||= 0 | ||
| result[:modules][mod.to_sym][:count] += 1 | ||
| result[:modules][mod.to_sym][:ui] ||= {} | ||
| result[:modules][mod.to_sym][:ui][ui] ||= 0 | ||
| result[:modules][mod.to_sym][:ui][ui] += 1 | ||
| end | ||
|
|
||
| def find_modules(result, content) | ||
| # y2start kind of log line. example: | ||
| # 2020-01-06 11:31:14 <1> localhost(3282) [Ruby] bin/y2start:22 y2base called with ["installation", "--arg", "continue", "qt", "--noborder", "--auto-fonts", "--fullscreen"] | ||
| content.lines.grep(/y2base called with /).each do |line| | ||
| mod = line[/\["([^"]+)"/, 1] | ||
| raise "invalid module for #{line}." unless mod | ||
| interface = case line | ||
| when /"qt"/ then :qt | ||
| when /"ncurses"/ then :ncurses | ||
| when /"UI"/ then :no | ||
| else raise "Unknown UI in #{line}." | ||
| end | ||
| # TODO CLI detection | ||
| set_mod_ui(result, mod, interface) | ||
| end | ||
| # y2base kind of log line. example: | ||
| # 2017-11-29 06:25:29 <1> install(3162) [liby2] genericfrontend.cc(main):617 Launched YaST2 component 'y2base' 'installation' '("initial")' 'qt' '--noborder' '--auto-fonts' '--fullscreen' | ||
| content.lines.grep(/Launched YaST2 component 'y2base' /).each do |line| | ||
| mod = line[/'y2base' '([^']+)'/, 1] | ||
| raise "invalid module for #{line}." unless mod | ||
| interface = case line | ||
| when /'qt'/ then :qt | ||
| when /'ncurses'/ then :ncurses | ||
| when /'UI'/ then :no | ||
| else raise "Unknown UI in #{line}." | ||
| end | ||
| # TODO CLI detection | ||
| set_mod_ui(result, mod, interface) | ||
| end | ||
| end | ||
|
|
||
| def find_base_product(result, content) | ||
| # use os-release. Line looks like: | ||
| # 2014-05-19 09:31:54 <1> linux(2541) [Ruby] modules/Misc.rb:197 ."/mnt/etc/os-release"."PRETTY_NAME": 'SUSE Linux Enterprise Server 12' | ||
| os_release = content.lines.grep(/os-release.*PRETTY_NAME":/).last | ||
| if os_release | ||
| product = os_release[/'(.*)'/, 1] | ||
| result[:product] = product | ||
| end | ||
| end | ||
|
|
||
| def analyze_log(result, file) | ||
| file = unpack_file(file) | ||
| # TODO: can be memory consuming | ||
| content = File.read(file) | ||
| find_modules(result, content) | ||
| find_base_product(result, content) | ||
| rescue ArgumentError => e | ||
| raise "Failed in #{file} with #{e.inspect}" | ||
| end | ||
|
|
||
| # Tarballs | ||
| TARBALLS_REGEXPS = [/\.tar\./, /\.tbz2$/, /\.tgz$/, /\.txz$/, /\.t7z$/] | ||
| ZIP_REGEXPS = [/\.zip$/] | ||
| RAR_REGEXPS = [/\.rar$/] | ||
| def single_file(file) | ||
| result = {} | ||
| if (TARBALLS_REGEXPS + ZIP_REGEXPS + RAR_REGEXPS).any?{ |r| file =~ r } | ||
| temp_dir = true | ||
| archive = file | ||
| file = Dir.mktmpdir("logs-analyzer") | ||
| if TARBALLS_REGEXPS.any? { |r| archive =~ r } | ||
| Cheetah.run("tar", "xvf", archive, "-C", file) | ||
| elsif ZIP_REGEXPS.any? { |r| archive =~ r } | ||
| Cheetah.run("unzip", archive, "-d", file) | ||
| elsif RAR_REGEXPS.any? { |r| archive =~ r } | ||
| Cheetah.run("unrar", "x", archive, file) | ||
| else | ||
| raise "Should not happen :)" | ||
| end | ||
| log.info "archive #{archive} destination #{file}" | ||
| end | ||
|
|
||
| if File.directory?(file) | ||
| Dir["#{file}/**/y2log{,-[1-9]}{,.*}"].each do |f| | ||
| log.info "directory #{file} analyze file #{f}" | ||
| analyze_log(result, f) | ||
| end | ||
| else | ||
| log.info "analyze file #{file}" | ||
| analyze_log(result, file) | ||
| end | ||
|
|
||
| result | ||
| ensure | ||
| if temp_dir | ||
| Cheetah.run("rm", "-rf", file) | ||
|
||
| end | ||
| end | ||
|
|
||
| def merge_results(total, single) | ||
| return unless single[:modules] | ||
| total[:logs_analyzed] ||= 0 | ||
| total[:logs_analyzed] += 1 | ||
| single[:modules].each_pair do |m, data| | ||
| total[:modules] ||= {} | ||
| total[:modules][m] ||= {} | ||
| total[:modules][m][:count] ||= 0 | ||
| total[:modules][m][:count] += data[:count] | ||
| total[:modules][m][:at_least_once] ||= 0 | ||
| total[:modules][m][:at_least_once] += 1 | ||
| end | ||
|
|
||
| total[:products] ||= {} | ||
| product = single[:product] | ||
| if product | ||
| total[:products][product] ||= 0 | ||
| total[:products][product] += 1 | ||
| end | ||
| end | ||
|
|
||
| logger = "/dev/null" | ||
| output = nil | ||
|
|
||
| parser = OptionParser.new do |opts| | ||
| opts.banner = "Usage: analyze_logs [options] path [other paths...]\nDefaults: analyze_logs <path>" | ||
| opts.on("-l", "--log LOG", "File to which log") { |o| logger = o } | ||
| opts.on("-o", "--output OUTPUT", "File to which YAML will be written.") { |o| output = o } | ||
| end | ||
| parser.parse! | ||
|
|
||
| if ARGV.empty? | ||
| STDERR.puts parser.help | ||
| exit 1 | ||
| end | ||
|
|
||
| @log = Logger.new(logger) | ||
|
|
||
| def log | ||
| @log | ||
| end | ||
|
|
||
| result = {} | ||
|
|
||
| ARGV.each do |arg| | ||
| merge_results(result, single_file(arg)) | ||
| end | ||
|
|
||
| final = result.to_yaml | ||
| if output | ||
| File.write(output, final) | ||
| else | ||
| puts final | ||
| end | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not be that sure 😉