request-log-analyzer 1.3.1 → 1.3.2
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.
- data/bin/request-log-analyzer +1 -0
 - data/lib/request_log_analyzer.rb +1 -1
 - data/lib/request_log_analyzer/controller.rb +6 -6
 - data/lib/request_log_analyzer/source/log_parser.rb +6 -4
 - data/lib/request_log_analyzer/tracker.rb +12 -8
 - data/lib/request_log_analyzer/tracker/duration.rb +6 -4
 - data/request-log-analyzer.gemspec +2 -2
 - data/spec/unit/file_format/apache_format_spec.rb +4 -4
 - metadata +2 -2
 
    
        data/bin/request-log-analyzer
    CHANGED
    
    
    
        data/lib/request_log_analyzer.rb
    CHANGED
    
    | 
         @@ -11,7 +11,7 @@ module RequestLogAnalyzer 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
              # The current version of request-log-analyzer.
         
     | 
| 
       13 
13 
     | 
    
         
             
              # This will be diplayed in output reports etc.  
         
     | 
| 
       14 
     | 
    
         
            -
              VERSION = "1.3. 
     | 
| 
      
 14 
     | 
    
         
            +
              VERSION = "1.3.2"
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
              # Loads constants in the RequestLogAnalyzer namespace using self.load_default_class_file(base, const)
         
     | 
| 
       17 
17 
     | 
    
         
             
              # <tt>const</tt>:: The constant that is not yet loaded in the RequestLogAnalyzer namespace. This should be passed as a string or symbol.
         
     | 
| 
         @@ -35,10 +35,11 @@ module RequestLogAnalyzer 
     | 
|
| 
       35 
35 
     | 
    
         
             
                  # Database command line options
         
     | 
| 
       36 
36 
     | 
    
         
             
                  options[:database]       = arguments[:database] if arguments[:database]
         
     | 
| 
       37 
37 
     | 
    
         
             
                  options[:reset_database] = arguments[:reset_database]
         
     | 
| 
       38 
     | 
    
         
            -
                  
         
     | 
| 
       39 
38 
     | 
    
         
             
                  options[:debug]    = arguments[:debug]
         
     | 
| 
       40 
39 
     | 
    
         
             
                  options[:dump]     = arguments[:dump]
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
                  options[:parse_strategy] = arguments[:parse_strategy]
         
     | 
| 
      
 41 
     | 
    
         
            +
                  options[:no_progress]    = arguments[:no_progress]
         
     | 
| 
      
 42 
     | 
    
         
            +
                  
         
     | 
| 
       42 
43 
     | 
    
         
             
                  output_class = RequestLogAnalyzer::Output::const_get(arguments[:output])
         
     | 
| 
       43 
44 
     | 
    
         
             
                  if arguments[:file]
         
     | 
| 
       44 
45 
     | 
    
         
             
                    output_file = File.new(arguments[:file], "w+")
         
     | 
| 
         @@ -75,10 +76,8 @@ module RequestLogAnalyzer 
     | 
|
| 
       75 
76 
     | 
    
         | 
| 
       76 
77 
     | 
    
         
             
                  controller = Controller.new(RequestLogAnalyzer::Source::LogParser.new(file_format, options), options)
         
     | 
| 
       77 
78 
     | 
    
         
             
                  #controller = Controller.new(RequestLogAnalyzer::Source::DatabaseLoader.new(file_format, options), options)
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                  options[:parse_strategy] = arguments[:parse_strategy]
         
     | 
| 
       80 
79 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
                  # register filters 
     | 
| 
      
 80 
     | 
    
         
            +
                  # register filters
         
     | 
| 
       82 
81 
     | 
    
         
             
                  if arguments[:after] || arguments[:before]
         
     | 
| 
       83 
82 
     | 
    
         
             
                    filter_options = {}
         
     | 
| 
       84 
83 
     | 
    
         
             
                    filter_options[:after]  = DateTime.parse(arguments[:after])  
         
     | 
| 
         @@ -133,8 +132,9 @@ module RequestLogAnalyzer 
     | 
|
| 
       133 
132 
     | 
    
         
             
                  @source.warning = lambda { |type, message, lineno|  @aggregators.each { |agg| agg.warning(type, message, lineno) } } if @source
         
     | 
| 
       134 
133 
     | 
    
         | 
| 
       135 
134 
     | 
    
         
             
                  # Handle progress messagess
         
     | 
| 
       136 
     | 
    
         
            -
                  @source.progress = lambda { |message, value| handle_progress(message, value) } if @source
         
     | 
| 
      
 135 
     | 
    
         
            +
                  @source.progress = lambda { |message, value| handle_progress(message, value) } if @source && !options[:no_progress]
         
     | 
| 
       137 
136 
     | 
    
         | 
| 
      
 137 
     | 
    
         
            +
                  # Handle source change messages
         
     | 
| 
       138 
138 
     | 
    
         
             
                  @source.source_changes = lambda { |change, filename| handle_source_change(change, filename) } if @source
         
     | 
| 
       139 
139 
     | 
    
         
             
                end
         
     | 
| 
       140 
140 
     | 
    
         | 
| 
         @@ -51,7 +51,7 @@ module RequestLogAnalyzer::Source 
     | 
|
| 
       51 
51 
     | 
    
         
             
                def each_request(options = {}, &block) # :yields: :request, request
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
                  case @source_files
         
     | 
| 
       54 
     | 
    
         
            -
                  when IO 
     | 
| 
      
 54 
     | 
    
         
            +
                  when IO
         
     | 
| 
       55 
55 
     | 
    
         
             
                    puts "Parsing from the standard input. Press CTRL+C to finish." # FIXME: not here
         
     | 
| 
       56 
56 
     | 
    
         
             
                    parse_stream(@source_files, options, &block) 
         
     | 
| 
       57 
57 
     | 
    
         
             
                  when String
         
     | 
| 
         @@ -97,6 +97,7 @@ module RequestLogAnalyzer::Source 
     | 
|
| 
       97 
97 
     | 
    
         
             
                # <tt>options</tt>:: A Hash of options that will be pased to parse_io.
         
     | 
| 
       98 
98 
     | 
    
         
             
                def parse_file(file, options = {}, &block)
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
      
 100 
     | 
    
         
            +
                  @progress_handler = @dormant_progress_handler
         
     | 
| 
       100 
101 
     | 
    
         
             
                  @current_source = File.expand_path(file)
         
     | 
| 
       101 
102 
     | 
    
         
             
                  @progress_handler.call(:started, file)                  if @progress_handler
         
     | 
| 
       102 
103 
     | 
    
         
             
                  @source_changes_handler.call(:started, @current_source) if @source_changes_handler
         
     | 
| 
         @@ -110,6 +111,7 @@ module RequestLogAnalyzer::Source 
     | 
|
| 
       110 
111 
     | 
    
         
             
                  @source_changes_handler.call(:finished, @current_source) if @source_changes_handler
         
     | 
| 
       111 
112 
     | 
    
         
             
                  @progress_handler.call(:finished, file)                  if @progress_handler
         
     | 
| 
       112 
113 
     | 
    
         
             
                  @current_source = nil
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @progress_handler = nil
         
     | 
| 
       113 
115 
     | 
    
         
             
                end
         
     | 
| 
       114 
116 
     | 
    
         | 
| 
       115 
117 
     | 
    
         
             
                # Parses an IO stream. It will simply call parse_io. This function does not support progress updates
         
     | 
| 
         @@ -134,8 +136,8 @@ module RequestLogAnalyzer::Source 
     | 
|
| 
       134 
136 
     | 
    
         
             
                # <tt>options</tt>:: A hash of options that can be used by the parser.
         
     | 
| 
       135 
137 
     | 
    
         
             
                def parse_io(io, options = {}, &block) # :yields: request
         
     | 
| 
       136 
138 
     | 
    
         
             
                  @current_lineno = 1
         
     | 
| 
       137 
     | 
    
         
            -
                  io. 
     | 
| 
       138 
     | 
    
         
            -
                    @progress_handler.call(:progress, io.pos) if @progress_handler &&  
     | 
| 
      
 139 
     | 
    
         
            +
                  while line = io.gets
         
     | 
| 
      
 140 
     | 
    
         
            +
                    @progress_handler.call(:progress, io.pos) if @progress_handler && @current_lineno % 127 == 0
         
     | 
| 
       139 
141 
     | 
    
         | 
| 
       140 
142 
     | 
    
         
             
                    if request_data = file_format.parse_line(line) { |wt, message| warn(wt, message) }
         
     | 
| 
       141 
143 
     | 
    
         
             
                      @parsed_lines += 1
         
     | 
| 
         @@ -152,7 +154,7 @@ module RequestLogAnalyzer::Source 
     | 
|
| 
       152 
154 
     | 
    
         
             
                # Add a block to this method to install a progress handler while parsing.
         
     | 
| 
       153 
155 
     | 
    
         
             
                # <tt>proc</tt>:: The proc that will be called to handle progress update messages
         
     | 
| 
       154 
156 
     | 
    
         
             
                def progress=(proc)
         
     | 
| 
       155 
     | 
    
         
            -
                  @ 
     | 
| 
      
 157 
     | 
    
         
            +
                  @dormant_progress_handler = proc
         
     | 
| 
       156 
158 
     | 
    
         
             
                end
         
     | 
| 
       157 
159 
     | 
    
         | 
| 
       158 
160 
     | 
    
         
             
                # Add a block to this method to install a warning handler while parsing,
         
     | 
| 
         @@ -57,16 +57,20 @@ module RequestLogAnalyzer::Tracker 
     | 
|
| 
       57 
57 
     | 
    
         
             
                def should_update?(request)
         
     | 
| 
       58 
58 
     | 
    
         
             
                  return false if options[:line_type] && !request.has_line_type?(options[:line_type])
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                  if options[:if] 
     | 
| 
       61 
     | 
    
         
            -
                     
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                     
     | 
| 
      
 60 
     | 
    
         
            +
                  if options[:if]
         
     | 
| 
      
 61 
     | 
    
         
            +
                    if options[:if].kind_of?(Symbol)
         
     | 
| 
      
 62 
     | 
    
         
            +
                      return false unless request[options[:if]]
         
     | 
| 
      
 63 
     | 
    
         
            +
                    elsif options[:if].respond_to?(:call)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      return false unless options[:if].call(request)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
       64 
66 
     | 
    
         
             
                  end
         
     | 
| 
       65 
67 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
                  if options[:unless] 
     | 
| 
       67 
     | 
    
         
            -
                     
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                     
     | 
| 
      
 68 
     | 
    
         
            +
                  if options[:unless]
         
     | 
| 
      
 69 
     | 
    
         
            +
                    if options[:unless].kind_of?(Symbol)
         
     | 
| 
      
 70 
     | 
    
         
            +
                      return false if request[options[:unless]]
         
     | 
| 
      
 71 
     | 
    
         
            +
                    elsif options[:unless].respond_to?(:call)
         
     | 
| 
      
 72 
     | 
    
         
            +
                      return false if options[:unless].call(request)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
       70 
74 
     | 
    
         
             
                  end
         
     | 
| 
       71 
75 
     | 
    
         | 
| 
       72 
76 
     | 
    
         
             
                  return true
         
     | 
| 
         @@ -28,7 +28,9 @@ module RequestLogAnalyzer::Tracker 
     | 
|
| 
       28 
28 
     | 
    
         
             
                def prepare
         
     | 
| 
       29 
29 
     | 
    
         
             
                  raise "No duration field set up for category tracker #{self.inspect}" unless options[:duration]
         
     | 
| 
       30 
30 
     | 
    
         
             
                  raise "No categorizer set up for duration tracker #{self.inspect}" unless options[:category]
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  @categorizer  = options[:category].respond_to?(:call) ? options[:category] : lambda { |request| request[options[:category]] }
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @durationizer = options[:duration].respond_to?(:call) ? options[:duration] : lambda { |request| request[options[:duration]] }
         
     | 
| 
       32 
34 
     | 
    
         
             
                  @categories = {}
         
     | 
| 
       33 
35 
     | 
    
         
             
                end
         
     | 
| 
       34 
36 
     | 
    
         | 
| 
         @@ -49,15 +51,15 @@ module RequestLogAnalyzer::Tracker 
     | 
|
| 
       49 
51 
     | 
    
         
             
                      raise "Capture mismatch for multiple values in a request"
         
     | 
| 
       50 
52 
     | 
    
         
             
                    end
         
     | 
| 
       51 
53 
     | 
    
         
             
                  else
         
     | 
| 
       52 
     | 
    
         
            -
                    category = options[:category].respond_to?(:call) ? options[:category].call(request) : request[options[:category]]
         
     | 
| 
       53 
     | 
    
         
            -
                    duration = options[:duration].respond_to?(:call) ? options[:duration].call(request) : request[options[:duration]]
         
     | 
| 
      
 54 
     | 
    
         
            +
                    category = @categorizer.call(request)  # options[:category].respond_to?(:call) ? options[:category].call(request) : request[options[:category]]
         
     | 
| 
      
 55 
     | 
    
         
            +
                    duration = @durationizer.call(request) # options[:duration].respond_to?(:call) ? options[:duration].call(request) : request[options[:duration]]
         
     | 
| 
       54 
56 
     | 
    
         | 
| 
       55 
57 
     | 
    
         
             
                    if duration.kind_of?(Float) && category.kind_of?(String)
         
     | 
| 
       56 
58 
     | 
    
         
             
                      @categories[category] ||= {:hits => 0, :cumulative => 0.0, :min => duration, :max => duration }
         
     | 
| 
       57 
59 
     | 
    
         
             
                      @categories[category][:hits] += 1
         
     | 
| 
       58 
60 
     | 
    
         
             
                      @categories[category][:cumulative] += duration
         
     | 
| 
       59 
61 
     | 
    
         
             
                      @categories[category][:min] = duration if duration < @categories[category][:min]
         
     | 
| 
       60 
     | 
    
         
            -
                      @categories[category][:max] = duration if duration > @categories[category][:max] 
     | 
| 
      
 62 
     | 
    
         
            +
                      @categories[category][:max] = duration if duration > @categories[category][:max]
         
     | 
| 
       61 
63 
     | 
    
         
             
                    end
         
     | 
| 
       62 
64 
     | 
    
         
             
                  end
         
     | 
| 
       63 
65 
     | 
    
         
             
                end
         
     | 
| 
         @@ -70,7 +70,7 @@ describe RequestLogAnalyzer::FileFormat::Apache do 
     | 
|
| 
       70 
70 
     | 
    
         
             
                end
         
     | 
| 
       71 
71 
     | 
    
         | 
| 
       72 
72 
     | 
    
         
             
                it "should read the correct values from a valid HTTP/1.0 access log line" do
         
     | 
| 
       73 
     | 
    
         
            -
                  @log_parser.parse_io(@sample_1) do |request|
         
     | 
| 
      
 73 
     | 
    
         
            +
                  @log_parser.parse_io(StringIO.new(@sample_1)) do |request|
         
     | 
| 
       74 
74 
     | 
    
         
             
                    request[:remote_host].should  == '1.129.119.13'
         
     | 
| 
       75 
75 
     | 
    
         
             
                    request[:timestamp].should    == 20090908075409
         
     | 
| 
       76 
76 
     | 
    
         
             
                    request[:http_status].should  == 200
         
     | 
| 
         @@ -82,7 +82,7 @@ describe RequestLogAnalyzer::FileFormat::Apache do 
     | 
|
| 
       82 
82 
     | 
    
         
             
                end
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
       84 
84 
     | 
    
         
             
                it "should read the correct values from a valid 200 access log line" do
         
     | 
| 
       85 
     | 
    
         
            -
                  @log_parser.parse_io(@sample_2) do |request|
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @log_parser.parse_io(StringIO.new(@sample_2)) do |request|
         
     | 
| 
       86 
86 
     | 
    
         
             
                    request[:remote_host].should  == '1.82.235.29'
         
     | 
| 
       87 
87 
     | 
    
         
             
                    request[:timestamp].should    == 20090908075405
         
     | 
| 
       88 
88 
     | 
    
         
             
                    request[:http_status].should  == 200
         
     | 
| 
         @@ -122,7 +122,7 @@ describe RequestLogAnalyzer::FileFormat::Apache do 
     | 
|
| 
       122 
122 
     | 
    
         
             
                end
         
     | 
| 
       123 
123 
     | 
    
         | 
| 
       124 
124 
     | 
    
         
             
                it "should read the correct values from a valid 404 access log line" do
         
     | 
| 
       125 
     | 
    
         
            -
                  @log_parser.parse_io(@sample_1) do |request|
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @log_parser.parse_io(StringIO.new(@sample_1)) do |request|
         
     | 
| 
       126 
126 
     | 
    
         
             
                    request[:remote_host].should  == '69.41.0.45'
         
     | 
| 
       127 
127 
     | 
    
         
             
                    request[:timestamp].should    == 20090902120240
         
     | 
| 
       128 
128 
     | 
    
         
             
                    request[:http_status].should  == 404
         
     | 
| 
         @@ -136,7 +136,7 @@ describe RequestLogAnalyzer::FileFormat::Apache do 
     | 
|
| 
       136 
136 
     | 
    
         
             
                end
         
     | 
| 
       137 
137 
     | 
    
         | 
| 
       138 
138 
     | 
    
         
             
                it "should read the correct values from a valid 200 access log line" do
         
     | 
| 
       139 
     | 
    
         
            -
                  @log_parser.parse_io(@sample_2) do |request|
         
     | 
| 
      
 139 
     | 
    
         
            +
                  @log_parser.parse_io(StringIO.new(@sample_2)) do |request|
         
     | 
| 
       140 
140 
     | 
    
         
             
                    request[:remote_host].should  == '10.0.1.1'
         
     | 
| 
       141 
141 
     | 
    
         
             
                    request[:timestamp].should    == 20090902050833
         
     | 
| 
       142 
142 
     | 
    
         
             
                    request[:http_status].should  == 200
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: request-log-analyzer
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1.3. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.3.2
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors: 
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Willem van Bergen
         
     | 
| 
         @@ -10,7 +10,7 @@ autorequire: 
     | 
|
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
            date: 2009-09- 
     | 
| 
      
 13 
     | 
    
         
            +
            date: 2009-09-13 00:00:00 +02:00
         
     | 
| 
       14 
14 
     | 
    
         
             
            default_executable: request-log-analyzer
         
     | 
| 
       15 
15 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       16 
16 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     |