lib/request_log_analyzer/request.rb in wvanbergen-request-log-analyzer-1.3.5 vs lib/request_log_analyzer/request.rb in wvanbergen-request-log-analyzer-1.3.6
- old
+ new
@@ -7,110 +7,122 @@
# This class provides several methods to access the data that was parsed from the log files.
# Request#first(field_name) returns the first (only) value corresponding to the given field
# Request#every(field_name) returns all values corresponding to the given field name as array.
class Request
+ def self.inherited(klass)
+ # klass.send(:include, Converters)
+ end
+
module Converters
-
+
+ # Default converter function, which converts the parsed strings to a native Ruby type
+ # using the type indication in the line definition. It will use a custom connverter
+ # method if one is available.
def convert_value(value, capture_definition)
- custom_converter_method = "convert_#{capture_definition[:type]}".to_sym
- if respond_to?(custom_converter_method)
- send(custom_converter_method, value, capture_definition)
- elsif !value.nil?
- case capture_definition[:type]
- when :decimal; value.to_f
- when :float; value.to_f
- when :double; value.to_f
- when :integer; value.to_i
- when :int; value.to_i
- when :symbol; value.to_sym
- else; value.to_s
- end
- else
- nil
- end
+ return capture_definition[:default] if value.nil?
+ custom_converter_method = :"convert_#{capture_definition[:type]}"
+ send(custom_converter_method, value, capture_definition)
end
+ def convert_string(value, capture_definition); value; end
+ def convert_decimal(value, capture_definition); value.to_f; end
+ def convert_float(value, capture_definition); value.to_f; end
+ def convert_decimal(value, capture_definition); value.to_f; end
+ def convert_int(value, capture_definition); value.to_i; end
+ def convert_integer(value, capture_definition); value.to_i; end
+ def convert_sym(value, capture_definition); value.to_sym; end
+ def convert_symbol(value, capture_definition); value.to_sym; end
+
+ # Converts :eval field, which should evaluate to a hash.
def convert_eval(value, capture_definition)
eval(value).inject({}) { |h, (k, v)| h[k.to_sym] = v; h}
rescue SyntaxError
nil
end
- # Slow default method to parse timestamps
+ # Slow default method to parse timestamps.
+ # Reimplement this function in a file format specific Request class
+ # to improve the timestamp parsing speed.
def convert_timestamp(value, capture_definition)
- DateTime.parse(value).strftime('%Y%m%d%H%M%S').to_i unless value.nil?
+ DateTime.parse(value).strftime('%Y%m%d%H%M%S').to_i
end
+ # Converts traffic fields to (whole) bytes based on the given unit.
def convert_traffic(value, capture_definition)
- return nil if value.nil?
case capture_definition[:unit]
+ when nil, :b, :B, :byte then value.to_i
when :GB, :G, :gigabyte then (value.to_f * 1000_000_000).round
when :GiB, :gibibyte then (value.to_f * (2 ** 30)).round
when :MB, :M, :megabyte then (value.to_f * 1000_000).round
when :MiB, :mebibyte then (value.to_f * (2 ** 20)).round
when :KB, :K, :kilobyte, :kB then (value.to_f * 1000).round
when :KiB, :kibibyte then (value.to_f * (2 ** 10)).round
- else value.to_i
+ else raise "Unknown traffic unit"
end
end
+ # Convert duration fields to float, and make sure the values are in seconds.
def convert_duration(value, capture_definition)
- return nil if value.nil?
case capture_definition[:unit]
+ when nil, :sec, :s then value.to_f
when :microsec, :musec then value.to_f / 1000000.0
when :msec, :millisec then value.to_f / 1000.0
- else value.to_f
+ else raise "Unknown duration unit"
end
end
end
-
- include RequestLogAnalyzer::FileFormat::Awareness
+
+ # Install the default converter methods
include Converters
-
- attr_reader :lines
- attr_reader :attributes
+
+ attr_reader :lines, :attributes, :file_format
# Initializes a new Request object.
# It will apply the the provided FileFormat module to this instance.
def initialize(file_format, attributes = {})
- @lines = []
- @attributes = attributes
- register_file_format(file_format)
+ @lines = []
+ @attributes = attributes
+ @file_format = file_format
end
# Creates a new request that was parsed from the log with the given FileFormat. The hashes
# that are passed to this function are added as lines to this request.
def self.create(file_format, *hashes)
request = self.new(file_format)
hashes.flatten.each { |hash| request << hash }
return request
end
- # Adds another line to the request.
- # The line should be provides as a hash of the fields parsed from the line.
+ # Adds another line to the request when it is parsed in the LogParser.
+ #
+ # The line should be provided as a hash with the attributes line_definition, :captures,
+ # :lineno and :source set. This function is called from LogParser.
def add_parsed_line (parsed_line)
value_hash = parsed_line[:line_definition].convert_captured_values(parsed_line[:captures], self)
value_hash[:line_type] = parsed_line[:line_definition].name
value_hash[:lineno] = parsed_line[:lineno]
value_hash[:source] = parsed_line[:source]
add_line_hash(value_hash)
end
+ # Adds another line to the request using a plain hash.
+ #
+ # The line should be provides as a hash of the fields parsed from the line.
def add_line_hash(value_hash)
@lines << value_hash
@attributes = value_hash.merge(@attributes)
end
-
+ # Adds another line to the request. This method switches automatically between
+ # the add_line_hash and add_parsed_line based on the keys of the provided hash.
def <<(hash)
hash[:line_definition] ? add_parsed_line(hash) : add_line_hash(hash)
end
# Checks whether the given line type was parsed from the log file for this request
def has_line_type?(line_type)
return true if @lines.length == 1 && @lines[0][:line_type] == line_type.to_sym
-
@lines.detect { |l| l[:line_type] == line_type.to_sym }
end
alias :=~ :has_line_type?
\ No newline at end of file