lib/gems/pending/util/miq_logger_processor.rb
class MiqLoggerProcessor include Enumerable attr_accessor :file_name def initialize(file_name) @file_name = file_name end def each File.open(file_name, "r") do |f| while (line = get_next_line(f)) yield line end end ensure cleanup_get_next_line end # # Convert the provided data into a graph in png format. Valid options are: # # :graph_type:: :line or :stacked # :outfile:: output file name (default is "graph.png") # # :title_font_size:: size of the title in pixels (default is 24) # :legend_font_size:: size of the legend items in pixels (default is 12) # :marker_font_size:: size of the x axis labels in pixels (default is 10) # # :x_axis_label:: x axis label (default is header of first column in data) # :y_axis_label:: y axis label (default is nil) # :title:: Title of the graph (default is "y_axis_label by x_axis_label"; if # y_axis_label is nil, defaults to "series 1, series 2, ...") # # :y_axis_increment:: y axis increment # :minimum_value:: y axis minimum value # :maximum_value:: y axis maximum value # # :convert_data_method:: method to call on each data point if a conversion is # needed (e.g. :to_i) #Cyclomatic complexity for to_png is too high. [17/11]
Method `to_png` has 31 lines of code (exceeds 25 allowed). Consider refactoring.
Method `to_png` has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. def self.to_png(data, options = {}) require 'gruff' graph = case options[:graph_type] when :line then Gruff::Line.new when :stacked then Gruff::StackedBar.newDuplicate branch body detected. else Gruff::Line.new end graph.title_font_size = options[:title_font_size] || 24 graph.legend_font_size = options[:legend_font_size] || 12 graph.marker_font_size = options[:marker_font_size] || 10 header = data[0] data = data.transpose x_axis_values = data.shift x_axis_values.shift # TODO: Move this outside of the to_png method to the method that collects the data (like the csv_to_png method) convert_data_method = options[:convert_data_method] data.each do |datum| label = datum.shift datum.collect! { |d| d.send(convert_data_method) } if convert_data_method graph.data(label, datum) end graph.x_axis_label = options[:x_axis_label] || header[0] graph.y_axis_label = options[:y_axis_label] graph.title = options[:title] || "#{graph.y_axis_label || header[1..-1].join(", ")} by #{graph.x_axis_label}" graph.y_axis_increment = options[:y_axis_increment] if options[:y_axis_increment] graph.minimum_value = options[:minimum_value] if options[:minimum_value] graph.maximum_value = options[:maximum_value] if options[:maximum_value] graph.labels = { 0 => x_axis_values[0], x_axis_values.length - 1 => x_axis_values[-1] } graph.labels[x_axis_values.length / 2] = x_axis_values[x_axis_values.length / 2] if x_axis_values.length > 2 graph.write(options[:outfile] || 'graph.png') end def self.csv_to_png(filename, options = {}) to_png(read_csv(filename), options) end def self.read_csv(filename) require 'csv' CSV.read(filename) end private Method `get_next_line` has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring. def get_next_line(f) return nil if @next_line == :eof line = @next_line || "" loop do new_line = f.gets if new_line.nil? @next_line = :eof return MiqLoggerLine.new(line) elsif @next_line.nil? @next_line = new_line line << new_lineUse `match?` instead of `=~` when `MatchData` is not used. elsif new_line[0, 6] =~ /^\[(?:----|\d{4})\]$/ @next_line = new_line return MiqLoggerLine.new(line) else line << new_line end end end def cleanup_get_next_line remove_instance_variable(:@next_line) if instance_variable_defined?(:@next_line) endend class MiqLoggerLine < String def parts @parts ||= self.class.split_raw_line(self).freeze end alias_method :to_a, :parts alias_method :split, :parts PARTS = %w(time pid tid level progname q_task_id fq_method message).freeze PARTS.each_with_index do |m, i| define_method(m) { parts[i] } end def each parts.each { |p| yield p } end Useless `private` access modifier. private Method `split_raw_line` has a Cognitive Complexity of 11 (exceeds 5 allowed). Consider refactoring.
`private` (on line 139) does not make singleton methods private. Use `private_class_method` or `private` inside a `class << self` block instead. def self.split_raw_line(line) line = line.to_s return if line.empty? time = line[11, 26] bracket_index = line.index(']', 39) pidtid = line[39...bracket_index] pid, tid = pidtid.split(':') level_index = bracket_index + 2 level = line[level_index, 5].strip progname_index = level_index + 9 # 5 for the level + 4 for the " -- " message_index = line.index(": ", progname_index) + 2 # Find up to the ": " separator for the message progname = line[progname_index...message_index].strip[0..-2] progname = nil if progname.empty? message = line[message_index..-1] if message[0, 9] == "Q-task_id" q_bracket_index = message.index(']', 11) q_task_id = message[11...q_bracket_index] message = message[q_bracket_index + 3..-1] else q_task_id = nil end fq_method = message[/^MIQ\(([\d\w\:\.\#\_\-]*)\)/, 1] if message && message.start_with?("MIQ(") message.chomp! return time, pid, tid, level, progname, q_task_id, fq_method, message rescue return nil, nil, nil, nil, nil, nil, line endend