Class: RequestLogAnalyzer::Controller
- Inherits:
-
Object
- Object
- RequestLogAnalyzer::Controller
- Defined in:
- lib/request_log_analyzer/controller.rb
Overview
The RequestLogAnalyzer::Controller class creates a LogParser instance for the requested file format, and connect it with sources and aggregators.
Sources are streams or files from which the requests will be parsed. Aggregators will handle every passed request to yield a meaningfull results.
-
Use the build-function to build a controller instance using command line arguments.
-
Use add_aggregator to register a new aggregator
-
Use add_source to register a new aggregator
-
Use the run! method to start the parser and send the requests to the aggregators.
Note that the order of sources can be imported if you have log files than succeed eachother. Requests that span over succeeding files will be parsed correctly if the sources are registered in the correct order. This can be helpful to parse requests from several logrotated log files.
Instance Attribute Summary collapse
-
#aggregators ⇒ Object
readonly
Returns the value of attribute aggregators.
-
#filters ⇒ Object
readonly
Returns the value of attribute filters.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#output ⇒ Object
readonly
Returns the value of attribute output.
-
#source ⇒ Object
readonly
Returns the value of attribute source.
Class Method Summary collapse
-
.build(arguments) ⇒ Object
Builds a RequestLogAnalyzer::Controller given parsed command line arguments <tt>arguments<tt> A CommandLine::Arguments hash containing parsed commandline parameters.
Instance Method Summary collapse
-
#add_aggregator(agg) ⇒ Object
(also: #>>)
Adds an aggregator to the controller.
-
#add_filter(filter, filter_options = {}) ⇒ Object
Adds a request filter to the controller.
-
#aggregate_request(request) ⇒ Object
Push a request to all the aggregators (@aggregators).
-
#filter_request(request) ⇒ Object
Push a request through the entire filterchain (@filters).
-
#handle_progress(message, value = nil) ⇒ Object
Progress function.
-
#handle_source_change(change, filename) ⇒ Object
Source change handler.
-
#initialize(source, options = {}) ⇒ Controller
constructor
Builds a new Controller for the given log file format.
- #install_signal_handlers ⇒ Object
-
#run! ⇒ Object
Runs RequestLogAnalyzer 1.
Constructor Details
#initialize(source, options = {}) ⇒ Controller
Builds a new Controller for the given log file format. format
Logfile format. Defaults to :rails Options are passd on to the LogParser.
-
:aggregator
Aggregator array. -
:database
Database the controller should use. -
:echo
Output debug information. -
:silent
Do not output any warnings. -
:colorize
Colorize output -
:output
All report outputs get << through this output.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/request_log_analyzer/controller.rb', line 113 def initialize(source, = {}) @source = source @options = @aggregators = [] @filters = [] @output = [:output] # Register the request format for this session after checking its validity raise "Invalid file format!" unless @source.file_format.valid? # Install event handlers for wrnings, progress updates and source changes @source.warning = lambda { |type, , lineno| @aggregators.each { |agg| agg.warning(type, , lineno) } } @source.progress = lambda { |, value| handle_progress(, value) } unless [:no_progress] @source.source_changes = lambda { |change, filename| handle_source_change(change, filename) } end |
Instance Attribute Details
#aggregators ⇒ Object (readonly)
Returns the value of attribute aggregators.
20 21 22 |
# File 'lib/request_log_analyzer/controller.rb', line 20 def aggregators @aggregators end |
#filters ⇒ Object (readonly)
Returns the value of attribute filters.
20 21 22 |
# File 'lib/request_log_analyzer/controller.rb', line 20 def filters @filters end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
20 21 22 |
# File 'lib/request_log_analyzer/controller.rb', line 20 def @options end |
#output ⇒ Object (readonly)
Returns the value of attribute output.
20 21 22 |
# File 'lib/request_log_analyzer/controller.rb', line 20 def output @output end |
#source ⇒ Object (readonly)
Returns the value of attribute source.
20 21 22 |
# File 'lib/request_log_analyzer/controller.rb', line 20 def source @source end |
Class Method Details
.build(arguments) ⇒ Object
Builds a RequestLogAnalyzer::Controller given parsed command line arguments arguments<tt> A CommandLine::Arguments hash containing parsed commandline parameters. <rr>report_with
Width of the report. Defaults to 80.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/request_log_analyzer/controller.rb', line 25 def self.build(arguments) = { } # Database command line options [:database] = arguments[:database] if arguments[:database] [:reset_database] = arguments[:reset_database] [:debug] = arguments[:debug] [:dump] = arguments[:dump] [:parse_strategy] = arguments[:parse_strategy] [:no_progress] = arguments[:no_progress] output_class = RequestLogAnalyzer::Output::const_get(arguments[:output]) if arguments[:file] output_file = File.new(arguments[:file], "w+") [:output] = output_class.new(output_file, :width => 80, :color => false, :characters => :ascii) elsif arguments[:mail] output_mail = RequestLogAnalyzer::Mailer.new(arguments[:mail]) [:output] = output_class.new(output_mail, :width => 80, :color => false, :characters => :ascii) else [:output] = output_class.new(STDOUT, :width => arguments[:report_width].to_i, :color => !arguments[:boring], :characters => (arguments[:boring] ? :ascii : :utf)) end # Create the controller with the correct file format file_format = if arguments[:apache_format] RequestLogAnalyzer::FileFormat.load(:apache, arguments[:apache_format]) else RequestLogAnalyzer::FileFormat.load(arguments[:format]) end # register sources if arguments.parameters.length == 1 file = arguments.parameters[0] if file == '-' || file == 'STDIN' .store(:source_files, $stdin) elsif File.exist?(file) .store(:source_files, file) else puts "File not found: #{file}" exit(0) end else .store(:source_files, arguments.parameters) end controller = Controller.new(RequestLogAnalyzer::Source::LogParser.new(file_format, ), ) #controller = Controller.new(RequestLogAnalyzer::Source::DatabaseLoader.new(file_format, options), options) # register filters if arguments[:after] || arguments[:before] = {} [:after] = DateTime.parse(arguments[:after]) [:before] = DateTime.parse(arguments[:before]) if arguments[:before] controller.add_filter(:timespan, ) end arguments[:reject].each do |(field, value)| controller.add_filter(:field, :mode => :reject, :field => field, :value => value) end arguments[:select].each do |(field, value)| controller.add_filter(:field, :mode => :select, :field => field, :value => value) end # register aggregators arguments[:aggregator].each { |agg| controller.add_aggregator(agg.to_sym) } # register the database controller.add_aggregator(:summarizer) if arguments[:aggregator].empty? controller.add_aggregator(:database_inserter) if arguments[:database] && !arguments[:aggregator].include?('database') # register the echo aggregator in debug mode controller.add_aggregator(:echo) if arguments[:debug] file_format.setup_environment(controller) return controller end |
Instance Method Details
#add_aggregator(agg) ⇒ Object Also known as: >>
Adds an aggregator to the controller. The aggregator will be called for every request that is parsed from the provided sources (see add_source)
158 159 160 161 |
# File 'lib/request_log_analyzer/controller.rb', line 158 def add_aggregator(agg) agg = RequestLogAnalyzer::Aggregator.const_get(RequestLogAnalyzer::to_camelcase(agg)) if agg.kind_of?(Symbol) @aggregators << agg.new(@source, @options) end |
#add_filter(filter, filter_options = {}) ⇒ Object
Adds a request filter to the controller.
166 167 168 169 |
# File 'lib/request_log_analyzer/controller.rb', line 166 def add_filter(filter, = {}) filter = RequestLogAnalyzer::Filter.const_get(RequestLogAnalyzer::to_camelcase(filter)) if filter.kind_of?(Symbol) @filters << filter.new(source.file_format, @options.merge()) end |
#aggregate_request(request) ⇒ Object
Push a request to all the aggregators (@aggregators). request
The request to push to the aggregators.
184 185 186 187 188 |
# File 'lib/request_log_analyzer/controller.rb', line 184 def aggregate_request(request) return false unless request @aggregators.each { |agg| agg.aggregate(request) } return true end |
#filter_request(request) ⇒ Object
Push a request through the entire filterchain (@filters). request
The request to filter. Returns the filtered request or nil.
174 175 176 177 178 179 180 |
# File 'lib/request_log_analyzer/controller.rb', line 174 def filter_request(request) @filters.each do |filter| request = filter.filter(request) return nil if request.nil? end return request end |
#handle_progress(message, value = nil) ⇒ Object
Progress function. Expects :started with file, :progress with current line and :finished or :interrupted when done. message
Current state (:started, :finished, :interupted or :progress). value
File or current line.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/request_log_analyzer/controller.rb', line 134 def handle_progress(, value = nil) case when :started @progress_bar = CommandLine::ProgressBar.new(File.basename(value), File.size(value), STDOUT) when :finished @progress_bar.finish @progress_bar = nil when :interrupted if @progress_bar @progress_bar.halt @progress_bar = nil end when :progress @progress_bar.set(value) end end |
#handle_source_change(change, filename) ⇒ Object
Source change handler
152 153 154 |
# File 'lib/request_log_analyzer/controller.rb', line 152 def handle_source_change(change, filename) @aggregators.each { |agg| agg.source_change(change, File.(filename, Dir.pwd)) } end |
#install_signal_handlers ⇒ Object
228 229 230 231 232 233 234 |
# File 'lib/request_log_analyzer/controller.rb', line 228 def install_signal_handlers Signal.trap("INT") do handle_progress(:interrupted) puts "Caught interrupt! Stopping parsing..." @interrupted = true end end |
#run! ⇒ Object
Runs RequestLogAnalyzer
-
Call prepare on every aggregator
-
Generate requests from source object
-
Filter out unwanted requests
-
Call aggregate for remaning requests on every aggregator
-
Call finalize on every aggregator
-
Call report on every aggregator
-
Finalize Source
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/request_log_analyzer/controller.rb', line 198 def run! @aggregators.each { |agg| agg.prepare } install_signal_handlers @source.each_request do |request| break if @interrupted aggregate_request(filter_request(request)) end @aggregators.each { |agg| agg.finalize } @output.header @aggregators.each { |agg| agg.report(@output) } @output. @source.finalize if @output.io.kind_of?(File) puts puts "Report written to: " + File.(@output.io.path) puts "Need an expert to analyze your application?" puts "Mail to [email protected] or visit us at http://railsdoctors.com" puts "Thanks for using request-log-analyzer!" @output.io.close elsif @output.io.kind_of?(RequestLogAnalyzer::Mailer) @output.io.mail end end |