Last active
December 2, 2016 14:48
Revisions
-
csabahenk revised this gist
Dec 2, 2016 . 1 changed file with 1 addition and 4 deletions.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 charactersOriginal file line number Diff line number Diff line change @@ -155,10 +155,7 @@ def report summary, fields=nil op.on("--show-columns[=bool]", TrueClass, "show colums used for CSV output") { |v| showcols = v } op.parse! showcols and puts (cols || GlusterConf::DEFAULTFIELDS).join(",") $*.each { |f| GlusterConf.module_eval { -
csabahenk revised this gist
Dec 1, 2016 . 1 changed file with 64 additions and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -98,15 +98,78 @@ def parse src topvol end def summarize vol, perf=[], cluster={"distribute"=>0, "replicate"=>0} xclass, xtype = vol["type"].split("/") case xclass when "performance" perf << xtype when "cluster" cluster[xtype] = vol["subvolumes"].size end (vol["subvolumes"]||[]).each { |sv| summarize sv, perf, cluster } {performance: perf, cluster: cluster} end DEFAULTFIELDS = %w[distribute replicate write-behind readdir-ahead quick-read md-cache perf-other] def report summary, fields=nil fields ||= DEFAULTFIELDS perf_hot = [] perf_other = "" rep = fields.map { |n| case n when "distribute", "replicate" summary[:cluster][n] when "perf-other" perf_other else perf_hot << n summary[:performance].include?(n) ? '✓' : '✖' end } perf_other << (summary[:performance] - perf_hot).reverse.join(" ") rep end end if __FILE__ == $0 require 'yaml' require 'csv' require 'optparse' fmt = 'yaml' cols = nil showcols = false op = OptionParser.new op.banner << " [<volfile>|<logfile>]..." op.on("-f", "--format FMT", "output format (csv or yaml)") { |v| %w[csv yaml].include? v or raise "Unknown format #{v}" fmt = v } op.on("--columns COLS", Array, "comma-separated column names for CSV (one of #{GlusterConf::DEFAULTFIELDS.join(",")})") { |v| cols = v } op.on("--show-columns[=bool]", TrueClass, "show colums used for CSV output") { |v| showcols = v } op.parse! if showcols puts (cols || GlusterConf::DEFAULTFIELDS).join(" ") exit end $*.each { |f| GlusterConf.module_eval { preparse(f == "-" ? STDIN : IO.readlines(f)).each { |v| vol = parse v print case fmt when "yaml" vol.to_yaml when "csv" report(summarize(vol), cols).to_csv end } } } -
csabahenk revised this gist
Dec 1, 2016 . 1 changed file with 43 additions and 2 deletions.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 charactersOriginal file line number Diff line number Diff line change @@ -10,6 +10,44 @@ def assert x, *bool bool.each { |b| raise GlusterConfError, "#{$.}: #{x}" unless bool } end LOGSEP = /\A\+---/ IDP = proc {|x| x} # extract conf from logs def preparse src vols = [] in_vol = nil is_log = nil preprocess = nil src.each { |l| (preprocess || IDP)[l] =~ /\A\s*\Z/ and next if in_vol if is_log and l =~ LOGSEP in_vol = false else vols.last << preprocess[l] end else if l =~ /\A\s*(volume|type|option|subvolumes|end-volume)(\s|\Z)/ in_vol == false and raise "mixed source" in_vol = true preprocess = IDP is_log = false vols << [l] else is_log = true preprocess ||= proc { |x| x.sub /\A\s*\d+: /, "" } if l =~ LOGSEP in_vol = true vols << [] end end end } vols end def parse src volh = {} vol = {} @@ -66,7 +104,10 @@ def parse src require 'yaml' $*.each { |f| GlusterConf.module_eval { preparse(f == "-" ? STDIN : IO.readlines(f)).each { |v| print parse(v).to_yaml } } } end -
csabahenk revised this gist
Dec 1, 2016 . 1 changed file with 4 additions and 1 deletion.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 charactersOriginal file line number Diff line number Diff line change @@ -65,5 +65,8 @@ def parse src if __FILE__ == $0 require 'yaml' $*.each { |f| print GlusterConf.parse( f == "-" ? STDIN : IO.readlines(f)).to_yaml } end -
csabahenk revised this gist
Dec 1, 2016 . 2 changed files with 69 additions and 57 deletions.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 charactersOriginal file line number Diff line number Diff line change @@ -1,57 +0,0 @@ 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ #!/usr/bin/env ruby module GlusterConf extend self class GlusterConfError < Exception end def assert x, *bool bool.each { |b| raise GlusterConfError, "#{$.}: #{x}" unless bool } end def parse src volh = {} vol = {} src.each { |l| ls = l.split case ls[0] when "volume" assert l, ls.size == 2, vol.empty? vol["name"] = ls[1] when "type" assert l, ls.size == 2, vol["name"], !vol["type"] vol["type"] = ls[1] when "option" assert l, ls.size == 3, vol["name"] (vol["option"] ||= {})[ls[1]] = case ls[2] when /\A\d+\Z/ Integer ls[2] when /\Aon|yes|true|enable\Z/i true when /\Aoff|no|false|disable\Z/i false else ls[2] end when "subvolumes" assert l, ls.size > 1, vol["name"], !vol["subvolumes"] vol["subvolumes"] = ls[1..-1] when "end-volume" assert l, ls.size == 1, vol["name"], vol["type"] volh[vol["name"]] = vol vol = {} when nil else assert l, false end } # XXX we could have more proper check to see if graph is a tree subvolumes = [] volh.each_value { |vol| subvolumes.concat(vol["subvolumes"] || []) } topvols = volh.keys - subvolumes assert "ambiguous toplevel volume: #{topvols.join(", ")}", topvols.size == 1 topvol = volh[topvols[0]] volh.each_value { |vol| (vol["subvolumes"] || []).map! { |w| volh.fetch w } } topvol end end if __FILE__ == $0 require 'yaml' puts GlusterConf.parse($<).to_yaml end -
csabahenk created this gist
Dec 1, 2016 .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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,57 @@ #!/usr/bin/env ruby require 'yaml' class GlusterConfError < Exception end def assert x, *bool bool.each { |b| raise GlusterConfError, "#{$.}: #{x}" unless bool } end volh = {} vol = {} $<.each { |l| ls = l.split case ls[0] when "volume" assert l, ls.size == 2, vol.empty? vol["name"] = ls[1] when "type" assert l, ls.size == 2, vol["name"], !vol["type"] vol["type"] = ls[1] when "option" assert l, ls.size == 3, vol["name"] (vol["option"] ||= {})[ls[1]] = case ls[2] when /\A\d+\Z/ Integer ls[2] when /\Aon|yes|true|enable\Z/i true when /\Aoff|no|false|disable\Z/i false else ls[2] end when "subvolumes" assert l, ls.size > 1, vol["name"], !vol["subvolumes"] vol["subvolumes"] = ls[1..-1] when "end-volume" assert l, ls.size == 1, vol["name"], vol["type"] volh[vol["name"]] = vol vol = {} when nil else assert l, false end } subvolumes = [] volh.each_value { |vol| subvolumes.concat(vol["subvolumes"] || []) } topvols = volh.keys - subvolumes assert "ambiguous toplevel volume: #{topvols.join(", ")}", topvols.size == 1 topvol = volh[topvols[0]] volh.each_value { |vol| (vol["subvolumes"] || []).map! { |w| volh[w] } } puts topvol.to_yaml