wvanbergen-request-log-analyzer 1.0.0 → 1.0.1
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/DESIGN +14 -0
- data/HACKING +7 -0
- data/README.textile +9 -98
- data/Rakefile +2 -2
- data/bin/request-log-analyzer +1 -1
- data/lib/cli/bashcolorizer.rb +60 -0
- data/lib/cli/command_line_arguments.rb +301 -0
- data/lib/cli/progressbar.rb +236 -0
- data/lib/request_log_analyzer/aggregator/base.rb +51 -0
- data/lib/request_log_analyzer/aggregator/database.rb +97 -0
- data/lib/request_log_analyzer/aggregator/echo.rb +25 -0
- data/lib/request_log_analyzer/aggregator/summarizer.rb +116 -0
- data/lib/request_log_analyzer/controller.rb +206 -0
- data/lib/request_log_analyzer/file_format/merb.rb +33 -0
- data/lib/request_log_analyzer/file_format/rails.rb +119 -0
- data/lib/request_log_analyzer/file_format.rb +77 -0
- data/lib/request_log_analyzer/filter/base.rb +29 -0
- data/lib/request_log_analyzer/filter/field.rb +36 -0
- data/lib/request_log_analyzer/filter/timespan.rb +32 -0
- data/lib/request_log_analyzer/line_definition.rb +159 -0
- data/lib/request_log_analyzer/log_parser.rb +183 -0
- data/lib/request_log_analyzer/log_processor.rb +121 -0
- data/lib/request_log_analyzer/request.rb +115 -0
- data/lib/request_log_analyzer/source/base.rb +42 -0
- data/lib/request_log_analyzer/source/log_file.rb +180 -0
- data/lib/request_log_analyzer/tracker/base.rb +54 -0
- data/lib/request_log_analyzer/tracker/category.rb +71 -0
- data/lib/request_log_analyzer/tracker/duration.rb +81 -0
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +80 -0
- data/lib/request_log_analyzer/tracker/timespan.rb +54 -0
- data/spec/file_format_spec.rb +78 -0
- data/spec/file_formats/spec_format.rb +26 -0
- data/spec/filter_spec.rb +137 -0
- data/spec/log_processor_spec.rb +57 -0
- data/tasks/rspec.rake +6 -0
- metadata +53 -55
- data/TODO +0 -58
- data/bin/request-log-database +0 -81
- data/lib/base/log_parser.rb +0 -78
- data/lib/base/record_inserter.rb +0 -139
- data/lib/command_line/arguments.rb +0 -129
- data/lib/command_line/flag.rb +0 -51
- data/lib/merb_analyzer/log_parser.rb +0 -26
- data/lib/rails_analyzer/log_parser.rb +0 -35
- data/lib/rails_analyzer/record_inserter.rb +0 -39
- data/tasks/test.rake +0 -8
- data/test/log_fragments/fragment_1.log +0 -59
- data/test/log_fragments/fragment_2.log +0 -5
- data/test/log_fragments/fragment_3.log +0 -12
- data/test/log_fragments/fragment_4.log +0 -10
- data/test/log_fragments/fragment_5.log +0 -24
- data/test/log_fragments/merb_1.log +0 -84
- data/test/merb_log_parser_test.rb +0 -39
- data/test/rails_log_parser_test.rb +0 -94
- data/test/record_inserter_test.rb +0 -45
data/lib/base/record_inserter.rb
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sqlite3'
|
3
|
-
|
4
|
-
module Base
|
5
|
-
|
6
|
-
# Set of functions that can be used to easily log requests into a SQLite3 Database.
|
7
|
-
class RecordInserter
|
8
|
-
|
9
|
-
attr_reader :database
|
10
|
-
attr_reader :current_request
|
11
|
-
attr_reader :warning_count
|
12
|
-
|
13
|
-
# Initializer
|
14
|
-
# <tt>db_file</tt> The file which will be used for the SQLite3 Database storage.
|
15
|
-
def initialize(db_file, options = {})
|
16
|
-
@database = SQLite3::Database.new(db_file)
|
17
|
-
@insert_statements = nil
|
18
|
-
@warning_count = 0
|
19
|
-
create_tables_if_needed!
|
20
|
-
|
21
|
-
self.initialize_hook(options) if self.respond_to?(:initialize_hook)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Calculate the database durations of the requests currenty in the database.
|
25
|
-
# Used if a logfile does contain any database durations.
|
26
|
-
def calculate_db_durations!
|
27
|
-
@database.execute('UPDATE "completed_queries" SET "database" = "duration" - "rendering" WHERE "database" IS NULL OR "database" = 0.0')
|
28
|
-
end
|
29
|
-
|
30
|
-
# Insert a batch of loglines into the database.
|
31
|
-
# Function prepares insert statements, yeilds and then closes and commits.
|
32
|
-
def insert_batch(&block)
|
33
|
-
@database.transaction
|
34
|
-
prepare_statements!
|
35
|
-
block.call(self)
|
36
|
-
close_prepared_statements!
|
37
|
-
@database.commit
|
38
|
-
rescue Exception => e
|
39
|
-
puts e.message
|
40
|
-
@database.rollback
|
41
|
-
end
|
42
|
-
|
43
|
-
def insert_warning(line, warning)
|
44
|
-
@database.execute("INSERT INTO parse_warnings (line, warning) VALUES (:line, :warning)", :line => line, :warning => warning)
|
45
|
-
@warning_count += 1
|
46
|
-
end
|
47
|
-
|
48
|
-
# Insert a request into the database.
|
49
|
-
# def insert(request, close_statements = false)
|
50
|
-
# raise 'No insert defined for this log file type'
|
51
|
-
# end
|
52
|
-
|
53
|
-
# Insert a batch of files into the database.
|
54
|
-
# <tt>db_file</tt> The filename of the database file to use.
|
55
|
-
# Returns the created database.
|
56
|
-
def self.insert_batch_into(db_file, options = {}, &block)
|
57
|
-
db = self.new(db_file)
|
58
|
-
db.insert_batch(&block)
|
59
|
-
return db
|
60
|
-
end
|
61
|
-
|
62
|
-
def count(type)
|
63
|
-
@database.get_first_value("SELECT COUNT(*) FROM \"#{type}_requests\"").to_i
|
64
|
-
end
|
65
|
-
|
66
|
-
protected
|
67
|
-
|
68
|
-
# Prepare insert statements.
|
69
|
-
def prepare_statements!
|
70
|
-
@insert_statements = {
|
71
|
-
:started => @database.prepare("
|
72
|
-
INSERT INTO started_requests ( line, timestamp, ip, method, controller, action)
|
73
|
-
VALUES (:line, :timestamp, :ip, :method, :controller, :action)"),
|
74
|
-
|
75
|
-
:failed => @database.prepare("
|
76
|
-
INSERT INTO failed_requests ( line, exception_string, stack_trace, error)
|
77
|
-
VALUES (:line, :exception_string, :stack_trace, :error)"),
|
78
|
-
|
79
|
-
:completed => @database.prepare("
|
80
|
-
INSERT INTO completed_requests ( line, url, status, duration, rendering_time, database_time)
|
81
|
-
VALUES (:line, :url, :status, :duration, :rendering, :db)")
|
82
|
-
}
|
83
|
-
end
|
84
|
-
|
85
|
-
# Close all prepared statments
|
86
|
-
def close_prepared_statements!
|
87
|
-
@insert_statements.each { |key, stmt| stmt.close }
|
88
|
-
end
|
89
|
-
|
90
|
-
# Create the needed database tables if they don't exist.
|
91
|
-
def create_tables_if_needed!
|
92
|
-
|
93
|
-
@database.execute("
|
94
|
-
CREATE TABLE IF NOT EXISTS started_requests (
|
95
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
96
|
-
line INTEGER NOT NULL,
|
97
|
-
timestamp DATETIME NOT NULL,
|
98
|
-
controller VARCHAR(255) NOT NULL,
|
99
|
-
action VARCHAR(255) NOT NULL,
|
100
|
-
method VARCHAR(6) NOT NULL,
|
101
|
-
ip VARCHAR(6) NOT NULL
|
102
|
-
)
|
103
|
-
");
|
104
|
-
|
105
|
-
@database.execute("
|
106
|
-
CREATE TABLE IF NOT EXISTS failed_requests (
|
107
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
108
|
-
line INTEGER NOT NULL,
|
109
|
-
started_request_id INTEGER,
|
110
|
-
error VARCHAR(255),
|
111
|
-
exception_string VARCHAR(255),
|
112
|
-
stack_trace TEXT
|
113
|
-
)
|
114
|
-
");
|
115
|
-
|
116
|
-
@database.execute("
|
117
|
-
CREATE TABLE IF NOT EXISTS completed_requests (
|
118
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
119
|
-
line INTEGER NOT NULL,
|
120
|
-
started_request_id INTEGER,
|
121
|
-
url VARCHAR(255) NOT NULL,
|
122
|
-
hashed_url VARCHAR(255),
|
123
|
-
status INTEGER NOT NULL,
|
124
|
-
duration FLOAT,
|
125
|
-
rendering_time FLOAT,
|
126
|
-
database_time FLOAT
|
127
|
-
)
|
128
|
-
");
|
129
|
-
|
130
|
-
@database.execute("CREATE TABLE IF NOT EXISTS parse_warnings (
|
131
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
132
|
-
line INTEGER NOT NULL,
|
133
|
-
warning VARCHAR(255) NOT NULL
|
134
|
-
)
|
135
|
-
");
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
end
|
@@ -1,129 +0,0 @@
|
|
1
|
-
require "#{File.dirname(__FILE__)}/flag"
|
2
|
-
require "#{File.dirname(__FILE__)}/exceptions"
|
3
|
-
|
4
|
-
# Module used to parse commandline arguments
|
5
|
-
module CommandLine
|
6
|
-
|
7
|
-
# Parse argument lists and return an argument object containing all set flags and switches.
|
8
|
-
class Arguments
|
9
|
-
|
10
|
-
FLAG_REGEXP = /^--?[A-z0-9]/
|
11
|
-
|
12
|
-
attr_reader :flag_definitions
|
13
|
-
|
14
|
-
attr_reader :flags
|
15
|
-
attr_reader :files
|
16
|
-
attr_reader :command
|
17
|
-
|
18
|
-
attr_accessor :required_files
|
19
|
-
|
20
|
-
# Initializer.
|
21
|
-
# <tt>arguments</tt> The arguments which are going to be parsed (defaults to $*).
|
22
|
-
def initialize(arguments = $*, &block)
|
23
|
-
@arguments = arguments
|
24
|
-
@flag_definitions = {}
|
25
|
-
@begins_with_command = false
|
26
|
-
end
|
27
|
-
|
28
|
-
# Parse a list of arguments. Intatiates a Argument object with the given arguments and yeilds
|
29
|
-
# it so that flags and switches can be set by the application.
|
30
|
-
# <tt>arguments</tt> The arguments which are going to be parsed (defaults to $*).
|
31
|
-
# Returns the arguments object.parse!
|
32
|
-
def self.parse(arguments = $*, &block)
|
33
|
-
cla = Arguments.new(arguments)
|
34
|
-
yield(cla)
|
35
|
-
return cla.parse!
|
36
|
-
end
|
37
|
-
|
38
|
-
# Handle argument switches for the application
|
39
|
-
# <tt>switch</tt> A switch symbol like :fast
|
40
|
-
# <tt>switch_alias</tt> An short alias for the same switch (:f).
|
41
|
-
def switch(switch, switch_alias = nil)
|
42
|
-
return self.flag(switch, :alias => switch_alias, :expects => nil)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Handle argument flags for the application
|
46
|
-
# <tt>flag</tt> A flag symbol like :fast
|
47
|
-
# Options
|
48
|
-
# * <tt>:expects</tt> Expects a value after the flag
|
49
|
-
def flag(flag, options)
|
50
|
-
options[:expects] = String unless options.has_key?(:expects)
|
51
|
-
argument = Flag.new(flag, options)
|
52
|
-
@flag_definitions[argument.to_argument] = argument
|
53
|
-
@flag_definitions[argument.to_alias] = argument if argument.has_alias?
|
54
|
-
return argument
|
55
|
-
end
|
56
|
-
|
57
|
-
# If called argument list must begin with a command.
|
58
|
-
# <tt>begins_w_command</tt> Defaults to true.
|
59
|
-
def begins_with_command!(begins_w_command=true)
|
60
|
-
@begins_with_command = begins_w_command
|
61
|
-
end
|
62
|
-
|
63
|
-
# Unknown flags will be silently ignored.
|
64
|
-
# <tt>ignore</tt> Defaults to true.
|
65
|
-
def ignore_unknown_flags!(ignore = true)
|
66
|
-
@ignore_unknown_flags = ignore
|
67
|
-
end
|
68
|
-
|
69
|
-
def [](name)
|
70
|
-
return flags[name.to_s.gsub(/_/, '-').to_sym]
|
71
|
-
end
|
72
|
-
|
73
|
-
# Parse the flags and switches set by the application.
|
74
|
-
# Returns an arguments object containing the flags and switches found in the commandline.
|
75
|
-
def parse!
|
76
|
-
@flags = {}
|
77
|
-
@files = []
|
78
|
-
|
79
|
-
i = 0
|
80
|
-
while @arguments.length > i do
|
81
|
-
arg = @arguments[i]
|
82
|
-
if FLAG_REGEXP =~ arg
|
83
|
-
if @flag_definitions.has_key?(arg)
|
84
|
-
flag = @flag_definitions[arg]
|
85
|
-
if flag.expects_argument?
|
86
|
-
|
87
|
-
if @arguments.length > (i + 1) && @arguments[i + 1]
|
88
|
-
@flags[flag.name] = @arguments[i + 1]
|
89
|
-
i += 1
|
90
|
-
else
|
91
|
-
raise CommandLine::FlagExpectsArgument.new(arg)
|
92
|
-
end
|
93
|
-
|
94
|
-
else
|
95
|
-
@flags[flag.name] = true
|
96
|
-
end
|
97
|
-
else
|
98
|
-
raise CommandLine::UnknownFlag.new(arg) unless @ignore_unknown_flags
|
99
|
-
end
|
100
|
-
else
|
101
|
-
if @begins_with_command && @command.nil?
|
102
|
-
@command = arg
|
103
|
-
else
|
104
|
-
@files << arg
|
105
|
-
end
|
106
|
-
end
|
107
|
-
i += 1
|
108
|
-
end
|
109
|
-
|
110
|
-
check_parsed_arguments!
|
111
|
-
|
112
|
-
return self
|
113
|
-
end
|
114
|
-
|
115
|
-
# Check if the parsed arguments meet their requirements.
|
116
|
-
# Raises CommandLineexception on error.
|
117
|
-
def check_parsed_arguments!
|
118
|
-
if @begins_with_command && @command.nil?
|
119
|
-
raise CommandLine::CommandMissing.new
|
120
|
-
end
|
121
|
-
|
122
|
-
if @required_files && @files.length < @required_files
|
123
|
-
raise CommandLine::FileMissing.new("You need at least #{@required_files} files")
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
data/lib/command_line/flag.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
module CommandLine
|
2
|
-
|
3
|
-
# Argument flag handling.
|
4
|
-
class Flag
|
5
|
-
|
6
|
-
attr_reader :name
|
7
|
-
attr_reader :alias
|
8
|
-
attr_reader :argument
|
9
|
-
|
10
|
-
# Initialize new Flag
|
11
|
-
# <tt>name</tt> The name of the flag
|
12
|
-
# <tt>definition</tt> The definition of the flag.
|
13
|
-
def initialize(name, definition)
|
14
|
-
@name = name.to_s.gsub(/_/, '-').to_sym
|
15
|
-
@alias = definition[:alias].to_sym if definition[:alias]
|
16
|
-
@required = definition.has_key?(:required) && definition[:required] == true
|
17
|
-
@argument = definition[:expects] if definition[:expects]
|
18
|
-
end
|
19
|
-
|
20
|
-
# Argument representation of the flag (--fast)
|
21
|
-
def to_argument
|
22
|
-
"--#{@name}"
|
23
|
-
end
|
24
|
-
|
25
|
-
# Argument alias representation of the flag (-f)
|
26
|
-
def to_alias
|
27
|
-
"-#{@alias}"
|
28
|
-
end
|
29
|
-
|
30
|
-
# Check if flag has an alias
|
31
|
-
def has_alias?
|
32
|
-
!@alias.nil?
|
33
|
-
end
|
34
|
-
|
35
|
-
# Check if flag is optional
|
36
|
-
def optional?
|
37
|
-
!@required
|
38
|
-
end
|
39
|
-
|
40
|
-
# Check if flag is required
|
41
|
-
def required?
|
42
|
-
@required
|
43
|
-
end
|
44
|
-
|
45
|
-
# Check if flag expects an argument (Are you talking to me?)
|
46
|
-
def expects_argument?
|
47
|
-
!@argument.nil?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module MerbAnalyzer
|
2
|
-
|
3
|
-
class LogParser < Base::LogParser
|
4
|
-
LOG_LINES = {
|
5
|
-
# ~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
6
|
-
:started => {
|
7
|
-
:teaser => /Started/,
|
8
|
-
:regexp => /Started request handling\:\ (.+)/,
|
9
|
-
:params => [{:timestamp => :timestamp}]
|
10
|
-
},
|
11
|
-
# ~ Params: {"action"=>"create", "controller"=>"session"}
|
12
|
-
# ~ Params: {"_method"=>"delete", "authenticity_token"=>"[FILTERED]", "action"=>"d}
|
13
|
-
:params => {
|
14
|
-
:teaser => /Params/,
|
15
|
-
:regexp => /Params\:\ \{(.+)\}/,
|
16
|
-
:params => [{:raw_hash => :string}]
|
17
|
-
},
|
18
|
-
# ~ {:dispatch_time=>0.006117, :after_filters_time=>6.1e-05, :before_filters_time=>0.000712, :action_time=>0.005833}
|
19
|
-
:completed => {
|
20
|
-
:teaser => /\{:dispatch_time/,
|
21
|
-
:regexp => /\{\:dispatch_time=>(.+), (?:\:after_filters_time=>(.+), )?(?:\:before_filters_time=>(.+), )?\:action_time=>(.+)\}/,
|
22
|
-
:params => [ {:dispatch_time => :sec}, {:after_filters_time => :sec}, {:before_filters_time => :sec}, {:action_time => :sec} ]
|
23
|
-
}
|
24
|
-
}
|
25
|
-
end
|
26
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module RailsAnalyzer
|
2
|
-
|
3
|
-
class LogParser < Base::LogParser
|
4
|
-
|
5
|
-
# Completed in 0.21665 (4 reqs/sec) | Rendering: 0.00926 (4%) | DB: 0.00000 (0%) | 200 OK [http://demo.nu/employees]
|
6
|
-
RAILS_21_COMPLETED = /Completed in (\d+\.\d{5}) \(\d+ reqs\/sec\) (?:\| Rendering: (\d+\.\d{5}) \(\d+\%\) )?(?:\| DB: (\d+\.\d{5}) \(\d+\%\) )?\| (\d\d\d).+\[(http.+)\]/
|
7
|
-
|
8
|
-
# Completed in 614ms (View: 120, DB: 31) | 200 OK [http://floorplanner.local/demo]
|
9
|
-
RAILS_22_COMPLETED = /Completed in (\d+)ms \((?:View: (\d+), )?DB: (\d+)\) \| (\d\d\d).+\[(http.+)\]/
|
10
|
-
|
11
|
-
|
12
|
-
LOG_LINES = {
|
13
|
-
# Processing EmployeeController#index (for 123.123.123.123 at 2008-07-13 06:00:00) [GET]
|
14
|
-
:started => {
|
15
|
-
:teaser => /Processing/,
|
16
|
-
:regexp => /Processing ((?:\w+::)?\w+)#(\w+)(?: to (\w+))? \(for (\d+\.\d+\.\d+\.\d+) at (\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)\) \[([A-Z]+)\]/,
|
17
|
-
:params => [{:controller => :string}, {:action => :string}, {:format => :string}, {:ip => :string}, {:timestamp => :timestamp}, {:method => :string}]
|
18
|
-
},
|
19
|
-
# RuntimeError (Cannot destroy employee): /app/models/employee.rb:198:in `before_destroy'
|
20
|
-
:failed => {
|
21
|
-
:teaser => /Error/,
|
22
|
-
:regexp => /(\w+)(?:Error|Invalid) \((.*)\)\:(.*)/,
|
23
|
-
:params => [{:error => :string}, {:exception_string => :string}, {:stack_trace => :string}]
|
24
|
-
},
|
25
|
-
|
26
|
-
:completed => {
|
27
|
-
:teaser => /Completed in /,
|
28
|
-
:regexp => Regexp.new("(?:#{RAILS_21_COMPLETED}|#{RAILS_22_COMPLETED})"),
|
29
|
-
:params => [{:duration => :sec}, {:rendering => :sec}, {:db => :sec}, {:status => :int}, {:url => :string}, # 2.1 variant
|
30
|
-
{:duration => :msec}, {:rendering => :msec}, {:db => :msec}, {:status => :int}, {:url => :string}] # 2.2 variant
|
31
|
-
|
32
|
-
}
|
33
|
-
}
|
34
|
-
end
|
35
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sqlite3'
|
3
|
-
|
4
|
-
module RailsAnalyzer
|
5
|
-
|
6
|
-
# Set of functions that can be used to easily log requests into a SQLite3 Database.
|
7
|
-
class RecordInserter < Base::RecordInserter
|
8
|
-
|
9
|
-
# Insert a request into the database.
|
10
|
-
# <tt>request</tt> The request to insert.
|
11
|
-
# <tt>close_statements</tt> Close prepared statements (default false)
|
12
|
-
def insert(request, close_statements = false)
|
13
|
-
unless @insert_statements
|
14
|
-
prepare_statements!
|
15
|
-
close_statements = true
|
16
|
-
end
|
17
|
-
|
18
|
-
if request[:type] && @insert_statements.has_key?(request[:type])
|
19
|
-
if request[:type] == :started
|
20
|
-
insert_warning(request[:line], "Unclosed request encountered on line #{request[:line]} (request started on line #{@current_request})") unless @current_request.nil?
|
21
|
-
@current_request = request[:line]
|
22
|
-
elsif [:failed, :completed].include?(request[:type])
|
23
|
-
@current_request = nil
|
24
|
-
end
|
25
|
-
|
26
|
-
begin
|
27
|
-
@insert_statements[request.delete(:type)].execute(request)
|
28
|
-
rescue SQLite3::Exception => e
|
29
|
-
insert_warning(request[:line], "Could not save log line to database: " + e.message.to_s)
|
30
|
-
end
|
31
|
-
else
|
32
|
-
insert_warning(request[:line], "Ignored unknown statement type")
|
33
|
-
end
|
34
|
-
|
35
|
-
close_prepared_statements! if close_statements
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
data/tasks/test.rake
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
Processing DashboardController#index (for 130.89.162.199 at 2008-08-14 21:16:25) [GET]
|
2
|
-
Session ID: BAh7CToMcmVmZXJlciIbL3ByaXNjaWxsYS9wZW9wbGUvMjM1MCIKZmxhc2hJ
|
3
|
-
QzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVz
|
4
|
-
ZWR7ADoNbGFuZ3VhZ2VvOhNMb2NhbGU6Ok9iamVjdBI6CUB3aW4wOg1AY291
|
5
|
-
bnRyeSIHTkw6CkBoYXNoaf3L2Js6DkBvcmlnX3N0ciIKbmwtTkw6DUBpc28z
|
6
|
-
MDY2MDoNQGNoYXJzZXQiClVURi04Og5AbGFuZ3VhZ2UiB25sOg5AbW9kaWZp
|
7
|
-
ZXIwOgtAcG9zaXgiCm5sX05MOg1AZ2VuZXJhbCIKbmxfTkw6DUB2YXJpYW50
|
8
|
-
MDoOQGZhbGxiYWNrMDoMQHNjcmlwdDA6DnBlcnNvbl9pZGkCMgc=--7918aed37151c13360cd370c37b541f136146fbd
|
9
|
-
Parameters: {"action"=>"index", "controller"=>"dashboard"}
|
10
|
-
Set language to: nl_NL
|
11
|
-
Rendering template within layouts/priscilla
|
12
|
-
Rendering dashboard/index
|
13
|
-
Completed in 0.22699 (4 reqs/sec) | Rendering: 0.02667 (11%) | DB: 0.03057 (13%) | 200 OK [https://www.example.com/]
|
14
|
-
|
15
|
-
|
16
|
-
Processing PeopleController#index (for 130.89.162.199 at 2008-08-14 21:16:30) [GET]
|
17
|
-
Session ID: BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
|
18
|
-
SGFzaHsABjoKQHVzZWR7ADoMcmVmZXJlciIQL3ByaXNjaWxsYS86DnBlcnNv
|
19
|
-
bl9pZGkCMgc6DWxhbmd1YWdlbzoTTG9jYWxlOjpPYmplY3QSOg1AY291bnRy
|
20
|
-
eSIHTkw6CUB3aW4wOg5Ab3JpZ19zdHIiCm5sLU5MOgpAaGFzaGn9y9ibOg5A
|
21
|
-
bGFuZ3VhZ2UiB25sOg1AY2hhcnNldCIKVVRGLTg6DUBpc28zMDY2MDoOQG1v
|
22
|
-
ZGlmaWVyMDoLQHBvc2l4IgpubF9OTDoNQHZhcmlhbnQwOg1AZ2VuZXJhbCIK
|
23
|
-
bmxfTkw6DEBzY3JpcHQwOg5AZmFsbGJhY2sw--48cbe3788ef27f6005f8e999610a42af6e90ffb3
|
24
|
-
Parameters: {"commit"=>"Zoek", "action"=>"index", "q"=>"gaby", "controller"=>"people"}
|
25
|
-
Set language to: nl_NL
|
26
|
-
Redirected to https://www.example.com/people/2545
|
27
|
-
Completed in 0.04759 (21 reqs/sec) | DB: 0.03719 (78%) | 302 Found [https://www.example.com/people?q=gaby&commit=Zoek]
|
28
|
-
|
29
|
-
|
30
|
-
Processing PeopleController#show (for 130.89.162.199 at 2008-08-14 21:16:30) [GET]
|
31
|
-
Session ID: BAh7CToMcmVmZXJlciIpL3ByaXNjaWxsYS9wZW9wbGU/cT1nYWJ5JmNvbW1p
|
32
|
-
dD1ab2VrIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxh
|
33
|
-
c2hIYXNoewAGOgpAdXNlZHsAOg1sYW5ndWFnZW86E0xvY2FsZTo6T2JqZWN0
|
34
|
-
EjoJQHdpbjA6DUBjb3VudHJ5IgdOTDoKQGhhc2hp/cvYmzoOQG9yaWdfc3Ry
|
35
|
-
IgpubC1OTDoNQGlzbzMwNjYwOg1AY2hhcnNldCIKVVRGLTg6DkBsYW5ndWFn
|
36
|
-
ZSIHbmw6DkBtb2RpZmllcjA6C0Bwb3NpeCIKbmxfTkw6DUBnZW5lcmFsIgpu
|
37
|
-
bF9OTDoNQHZhcmlhbnQwOg5AZmFsbGJhY2swOgxAc2NyaXB0MDoOcGVyc29u
|
38
|
-
X2lkaQIyBw==--3ad1948559448522a49d289a2a89dc7ccbe8847a
|
39
|
-
Parameters: {"action"=>"show", "id"=>"2545", "controller"=>"people"}
|
40
|
-
Set language to: nl_NL
|
41
|
-
Rendering template within layouts/priscilla
|
42
|
-
Rendering people/show
|
43
|
-
person: Gaby Somers, study_year: 2008/2009
|
44
|
-
Completed in 0.29077 (3 reqs/sec) | Rendering: 0.24187 (83%) | DB: 0.04030 (13%) | 200 OK [https://www.example.com/people/2545]
|
45
|
-
|
46
|
-
|
47
|
-
Processing PeopleController#picture (for 130.89.162.199 at 2008-08-14 21:16:35) [GET]
|
48
|
-
Session ID: BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo
|
49
|
-
SGFzaHsABjoKQHVzZWR7ADoMcmVmZXJlciIbL3ByaXNjaWxsYS9wZW9wbGUv
|
50
|
-
MjU0NToOcGVyc29uX2lkaQIyBzoNbGFuZ3VhZ2VvOhNMb2NhbGU6Ok9iamVj
|
51
|
-
dBI6DUBjb3VudHJ5IgdOTDoJQHdpbjA6DkBvcmlnX3N0ciIKbmwtTkw6CkBo
|
52
|
-
YXNoaf3L2Js6DkBsYW5ndWFnZSIHbmw6DUBjaGFyc2V0IgpVVEYtODoNQGlz
|
53
|
-
bzMwNjYwOg5AbW9kaWZpZXIwOgtAcG9zaXgiCm5sX05MOg1AdmFyaWFudDA6
|
54
|
-
DUBnZW5lcmFsIgpubF9OTDoMQHNjcmlwdDA6DkBmYWxsYmFjazA=--797a33f280a482647111397d138d0918f2658167
|
55
|
-
Parameters: {"action"=>"picture", "id"=>"2545", "controller"=>"people"}
|
56
|
-
Set language to: nl_NL
|
57
|
-
Rendering template within layouts/priscilla
|
58
|
-
Rendering people/picture
|
59
|
-
Completed in 0.05383 (18 reqs/sec) | Rendering: 0.04622 (85%) | DB: 0.00206 (3%) | 200 OK [https://www.example.com/people/2545/picture]
|
@@ -1,5 +0,0 @@
|
|
1
|
-
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Processing EmployeeController#index (for 10.1.1.33 at 2008-07-13 06:25:58) [GET]
|
2
|
-
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Session ID: bd1810833653be11c38ad1e5675635bd
|
3
|
-
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Parameters: {"format"=>"xml", "action"=>"index}
|
4
|
-
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Rendering employees
|
5
|
-
Jul 13 06:25:58 10.1.1.32 app_p [1957]: Completed in 0.21665 (4 reqs/sec) | Rendering: 0.00926 (4%) | DB: 0.00000 (0%) | 200 OK [http://example.com/employee.xml]
|
@@ -1,12 +0,0 @@
|
|
1
|
-
Processing PageController#demo (for 127.0.0.1 at 2008-12-10 16:28:09) [GET]
|
2
|
-
Parameters: {"action"=>"demo", "controller"=>"page"}
|
3
|
-
Logging in from session data...
|
4
|
-
Logged in as willem@depillem.com
|
5
|
-
Using locale: en-US, http-accept: ["en-US"], session: , det browser: en-US, det domain:
|
6
|
-
Rendering template within layouts/demo
|
7
|
-
Rendering page/demo
|
8
|
-
Rendered shared/_analytics (0.2ms)
|
9
|
-
Rendered layouts/_actions (0.6ms)
|
10
|
-
Rendered layouts/_menu (2.2ms)
|
11
|
-
Rendered layouts/_tabbar (0.5ms)
|
12
|
-
Completed in 614ms (View: 120, DB: 31) | 200 OK [http://floorplanner.local/demo]
|
@@ -1,10 +0,0 @@
|
|
1
|
-
Processing CachedController#cached (for 1.1.1.1 at 2008-12-24 07:36:53) [GET]
|
2
|
-
Parameters: {"action"=>"cached", "controller"=>"cached"}
|
3
|
-
Logging in from session data...
|
4
|
-
Logging in using cookie...
|
5
|
-
Using locale: zh-Hans, http-accept: ["zh-CN", "zh-HK", "zh-TW", "en-US"], session: , det browser: zh-Hans, det domain: , user pref locale:
|
6
|
-
Referer: http://www.example.com/referer
|
7
|
-
Cached fragment hit: views/zh-Hans-www-cached-cached-all-CN--- (0.0ms)
|
8
|
-
Filter chain halted as [#<ActionController::Caching::Actions::ActionCacheFilter:0x2a999ad620 @check=nil, @options={:store_options=>{}, :layout=>nil, :cache_path=>#<Proc:0x0000002a999b8890@/app/controllers/cached_controller.rb:8>}>] rendered_or_redirected.
|
9
|
-
Filter chain halted as [#<ActionController::Filters::AroundFilter:0x2a999ad120 @identifier=nil, @kind=:filter, @options={:only=>#<Set: {"cached"}>, :if=>:not_logged_in?, :unless=>nil}, @method=#<ActionController::Caching::Actions::ActionCacheFilter:0x2a999ad620 @check=nil, @options={:store_options=>{}, :layout=>nil, :cache_path=>#<Proc:0x0000002a999b8890@/app/controllers/cached_controller.rb:8>}>>] did_not_yield.
|
10
|
-
Completed in 3ms (View: 0, DB: 0) | 200 OK [http://www.example.com/cached/cached/]
|
@@ -1,24 +0,0 @@
|
|
1
|
-
Processing AccountController#dashboard (for 1.1.1.1 at 2008-12-24 07:36:49) [GET]
|
2
|
-
Parameters: {"action"=>"dashboard", "controller"=>"account", "first_use"=>"true"}
|
3
|
-
Logging in from session data...
|
4
|
-
|
5
|
-
|
6
|
-
Processing ProjectsController#new (for 1.1.1.1 at 2008-12-24 07:36:49) [GET]
|
7
|
-
Parameters: {"action"=>"new", "controller"=>"projects"}
|
8
|
-
Rendering template within layouts/default
|
9
|
-
Rendering account/dashboard
|
10
|
-
Logging in from session data...
|
11
|
-
Logging in using cookie...
|
12
|
-
Using locale: en-US, http-accept: [], session: , det browser: , det domain: , user pref locale:
|
13
|
-
Rendered shared/_maintenance (0.6ms)
|
14
|
-
Rendering template within layouts/templates/general_default/index.html.erb
|
15
|
-
Rendered projects/_recent_designs (4.3ms)
|
16
|
-
Rendered projects/_project (13.6ms)
|
17
|
-
Rendered projects/_projects (18.7ms)
|
18
|
-
Rendered layouts/_menu (1.4ms)
|
19
|
-
Completed in 36ms (View: 30, DB: 3) | 200 OK [http://www.example.com/projects/new]
|
20
|
-
Rendered layouts/_actions (0.3ms)
|
21
|
-
Rendered layouts/_menu (1.6ms)
|
22
|
-
Rendered layouts/_tabbar (1.9ms)
|
23
|
-
Rendered layouts/_footer (3.2ms)
|
24
|
-
Completed in 50ms (View: 41, DB: 4) | 200 OK [http://www.example.com/dashboard?first_use=true]
|
@@ -1,84 +0,0 @@
|
|
1
|
-
~ Loaded DEVELOPMENT Environment...
|
2
|
-
~ Connecting to database...
|
3
|
-
~ loading gem 'merb_datamapper' ...
|
4
|
-
~ loading gem 'gettext' ...
|
5
|
-
~ loading gem 'merb_helpers' ...
|
6
|
-
~ loading gem 'merb-assets' ...
|
7
|
-
~ loading gem 'merb-action-args' ...
|
8
|
-
~ loading gem 'merb-mailer' ...
|
9
|
-
~ loading gem 'merb_param_protection' ...
|
10
|
-
~ loading gem 'merb_has_flash' ...
|
11
|
-
~ loading gem 'merb_forgery_protection' ...
|
12
|
-
~ loading gem 'dm-validations' ...
|
13
|
-
~ loading gem 'dm-timestamps' ...
|
14
|
-
~ loading gem 'dm-migrations' ...
|
15
|
-
~ loading gem 'dm-aggregates' ...
|
16
|
-
~ loading gem 'dm-adjust' ...
|
17
|
-
~ loading gem 'dm-serializer' ...
|
18
|
-
~ loading gem 'dm-constraints' ...
|
19
|
-
~ loading gem 'dm-timeline' ...
|
20
|
-
~ loading gem 'dm-searchable' ...
|
21
|
-
~ loading gem 'dm-audited' ...
|
22
|
-
~ loading gem 'lib/extensions' ...
|
23
|
-
~ loading gem 'lib/authenticated_system/authenticated_dependencies' ...
|
24
|
-
~ Compiling routes...
|
25
|
-
~ Using 'share-nothing' cookie sessions (4kb limit per client)
|
26
|
-
~ Using Mongrel adapter
|
27
|
-
~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
28
|
-
~ Params: {"_method"=>"delete", "authenticity_token"=>"[FILTERED]", "action"=>"destroy", "method"=>"delete", "controller"=>"session"}
|
29
|
-
~ Cookie deleted: auth_token => nil
|
30
|
-
~ Redirecting to: / (302)
|
31
|
-
~ {:dispatch_time=>0.243424, :after_filters_time=>6.9e-05, :before_filters_time=>0.213213, :action_time=>0.241652}
|
32
|
-
~
|
33
|
-
|
34
|
-
~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
35
|
-
~ Params: {"action"=>"index", "controller"=>"dashboard"}
|
36
|
-
~ Redirecting to: /login (302)
|
37
|
-
~ {:dispatch_time=>0.002649, :after_filters_time=>7.4e-05, :action_time=>0.001951}
|
38
|
-
~
|
39
|
-
|
40
|
-
~ Started request handling: Fri Aug 29 11:10:23 +0200 2008
|
41
|
-
~ Params: {"action"=>"create", "controller"=>"session"}
|
42
|
-
~ {:dispatch_time=>0.006117, :after_filters_time=>6.1e-05, :before_filters_time=>0.000712, :action_time=>0.005833}
|
43
|
-
~
|
44
|
-
|
45
|
-
~ Started request handling: Fri Aug 29 11:10:27 +0200 2008
|
46
|
-
~ Params: {"authenticity_token"=>"[FILTERED]", "action"=>"create", "controller"=>"session", "login"=>"username", "password"=>"[FILTERED]", "remember_me"=>"0"}
|
47
|
-
~ Redirecting to: / (302)
|
48
|
-
~ {:dispatch_time=>0.006652, :after_filters_time=>0.000143, :before_filters_time=>0.000861, :action_time=>0.006171}
|
49
|
-
~
|
50
|
-
|
51
|
-
~ Started request handling: Fri Aug 29 11:10:27 +0200 2008
|
52
|
-
~ Params: {"action"=>"index", "controller"=>"dashboard"}
|
53
|
-
~ Redirecting to: /dashboard (302)
|
54
|
-
~ {:dispatch_time=>0.008241, :after_filters_time=>0.000126, :before_filters_time=>0.002632, :action_time=>0.007711}
|
55
|
-
~
|
56
|
-
|
57
|
-
~ Started request handling: Fri Aug 29 11:10:27 +0200 2008
|
58
|
-
~ Params: {"action"=>"index", "namespace"=>"dashboard", "controller"=>"dashboard"}
|
59
|
-
~ {:dispatch_time=>0.009458, :after_filters_time=>0.000103, :before_filters_time=>0.00266, :action_time=>0.008742}
|
60
|
-
~
|
61
|
-
|
62
|
-
~ Started request handling: Fri Aug 29 11:10:29 +0200 2008
|
63
|
-
~ Params: {"format"=>nil, "action"=>"index", "namespace"=>"dashboard", "controller"=>"employees"}
|
64
|
-
~ {:dispatch_time=>0.102725, :after_filters_time=>0.000115, :before_filters_time=>0.00411, :action_time=>0.101836}
|
65
|
-
~
|
66
|
-
|
67
|
-
~ Started request handling: Fri Aug 29 11:10:30 +0200 2008
|
68
|
-
~ Params: {"format"=>nil, "action"=>"index", "namespace"=>"dashboard", "controller"=>"organisations"}
|
69
|
-
~ {:dispatch_time=>0.042575, :after_filters_time=>8.9e-05, :before_filters_time=>0.004267, :action_time=>0.041762}
|
70
|
-
~
|
71
|
-
|
72
|
-
~ Started request handling: Fri Aug 29 11:10:31 +0200 2008
|
73
|
-
~ Params: {"action"=>"index", "namespace"=>"dashboard", "controller"=>"dashboard"}
|
74
|
-
~ {:dispatch_time=>0.010311, :after_filters_time=>8.0e-05, :before_filters_time=>0.003195, :action_time=>0.009567}
|
75
|
-
~
|
76
|
-
|
77
|
-
~ Started request handling: Fri Aug 29 11:10:33 +0200 2008
|
78
|
-
~ Params: {"format"=>nil, "action"=>"index", "namespace"=>"dashboard", "controller"=>"employees"}
|
79
|
-
~ {:dispatch_time=>0.012913, :after_filters_time=>7.1e-05, :before_filters_time=>0.004422, :action_time=>0.012141}
|
80
|
-
~
|
81
|
-
|
82
|
-
~ Started request handling: Fri Aug 29 11:10:35 +0200 2008
|
83
|
-
~ Params: {"action"=>"new", "namespace"=>"dashboard", "controller"=>"employees"}
|
84
|
-
~ {:dispatch_time=>0.013051, :after_filters_time=>7.8e-05, :before_filters_time=>0.003576, :action_time=>0.011773}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require "#{File.dirname(__FILE__)}/../lib/base/log_parser"
|
4
|
-
require "#{File.dirname(__FILE__)}/../lib/merb_analyzer/log_parser"
|
5
|
-
|
6
|
-
class MerbLogParserTest < Test::Unit::TestCase
|
7
|
-
|
8
|
-
def fragment_file(number)
|
9
|
-
"#{File.dirname(__FILE__)}/log_fragments/merb_#{number}.log"
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_parse_started_merb_fragment
|
13
|
-
requests = []
|
14
|
-
parser = MerbAnalyzer::LogParser.new(fragment_file(1)).each(:started) do |request|
|
15
|
-
requests << request
|
16
|
-
end
|
17
|
-
assert_equal requests[0][:timestamp], "Fri Aug 29 11:10:23 +0200 2008"
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_parse_completed_merb_fragment
|
21
|
-
requests = []
|
22
|
-
parser = MerbAnalyzer::LogParser.new(fragment_file(1)).each(:completed) do |request|
|
23
|
-
requests << request
|
24
|
-
end
|
25
|
-
|
26
|
-
assert_equal requests[0][:action_time], 0.241652
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_parse_params_merb_fragment
|
30
|
-
requests = []
|
31
|
-
parser = MerbAnalyzer::LogParser.new(fragment_file(1)).each(:params) do |request|
|
32
|
-
requests << request
|
33
|
-
end
|
34
|
-
|
35
|
-
assert_match '"controller"=>"session"', requests[0][:raw_hash]
|
36
|
-
assert_match '"action"=>"destroy"', requests[0][:raw_hash]
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|