request-log-analyzer 1.4.2 → 1.5.0
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 +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
|