request-log-analyzer 1.4.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/request-log-analyzer +10 -7
- data/lib/request_log_analyzer.rb +1 -1
- data/lib/request_log_analyzer/aggregator/summarizer.rb +12 -1
- data/lib/request_log_analyzer/controller.rb +31 -10
- data/lib/request_log_analyzer/file_format.rb +46 -2
- data/lib/request_log_analyzer/file_format/apache.rb +1 -1
- data/lib/request_log_analyzer/file_format/mysql.rb +93 -0
- data/lib/request_log_analyzer/file_format/rails_development.rb +1 -1
- data/lib/request_log_analyzer/mailer.rb +7 -4
- data/lib/request_log_analyzer/output/fixed_width.rb +1 -1
- data/lib/request_log_analyzer/request.rb +5 -0
- data/lib/request_log_analyzer/source/log_parser.rb +33 -10
- data/lib/request_log_analyzer/tracker/count.rb +93 -0
- data/request-log-analyzer.gemspec +6 -6
- data/spec/fixtures/mysql_slow_query.log +110 -0
- data/spec/integration/mailer_spec.rb +179 -0
- data/spec/integration/scout_spec.rb +2 -1
- data/spec/lib/helpers.rb +21 -1
- data/spec/unit/file_format/format_autodetection_spec.rb +35 -0
- data/spec/unit/file_format/mysql_format_spec.rb +155 -0
- data/spec/unit/mailer_spec.rb +12 -0
- data/spec/unit/tracker/count_tracker_spec.rb +123 -0
- metadata +126 -115
@@ -0,0 +1,93 @@
|
|
1
|
+
module RequestLogAnalyzer::Tracker
|
2
|
+
|
3
|
+
# Get highest count of a specific attribute
|
4
|
+
class Count < Base
|
5
|
+
|
6
|
+
include RequestLogAnalyzer::Tracker::StatisticsTracking
|
7
|
+
|
8
|
+
attr_reader :categories
|
9
|
+
|
10
|
+
def prepare
|
11
|
+
raise "No categorizer set up for category tracker #{self.inspect}" unless options[:category]
|
12
|
+
raise "No field to count has been set up #{self.inspect}" unless options[:field]
|
13
|
+
|
14
|
+
@categorizer = create_lambda(options[:category])
|
15
|
+
@counter = create_lambda(options[:field])
|
16
|
+
@categories = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the duration information fron the request and store it in the different categories.
|
20
|
+
# <tt>request</tt> The request.
|
21
|
+
def update(request)
|
22
|
+
category = @categorizer.call(request)
|
23
|
+
count = @counter.call(request)
|
24
|
+
update_statistics(category, count) if count.kind_of?(Numeric) && !category.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def report(output)
|
28
|
+
sortings = output.options[:sort] || [:sum, :mean]
|
29
|
+
|
30
|
+
sortings.each do |report|
|
31
|
+
case report
|
32
|
+
when :mean
|
33
|
+
report_table(output, :mean, :title => "#{title} - sorted by mean")
|
34
|
+
when :stddev
|
35
|
+
report_table(output, :stddev, :title => "#{title} - sorted by standard deviation")
|
36
|
+
when :sum
|
37
|
+
report_table(output, :sum, :title => "#{title} - sorted by sum")
|
38
|
+
when :hits
|
39
|
+
report_table(output, :hits, :title => "#{title} - sorted by hits")
|
40
|
+
else
|
41
|
+
raise "Unknown duration report specified: #{report}!"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Block function to build a result table using a provided sorting function.
|
47
|
+
# <tt>output</tt> The output object.
|
48
|
+
# <tt>amount</tt> The number of rows in the report table (default 10).
|
49
|
+
# === Options
|
50
|
+
# * </tt>:title</tt> The title of the table
|
51
|
+
# * </tt>:sort</tt> The key to sort on (:hits, :cumulative, :average, :min or :max)
|
52
|
+
def report_table(output, sort, options = {}, &block)
|
53
|
+
output.puts
|
54
|
+
|
55
|
+
top_categories = output.slice_results(sorted_by(sort))
|
56
|
+
output.with_style(:top_line => true) do
|
57
|
+
output.table(*statistics_header(:title => options[:title],:highlight => sort)) do |rows|
|
58
|
+
top_categories.each { |(cat, info)| rows.push(statistics_row(cat)) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
output.puts
|
62
|
+
end
|
63
|
+
|
64
|
+
# Format an int to a nice string with decimal seperation.
|
65
|
+
# Also see http://en.wikipedia.org/wiki/Terabyte
|
66
|
+
# <tt>count</tt> the value to reduce
|
67
|
+
def display_value(count)
|
68
|
+
return "- " if count.nil?
|
69
|
+
return "0 " if count.zero?
|
70
|
+
|
71
|
+
case Math.log10(count).floor
|
72
|
+
when 1...4 then '%d ' % count
|
73
|
+
when 4...7 then '%dk' % (count / 1000)
|
74
|
+
when 7...10 then '%dM' % (count / 1000_000)
|
75
|
+
when 10...13 then '%dG' % (count / 1000_000_000)
|
76
|
+
when 13...16 then '%dT' % (count / 1000_000_000_000)
|
77
|
+
else '%dP' % (count / 1000_000_000_000_000)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the title of this tracker for reports
|
83
|
+
def title
|
84
|
+
options[:title] || 'Total'
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns all the categories and the tracked duration as a hash than can be exported to YAML
|
88
|
+
def to_yaml_object
|
89
|
+
return nil if @categories.empty?
|
90
|
+
@categories
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
|
|
2
2
|
s.name = "request-log-analyzer"
|
3
3
|
|
4
4
|
# Do not set the version and date field manually, this is done by the release script
|
5
|
-
s.version = "1.
|
6
|
-
s.date = "2009-
|
5
|
+
s.version = "1.5.0"
|
6
|
+
s.date = "2009-11-18"
|
7
7
|
|
8
8
|
s.rubyforge_project = 'r-l-a'
|
9
9
|
|
@@ -26,8 +26,8 @@ Gem::Specification.new do |s|
|
|
26
26
|
|
27
27
|
s.requirements << "To use the database inserter, ActiveRecord and an appropriate database adapter are required."
|
28
28
|
|
29
|
-
s.add_development_dependency('rspec',
|
30
|
-
s.add_development_dependency('git',
|
29
|
+
s.add_development_dependency('rspec', '>= 1.2.4')
|
30
|
+
s.add_development_dependency('git', '>= 1.1.0')
|
31
31
|
|
32
32
|
s.authors = ['Willem van Bergen', 'Bart ten Brinke']
|
33
33
|
s.email = ['willem@railsdoctors.com', 'bart@railsdoctors.com']
|
@@ -35,6 +35,6 @@ Gem::Specification.new do |s|
|
|
35
35
|
|
36
36
|
# The files and test_files directives are set automatically by the release script.
|
37
37
|
# Do not change them by hand, but make sure to add the files to the git repository.
|
38
|
-
s.files = %w(spec/unit/
|
39
|
-
s.test_files = %w(spec/unit/
|
38
|
+
s.files = %w(lib/request_log_analyzer/output/html.rb spec/unit/tracker/hourly_spread_spec.rb DESIGN.rdoc spec/fixtures/rails_unordered.log spec/fixtures/multiple_files_1.log lib/request_log_analyzer/database/source.rb README.rdoc spec/unit/file_format/amazon_s3_format_spec.rb lib/request_log_analyzer/file_format/rails_development.rb spec/fixtures/rails_22.log spec/fixtures/test_order.log spec/unit/database/base_class_spec.rb lib/request_log_analyzer/database/connection.rb lib/request_log_analyzer/aggregator.rb spec/fixtures/decompression.log lib/request_log_analyzer/file_format/apache.rb spec/fixtures/decompression.log.gz lib/request_log_analyzer/tracker/frequency.rb lib/request_log_analyzer/tracker/duration.rb tasks/github-gem.rake .gitignore spec/unit/filter/filter_spec.rb spec/lib/macros.rb spec/spec_helper.rb spec/unit/tracker/count_tracker_spec.rb spec/fixtures/decompression.log.bz2 spec/unit/database/connection_spec.rb lib/request_log_analyzer/filter.rb spec/integration/scout_spec.rb spec/fixtures/test_file_format.log lib/request_log_analyzer/tracker/traffic.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/file_format/file_format_api_spec.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/file_format/merb.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/file_format/amazon_s3.rb lib/cli/database_console.rb spec/integration/mailer_spec.rb lib/request_log_analyzer/line_definition.rb spec/unit/tracker/frequency_tracker_spec.rb spec/fixtures/multiple_files_2.log spec/lib/mocks.rb spec/unit/file_format/apache_format_spec.rb spec/fixtures/syslog_1x.log spec/integration/munin_plugins_rails_spec.rb spec/lib/helpers.rb spec/fixtures/rails.db spec/unit/source/log_parser_spec.rb lib/request_log_analyzer/aggregator/database_inserter.rb spec/fixtures/header_and_footer.log spec/lib/testing_format.rb lib/request_log_analyzer/database.rb spec/unit/file_format/rails_format_spec.rb lib/request_log_analyzer/request.rb lib/request_log_analyzer/output/fixed_width.rb spec/integration/command_line_usage_spec.rb lib/request_log_analyzer/file_format/rack.rb spec/fixtures/test_language_combined.log lib/cli/command_line_arguments.rb lib/request_log_analyzer.rb spec/database.yml spec/unit/request_spec.rb lib/request_log_analyzer/database/base.rb spec/unit/aggregator/database_inserter_spec.rb lib/request_log_analyzer/database/request.rb lib/cli/database_console_init.rb lib/cli/progressbar.rb lib/request_log_analyzer/database/warning.rb spec/unit/filter/anonymize_filter_spec.rb spec/fixtures/apache_combined.log spec/fixtures/rails_22_cached.log lib/request_log_analyzer/aggregator/summarizer.rb spec/unit/tracker/duration_tracker_spec.rb spec/fixtures/rails_1x.log lib/request_log_analyzer/tracker/count.rb lib/request_log_analyzer/output.rb spec/unit/file_format/line_definition_spec.rb lib/request_log_analyzer/file_format/mysql.rb spec/unit/file_format/mysql_format_spec.rb request-log-analyzer.gemspec spec/fixtures/apache_common.log lib/request_log_analyzer/file_format/rails.rb Rakefile spec/unit/mailer_spec.rb lib/request_log_analyzer/tracker/hourly_spread.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/traffic_tracker_spec.rb lib/request_log_analyzer/tracker/timespan.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/field_filter_spec.rb spec/fixtures/merb_prefixed.log lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/filter/timespan.rb spec/unit/controller/controller_spec.rb lib/request_log_analyzer/mailer.rb lib/cli/tools.rb spec/fixtures/decompression.tar.gz spec/unit/tracker/timespan_tracker_spec.rb spec/lib/matchers.rb lib/request_log_analyzer/controller.rb spec/unit/tracker/tracker_api_spec.rb lib/request_log_analyzer/source/database_loader.rb spec/fixtures/merb.log LICENSE lib/request_log_analyzer/file_format.rb tasks/request_log_analyzer.rake spec/unit/database/database_spec.rb spec/fixtures/decompression.log.zip spec/fixtures/decompression.tgz bin/request-log-analyzer lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/source.rb spec/fixtures/mysql_slow_query.log lib/request_log_analyzer/source/log_parser.rb lib/request_log_analyzer/aggregator/echo.rb)
|
39
|
+
s.test_files = %w(spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/database/base_class_spec.rb spec/unit/filter/filter_spec.rb spec/unit/tracker/count_tracker_spec.rb spec/unit/database/connection_spec.rb spec/integration/scout_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/integration/mailer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/munin_plugins_rails_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/file_format/rails_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/request_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/filter/anonymize_filter_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/file_format/mysql_format_spec.rb spec/unit/mailer_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/controller/controller_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/database/database_spec.rb)
|
40
40
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
2
|
+
# Time: 091112 18:13:56
|
3
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
4
|
+
# Query_time: 10 Lock_time: 0 Rows_sent: 1191307 Rows_examined: 1191307
|
5
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
6
|
+
# Time: 091112 18:14:07
|
7
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
8
|
+
# Query_time: 9 Lock_time: 0 Rows_sent: 258841 Rows_examined: 258841
|
9
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `sessions`;
|
10
|
+
# Time: 091112 18:14:44
|
11
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
12
|
+
# Query_time: 6 Lock_time: 0 Rows_sent: 603732 Rows_examined: 603732
|
13
|
+
use sensire_s;
|
14
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
15
|
+
# Time: 091112 18:14:56
|
16
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
17
|
+
# Query_time: 12 Lock_time: 0 Rows_sent: 1068438 Rows_examined: 1068438
|
18
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
19
|
+
# Time: 091112 18:16:18
|
20
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
21
|
+
# Query_time: 17 Lock_time: 0 Rows_sent: 1822689 Rows_examined: 1822689
|
22
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
23
|
+
# Time: 091112 18:16:28
|
24
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
25
|
+
# Query_time: 10 Lock_time: 0 Rows_sent: 1113903 Rows_examined: 1113903
|
26
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
27
|
+
# Time: 091112 18:17:37
|
28
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
29
|
+
# Query_time: 19 Lock_time: 0 Rows_sent: 1631168 Rows_examined: 1631168
|
30
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
31
|
+
# Time: 091112 18:17:49
|
32
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
33
|
+
# Query_time: 11 Lock_time: 0 Rows_sent: 951103 Rows_examined: 951103
|
34
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
35
|
+
# Time: 091112 18:19:31
|
36
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
37
|
+
# Query_time: 7 Lock_time: 0 Rows_sent: 747129 Rows_examined: 747129
|
38
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
39
|
+
# Time: 091112 18:19:49
|
40
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
41
|
+
# Query_time: 17 Lock_time: 0 Rows_sent: 1904679 Rows_examined: 1904679
|
42
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
43
|
+
# Time: 091112 18:21:34
|
44
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
45
|
+
# Query_time: 59 Lock_time: 0 Rows_sent: 5013829 Rows_examined: 5013829
|
46
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
47
|
+
# Time: 091112 18:21:54
|
48
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
49
|
+
# Query_time: 20 Lock_time: 0 Rows_sent: 1634467 Rows_examined: 1634467
|
50
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
51
|
+
# Time: 091112 18:22:58
|
52
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
53
|
+
# Query_time: 5 Lock_time: 0 Rows_sent: 634683 Rows_examined: 634683
|
54
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
55
|
+
# Time: 091112 18:23:58
|
56
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
57
|
+
# Query_time: 5 Lock_time: 0 Rows_sent: 444697 Rows_examined: 444697
|
58
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
59
|
+
# Time: 091112 18:24:34
|
60
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
61
|
+
# Query_time: 7 Lock_time: 0 Rows_sent: 669623 Rows_examined: 669623
|
62
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
63
|
+
# Time: 091112 18:26:18
|
64
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
65
|
+
# Query_time: 27 Lock_time: 0 Rows_sent: 2727395 Rows_examined: 2727395
|
66
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
67
|
+
# Time: 091112 18:26:28
|
68
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
69
|
+
# Query_time: 10 Lock_time: 0 Rows_sent: 859164 Rows_examined: 859164
|
70
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
71
|
+
# Time: 091112 18:27:50
|
72
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
73
|
+
# Query_time: 29 Lock_time: 0 Rows_sent: 2607634 Rows_examined: 2607634
|
74
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
75
|
+
# Time: 091112 18:27:59
|
76
|
+
# User@Host: admin[admin] @ db1 [10.0.0.1]
|
77
|
+
# Query_time: 9 Lock_time: 0 Rows_sent: 766241 Rows_examined: 766241
|
78
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
79
|
+
# Time: 091112 18:30:39
|
80
|
+
# User@Host: user_1[user_1] @ rails1 [10.0.1.3]
|
81
|
+
# Query_time: 6 Lock_time: 0 Rows_sent: 0 Rows_examined: 1648536
|
82
|
+
SELECT * FROM `clients` WHERE (1=1
|
83
|
+
AND clients.valid_from < '2009-12-05' AND (clients.valid_to IS NULL or clients.valid_to > '2009-11-20')
|
84
|
+
AND clients.index > 0
|
85
|
+
) AND (clients.deleted_at IS NULL);
|
86
|
+
# Time: 091112 20:15:16
|
87
|
+
# User@Host: user_2[user_2] @ rails1 [10.0.1.3]
|
88
|
+
# Query_time: 7 Lock_time: 0 Rows_sent: 796074 Rows_examined: 796074
|
89
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
90
|
+
# Time: 091112 20:15:29
|
91
|
+
# User@Host: user_2[user_2] @ rails1 [10.0.1.3]
|
92
|
+
# Query_time: 12 Lock_time: 0 Rows_sent: 1191307 Rows_examined: 1191307
|
93
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
94
|
+
# Time: 091112 20:15:45
|
95
|
+
# User@Host: user_2[user_2] @ rails1 [10.0.1.3]
|
96
|
+
# Query_time: 12 Lock_time: 0 Rows_sent: 259350 Rows_examined: 259350
|
97
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `sessions`;
|
98
|
+
# Time: 091112 20:18:50
|
99
|
+
# User@Host: user_1[user_1] @ rails1 [10.0.1.3]
|
100
|
+
# Query_time: 28 Lock_time: 0 Rows_sent: 2727404 Rows_examined: 2727404
|
101
|
+
use zuwe_p;
|
102
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `clients`;
|
103
|
+
# Time: 091112 20:19:18
|
104
|
+
# User@Host: user_1[user_1] @ rails1 [10.0.1.3]
|
105
|
+
# Query_time: 28 Lock_time: 0 Rows_sent: 859164 Rows_examined: 859164
|
106
|
+
SELECT /*!40001 SQL_NO_CACHE */ * FROM `events`;
|
107
|
+
# Time: 091112 20:19:40
|
108
|
+
# User@Host: user_1[user_1] @ db1 [10.1.1.178]
|
109
|
+
# Query_time: 6 Lock_time: 0 Rows_sent: 33 Rows_examined: 1648542
|
110
|
+
SELECT * FROM `clients` WHERE (valid_to IS NULL OR valid_to > '2009-12-12') AND ((`clients`.`deleted` = 1) AND (clients.deleted_at IS NULL));
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
describe RequestLogAnalyzer, 'running mailer integration' do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@log_file = temp_output_file('mailtrap.log')
|
8
|
+
|
9
|
+
Process.fork {
|
10
|
+
Mailtrap.new('localhost', 2525, true, @log_file)
|
11
|
+
Process.exit! # Do not call rspec after exit hook!
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
cleanup_temp_files!
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should send plaintext mail" do
|
20
|
+
RequestLogAnalyzer::Controller.build(
|
21
|
+
:mail => 'root@localhost',
|
22
|
+
:mailhost => 'localhost:2525',
|
23
|
+
:source_files => log_fixture(:rails_1x),
|
24
|
+
:format => RequestLogAnalyzer::FileFormat::Rails,
|
25
|
+
:no_progress => true
|
26
|
+
).run!
|
27
|
+
|
28
|
+
Process.wait # Wait for mailer to complete
|
29
|
+
|
30
|
+
find_string_in_file("From: <contact@railsdoctors.com>", @log_file).should_not be_nil
|
31
|
+
find_string_in_file("To: <root@localhost>", @log_file).should_not be_nil
|
32
|
+
find_string_in_file("From: Request-log-analyzer reporter <contact@railsdoctors.com>", @log_file).should_not be_nil
|
33
|
+
find_string_in_file("Request summary", @log_file).should_not be_nil
|
34
|
+
find_string_in_file("PeopleController#show.html [ | 1 | 0.29s | 0.29s | 0.00s | 0.29s | 0.29s", @log_file).should_not be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should send html mail" do
|
38
|
+
RequestLogAnalyzer::Controller.build(
|
39
|
+
:output => 'HTML',
|
40
|
+
:mail => 'root@localhost',
|
41
|
+
:mailhost => 'localhost:2525',
|
42
|
+
:source_files => log_fixture(:rails_1x),
|
43
|
+
:format => RequestLogAnalyzer::FileFormat::Rails,
|
44
|
+
:no_progress => true
|
45
|
+
).run!
|
46
|
+
|
47
|
+
Process.wait # Wait for mailer to complete
|
48
|
+
|
49
|
+
find_string_in_file("From: <contact@railsdoctors.com>", @log_file).should_not be_nil
|
50
|
+
find_string_in_file("To: <root@localhost>", @log_file).should_not be_nil
|
51
|
+
find_string_in_file("From: Request-log-analyzer reporter <contact@railsdoctors.com>", @log_file).should_not be_nil
|
52
|
+
find_string_in_file('<h1>Request-log-analyzer summary report</h1>', @log_file).should_not be_nil
|
53
|
+
find_string_in_file('<td class="alt">0.29s</td></tr><tr><td>DashboardController#index.html [GET]</td>', @log_file).should_not be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
# Mailtrap
|
60
|
+
# by Matt Mower <self@mattmower.com>
|
61
|
+
# http://matt.blogs.it/
|
62
|
+
#
|
63
|
+
# Included in RLA because original mailtrap puts anoying stuff when called
|
64
|
+
# through ruby.
|
65
|
+
#
|
66
|
+
# Mailtrap creates a TCP server that listens on a specified port for SMTP
|
67
|
+
# clients. Accepts the connection and talks just enough of the SMTP protocol
|
68
|
+
# for them to deliver a message which it writes to disk.
|
69
|
+
#
|
70
|
+
class Mailtrap
|
71
|
+
VERSION = '0.2.1'
|
72
|
+
|
73
|
+
# Create a new Mailtrap on the specified host:port. If once it true it
|
74
|
+
# will listen for one message then exit. Specify the msgdir where messages
|
75
|
+
# are written.
|
76
|
+
def initialize( host, port, once, msgfile )
|
77
|
+
@host = host
|
78
|
+
@port = port
|
79
|
+
@once = once
|
80
|
+
@msgfile = msgfile
|
81
|
+
|
82
|
+
File.open( @msgfile, "a" ) do |file|
|
83
|
+
file.puts "\n* Mailtrap started at #{@host}:#{port}\n"
|
84
|
+
end
|
85
|
+
|
86
|
+
service = TCPServer.new( @host, @port )
|
87
|
+
accept( service )
|
88
|
+
end
|
89
|
+
|
90
|
+
# Service one or more SMTP client connections
|
91
|
+
def accept( service )
|
92
|
+
while session = service.accept
|
93
|
+
|
94
|
+
class << session
|
95
|
+
def get_line
|
96
|
+
line = gets
|
97
|
+
line.chomp! unless line.nil?
|
98
|
+
line
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
begin
|
103
|
+
serve( session )
|
104
|
+
rescue Exception => e
|
105
|
+
end
|
106
|
+
|
107
|
+
break if @once
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Write a plain text dump of the incoming email to a text
|
112
|
+
# file. The file will be in the @msgdir folder and will
|
113
|
+
# be called smtp0001.msg, smtp0002.msg, and so on.
|
114
|
+
def write( from, to_list, message )
|
115
|
+
|
116
|
+
# Strip SMTP commands from To: and From:
|
117
|
+
from.gsub!( /MAIL FROM:\s*/, "" )
|
118
|
+
to_list = to_list.map { |to| to.gsub( /RCPT TO:\s*/, "" ) }
|
119
|
+
|
120
|
+
# Append to the end of the messages file
|
121
|
+
File.open( @msgfile, "a" ) do |file|
|
122
|
+
file.puts "* Message begins"
|
123
|
+
file.puts "From: #{from}"
|
124
|
+
file.puts "To: #{to_list.join(", ")}"
|
125
|
+
file.puts "Body:"
|
126
|
+
file.puts message
|
127
|
+
file.puts "\n* Message ends"
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
# Talk pidgeon-SMTP to the client to get them to hand over the message
|
133
|
+
# and go away.
|
134
|
+
def serve( connection )
|
135
|
+
connection.puts( "220 #{@host} MailTrap ready ESTMP" )
|
136
|
+
helo = connection.get_line # whoever they are
|
137
|
+
|
138
|
+
if helo =~ /^EHLO\s+/
|
139
|
+
connection.puts "250-#{@host} offers just ONE extension my pretty"
|
140
|
+
connection.puts "250 HELP"
|
141
|
+
end
|
142
|
+
|
143
|
+
# Accept MAIL FROM:
|
144
|
+
from = connection.get_line
|
145
|
+
connection.puts( "250 OK" )
|
146
|
+
|
147
|
+
to_list = []
|
148
|
+
|
149
|
+
# Accept RCPT TO: until we see DATA
|
150
|
+
loop do
|
151
|
+
to = connection.get_line
|
152
|
+
break if to.nil?
|
153
|
+
|
154
|
+
if to =~ /^DATA/
|
155
|
+
connection.puts( "354 Start your message" )
|
156
|
+
break
|
157
|
+
else
|
158
|
+
to_list << to
|
159
|
+
connection.puts( "250 OK" )
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Capture the message body terminated by <CR>.<CR>
|
164
|
+
lines = []
|
165
|
+
loop do
|
166
|
+
line = connection.get_line
|
167
|
+
break if line.nil? || line == "."
|
168
|
+
lines << line
|
169
|
+
end
|
170
|
+
|
171
|
+
# We expect the client will go away now
|
172
|
+
connection.puts( "250 OK" )
|
173
|
+
connection.gets # Quit
|
174
|
+
connection.puts "221 Seeya"
|
175
|
+
connection.close
|
176
|
+
|
177
|
+
write( from, to_list, lines.join( "\n" ) )
|
178
|
+
end
|
179
|
+
end
|
@@ -29,7 +29,8 @@ describe RequestLogAnalyzer, 'when using the rla API like the scout plugin' do
|
|
29
29
|
:output => EmbeddedHTML,
|
30
30
|
:file => sio,
|
31
31
|
:after => Time.local(2008, 8, 14, 21, 16, 31), # after 3rd req
|
32
|
-
:source_files => log
|
32
|
+
:source_files => log,
|
33
|
+
:format => RequestLogAnalyzer::FileFormat::Rails
|
33
34
|
).run!
|
34
35
|
end
|
35
36
|
end
|
data/spec/lib/helpers.rb
CHANGED
@@ -47,6 +47,26 @@ module RequestLogAnalyzer::Spec::Helpers
|
|
47
47
|
|
48
48
|
# Return a filename that can be used as temporary file in specs
|
49
49
|
def temp_output_file(file_type)
|
50
|
-
"#{File.dirname(__FILE__)}/../../tmp/spec.#{file_type}.tmp"
|
50
|
+
File.expand_path("#{File.dirname(__FILE__)}/../../tmp/spec.#{file_type}.tmp")
|
51
|
+
end
|
52
|
+
|
53
|
+
# Check if a given string can be found in the given file
|
54
|
+
# Returns the line number if found, nil otherwise
|
55
|
+
def find_string_in_file(string, file, options = {})
|
56
|
+
return nil unless File::exists?(file)
|
57
|
+
|
58
|
+
line_counter = 0
|
59
|
+
|
60
|
+
File.open( file ) do |io|
|
61
|
+
io.each {|line|
|
62
|
+
line_counter += 1
|
63
|
+
line.chomp!
|
64
|
+
|
65
|
+
p line if options[:debug]
|
66
|
+
return line_counter if line.include? string
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
return nil
|
51
71
|
end
|
52
72
|
end
|