request-log-analyzer 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/DESIGN.rdoc +0 -1
- data/README.rdoc +6 -5
- data/lib/request_log_analyzer.rb +1 -1
- data/lib/request_log_analyzer/file_format.rb +1 -0
- data/lib/request_log_analyzer/file_format/delayed_job2.rb +1 -1
- data/lib/request_log_analyzer/file_format/delayed_job21.rb +39 -0
- data/lib/request_log_analyzer/tracker/duration.rb +7 -0
- data/lib/request_log_analyzer/tracker/numeric_value.rb +119 -12
- data/lib/request_log_analyzer/tracker/traffic.rb +7 -0
- data/request-log-analyzer.gemspec +4 -4
- data/spec/integration/mailer_spec.rb +3 -3
- data/spec/unit/file_format/delayed_job21_format_spec.rb +54 -0
- data/spec/unit/tracker/duration_tracker_spec.rb +3 -1
- data/spec/unit/tracker/numeric_value_tracker_spec.rb +27 -10
- data/tasks/github-gem.rake +24 -36
- metadata +171 -151
data/DESIGN.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -4,11 +4,11 @@ This is a simple command line tool to analyze request log files in various forma
|
|
4
4
|
|
5
5
|
* Analyzes log files. Currently supports: Amazon S3, Apache, Delayed::Job, Merb, Mysql, PostgreSQL, Rack, Rails and more.
|
6
6
|
* Combines multiple files and decompresses compressed files, which comes in handy if you are using logrotate.
|
7
|
-
* Uses several metrics, including cumulative request time, mean request time, process blockers, database and rendering time, HTTP methods and statuses, Rails action cache statistics, etc.) (Sample output: http://
|
7
|
+
* Uses several metrics, including cumulative request time, mean request time, process blockers, database and rendering time, HTTP methods and statuses, Rails action cache statistics, etc.) (Sample output: http://github.com/wvanbergen/request-log-analyzer/wiki/sample-output)
|
8
8
|
* Low memory footprint and reasonably fast, so it is safe to run on a production server.
|
9
9
|
* MIT licensed
|
10
10
|
|
11
|
-
See the project wiki at http://
|
11
|
+
See the project wiki at http://github.com/wvanbergen/request-log-analyzer/wiki for documentation and additional information.
|
12
12
|
|
13
13
|
== Installation & basic usage
|
14
14
|
|
@@ -22,7 +22,7 @@ request-log-analyzer like this:
|
|
22
22
|
|
23
23
|
$ request-log-analyzer log/production.log
|
24
24
|
|
25
|
-
For more details, other file formats, and available command line options, see the project's wiki at http://
|
25
|
+
For more details, other file formats, and available command line options, see the project's wiki at http://github.com/wvanbergen/request-log-analyzer/wiki
|
26
26
|
|
27
27
|
== Additional information
|
28
28
|
|
@@ -33,6 +33,7 @@ Do you have a rails application that is not performing as it should? If you need
|
|
33
33
|
an expert to analyze your application, feel free to contact either Willem van
|
34
34
|
Bergen (willem@railsdoctors.com) or Bart ten Brinke (bart@railsdoctors.com).
|
35
35
|
|
36
|
-
* Project wiki at GitHub: http://
|
36
|
+
* Project wiki at GitHub: http://github.com/wvanbergen/request-log-analyzer/wiki
|
37
|
+
* Issue tracker at GitHub: http://github.com/wvanbergen/request-log-analyzer/issues
|
37
38
|
* railsdoctors homepage: http://railsdoctors.com
|
38
|
-
* wvanbergen's blog posts: http://techblog.floorplanner.com/tag/request-log-analyzer
|
39
|
+
* wvanbergen's blog posts: http://techblog.floorplanner.com/tag/request-log-analyzer
|
data/lib/request_log_analyzer.rb
CHANGED
@@ -13,7 +13,7 @@ module RequestLogAnalyzer
|
|
13
13
|
|
14
14
|
# The current version of request-log-analyzer.
|
15
15
|
# Do not change the value by hand; it will be updated automatically by the gem release script.
|
16
|
-
VERSION = "1.
|
16
|
+
VERSION = "1.9.0"
|
17
17
|
|
18
18
|
|
19
19
|
autoload :Controller, 'request_log_analyzer/controller'
|
@@ -10,6 +10,7 @@ module RequestLogAnalyzer::FileFormat
|
|
10
10
|
autoload :Postgresql, 'request_log_analyzer/file_format/postgresql'
|
11
11
|
autoload :DelayedJob, 'request_log_analyzer/file_format/delayed_job'
|
12
12
|
autoload :DelayedJob2, 'request_log_analyzer/file_format/delayed_job2'
|
13
|
+
autoload :DelayedJob21, 'request_log_analyzer/file_format/delayed_job21'
|
13
14
|
autoload :Apache, 'request_log_analyzer/file_format/apache'
|
14
15
|
autoload :AmazonS3, 'request_log_analyzer/file_format/amazon_s3'
|
15
16
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module RequestLogAnalyzer::FileFormat
|
2
2
|
|
3
|
-
# The DelayedJob2 file format parsed log files that are created by DelayedJob 2.0
|
3
|
+
# The DelayedJob2 file format parsed log files that are created by DelayedJob 2.0.
|
4
4
|
# By default, the log file can be found in RAILS_ROOT/log/delayed_job.log
|
5
5
|
class DelayedJob2 < Base
|
6
6
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RequestLogAnalyzer::FileFormat
|
2
|
+
|
3
|
+
# The DelayedJob21 file format parsed log files that are created by DelayedJob 2.1 or higher.
|
4
|
+
# By default, the log file can be found in RAILS_ROOT/log/delayed_job.log
|
5
|
+
class DelayedJob21 < Base
|
6
|
+
|
7
|
+
extend CommonRegularExpressions
|
8
|
+
|
9
|
+
line_definition :job_lock do |line|
|
10
|
+
line.header = true
|
11
|
+
line.regexp = /(#{timestamp('%Y-%m-%dT%H:%M:%S%z')}): \[Worker\(\w+ host:(\S+) pid:(\d+)\)\] acquired lock on (\S+)/
|
12
|
+
|
13
|
+
line.capture(:timestamp).as(:timestamp)
|
14
|
+
line.capture(:host)
|
15
|
+
line.capture(:pid).as(:integer)
|
16
|
+
line.capture(:job)
|
17
|
+
end
|
18
|
+
|
19
|
+
line_definition :job_completed do |line|
|
20
|
+
line.footer = true
|
21
|
+
line.regexp = /(#{timestamp('%Y-%m-%dT%H:%M:%S%z')}): \[Worker\(\w+ host:(\S+) pid:(\d+)\)\] (\S+) completed after (\d+\.\d+)/
|
22
|
+
line.capture(:timestamp).as(:timestamp)
|
23
|
+
line.capture(:host)
|
24
|
+
line.capture(:pid).as(:integer)
|
25
|
+
line.capture(:job)
|
26
|
+
line.capture(:duration).as(:duration, :unit => :sec)
|
27
|
+
end
|
28
|
+
|
29
|
+
report do |analyze|
|
30
|
+
analyze.timespan
|
31
|
+
analyze.hourly_spread
|
32
|
+
|
33
|
+
analyze.frequency :job, :line_type => :job_completed, :title => "Completed jobs"
|
34
|
+
#analyze.frequency :job, :if => lambda { |request| request[:attempts] == 1 }, :title => "Failed jobs"
|
35
|
+
|
36
|
+
analyze.duration :duration, :category => :job, :line_type => :job_completed, :title => "Job duration"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -25,6 +25,13 @@ module RequestLogAnalyzer::Tracker
|
|
25
25
|
def prepare
|
26
26
|
options[:value] = options[:duration] if options[:duration]
|
27
27
|
super
|
28
|
+
|
29
|
+
@number_of_buckets = options[:number_of_buckets] || 1000
|
30
|
+
@min_bucket_value = options[:min_bucket_value] ? options[:min_bucket_value].to_f : 0.0001
|
31
|
+
@max_bucket_value = options[:max_bucket_value] ? options[:max_bucket_value].to_f : 1000
|
32
|
+
|
33
|
+
# precalculate the bucket size
|
34
|
+
@bucket_size = (Math.log(@max_bucket_value) - Math.log(@min_bucket_value)) / @number_of_buckets.to_f
|
28
35
|
end
|
29
36
|
|
30
37
|
# Display a duration
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RequestLogAnalyzer::Tracker
|
2
|
-
|
2
|
+
|
3
3
|
class NumericValue < Base
|
4
4
|
|
5
5
|
attr_reader :categories
|
@@ -8,7 +8,7 @@ module RequestLogAnalyzer::Tracker
|
|
8
8
|
# options are set that are used to extract and categorize the values during
|
9
9
|
# parsing. Two lambda procedures are created for these tasks
|
10
10
|
def prepare
|
11
|
-
|
11
|
+
|
12
12
|
raise "No value field set up for numeric tracker #{self.inspect}" unless options[:value]
|
13
13
|
raise "No categorizer set up for numeric tracker #{self.inspect}" unless options[:category]
|
14
14
|
|
@@ -16,15 +16,22 @@ module RequestLogAnalyzer::Tracker
|
|
16
16
|
@categorizer = create_lambda(options[:category])
|
17
17
|
@valueizer = create_lambda(options[:value])
|
18
18
|
end
|
19
|
+
|
20
|
+
@number_of_buckets = options[:number_of_buckets] || 1000
|
21
|
+
@min_bucket_value = options[:min_bucket_value] ? options[:min_bucket_value].to_f : 0.000001
|
22
|
+
@max_bucket_value = options[:max_bucket_value] ? options[:max_bucket_value].to_f : 1_000_000_000
|
23
|
+
|
24
|
+
# precalculate the bucket size
|
25
|
+
@bucket_size = (Math.log(@max_bucket_value) - Math.log(@min_bucket_value)) / @number_of_buckets.to_f
|
19
26
|
|
20
27
|
@categories = {}
|
21
28
|
end
|
22
29
|
|
23
30
|
# Get the value information from the request and store it in the respective categories.
|
24
31
|
#
|
25
|
-
# If a request can contain multiple usable values for this tracker, the :multiple option
|
32
|
+
# If a request can contain multiple usable values for this tracker, the :multiple option
|
26
33
|
# should be set to true. In this case, all the values and respective categories will be
|
27
|
-
# read from the request using the #every method from the fields given in the :value and
|
34
|
+
# read from the request using the #every method from the fields given in the :value and
|
28
35
|
# :category option.
|
29
36
|
#
|
30
37
|
# If the request contains only one suitable value and the :multiple is not set, it will
|
@@ -38,11 +45,11 @@ module RequestLogAnalyzer::Tracker
|
|
38
45
|
found_categories = request.every(options[:category])
|
39
46
|
found_values = request.every(options[:value])
|
40
47
|
raise "Capture mismatch for multiple values in a request" unless found_categories.length == found_values.length
|
41
|
-
|
42
|
-
found_categories.each_with_index do |cat, index|
|
48
|
+
|
49
|
+
found_categories.each_with_index do |cat, index|
|
43
50
|
update_statistics(cat, found_values[index]) if cat && found_values[index].kind_of?(Numeric)
|
44
51
|
end
|
45
|
-
|
52
|
+
|
46
53
|
else
|
47
54
|
category = @categorizer.call(request)
|
48
55
|
value = @valueizer.call(request)
|
@@ -90,7 +97,7 @@ module RequestLogAnalyzer::Tracker
|
|
90
97
|
sortings.each do |sorting|
|
91
98
|
report_table(output, sorting, :title => "#{title} - by #{sorting}")
|
92
99
|
end
|
93
|
-
|
100
|
+
|
94
101
|
if options[:total]
|
95
102
|
output.puts
|
96
103
|
output.puts "#{output.colorize(title, :white, :bold)} - total: " + output.colorize(display_value(sum_overall), :brown, :bold)
|
@@ -116,13 +123,109 @@ module RequestLogAnalyzer::Tracker
|
|
116
123
|
return nil if @categories.empty?
|
117
124
|
@categories
|
118
125
|
end
|
126
|
+
|
127
|
+
|
128
|
+
# Returns the bucket index for a value
|
129
|
+
def bucket_index(value)
|
130
|
+
return 0 if value < @min_bucket_value
|
131
|
+
return @number_of_buckets - 1 if value >= @max_bucket_value
|
132
|
+
|
133
|
+
((Math.log(value) - Math.log(@min_bucket_value)) / @bucket_size).floor
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the lower value of a bucket given its index
|
137
|
+
def bucket_lower_bound(index)
|
138
|
+
Math.exp((index * @bucket_size) + Math.log(@min_bucket_value))
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns the upper value of a bucket given its index
|
142
|
+
def bucket_upper_bound(index)
|
143
|
+
bucket_lower_bound(index + 1)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the average of the lower and upper bound of the bucket.
|
147
|
+
def bucket_average_value(index)
|
148
|
+
(bucket_lower_bound(index) + bucket_upper_bound(index)) / 2
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns a single value representing a bucket.
|
152
|
+
def bucket_value(index, type = nil)
|
153
|
+
case type
|
154
|
+
when :begin, :start, :lower, :lower_bound; bucket_lower_bound(index)
|
155
|
+
when :end, :finish, :upper, :upper_bound; bucket_upper_bound(index)
|
156
|
+
else bucket_average_value(index)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Returns the range of values for a bucket.
|
161
|
+
def bucket_interval(index)
|
162
|
+
Range.new(bucket_lower_bound(index), bucket_upper_bound(index), true)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Records a hit on a bucket that includes the given value.
|
166
|
+
def bucketize(category, value)
|
167
|
+
@categories[category][:buckets][bucket_index(value)] += 1
|
168
|
+
end
|
169
|
+
|
170
|
+
# Returns the upper bound value that would include x% of the hits.
|
171
|
+
def percentile_index(category, x, inclusive = false)
|
172
|
+
total_encountered = 0
|
173
|
+
@categories[category][:buckets].each_with_index do |count, index|
|
174
|
+
total_encountered += count
|
175
|
+
percentage = ((total_encountered.to_f / hits(category).to_f) * 100).floor
|
176
|
+
return index if (inclusive && percentage >= x) || (!inclusive && percentage > x)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def percentile_indices(category, start, finish)
|
181
|
+
result = [nil, nil]
|
182
|
+
total_encountered = 0
|
183
|
+
@categories[category][:buckets].each_with_index do |count, index|
|
184
|
+
total_encountered += count
|
185
|
+
percentage = ((total_encountered.to_f / hits(category).to_f) * 100).floor
|
186
|
+
if !result[0] && percentage > start
|
187
|
+
result[0] = index
|
188
|
+
elsif !result[1] && percentage >= finish
|
189
|
+
result[1] = index
|
190
|
+
return result
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def percentile(category, x, type = nil)
|
196
|
+
bucket_value(percentile_index(category, x, type == :upper), type)
|
197
|
+
end
|
198
|
+
|
119
199
|
|
200
|
+
def median(category)
|
201
|
+
percentile(category, 50, :average)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Returns a percentile interval, i.e. the lower bound and the upper bound of the values
|
205
|
+
# that represent the x%-interval for the bucketized dataset.
|
206
|
+
#
|
207
|
+
# A 90% interval means that 5% of the values would have been lower than the lower bound and
|
208
|
+
# 5% would have been higher than the upper bound, leaving 90% of the values within the bounds.
|
209
|
+
# You can also provide a Range to specify the lower bound and upper bound percentages (e.g. 5..95).
|
210
|
+
def percentile_interval(category, x)
|
211
|
+
case x
|
212
|
+
when Range
|
213
|
+
lower, upper = percentile_indices(category, x.begin, x.end)
|
214
|
+
Range.new(bucket_lower_bound(lower), bucket_upper_bound(upper))
|
215
|
+
when Numeric
|
216
|
+
percentile_interval(category, Range.new((100 - x) / 2, (100 - (100 - x) / 2)))
|
217
|
+
else
|
218
|
+
raise 'What does it mean?'
|
219
|
+
end
|
220
|
+
end
|
120
221
|
|
121
|
-
# Update
|
222
|
+
# Update the running calculation of statistics with the newly found numeric value.
|
122
223
|
# <tt>category</tt>:: The category for which to update the running statistics calculations
|
123
224
|
# <tt>number</tt>:: The numeric value to update the calculations with.
|
124
225
|
def update_statistics(category, number)
|
125
|
-
@categories[category] ||= {:hits => 0, :sum => 0, :mean => 0.0, :sum_of_squares => 0.0, :min => number, :max => number
|
226
|
+
@categories[category] ||= { :hits => 0, :sum => 0, :mean => 0.0, :sum_of_squares => 0.0, :min => number, :max => number,
|
227
|
+
:buckets => Array.new(@number_of_buckets, 0) }
|
228
|
+
|
126
229
|
delta = number - @categories[category][:mean]
|
127
230
|
|
128
231
|
@categories[category][:hits] += 1
|
@@ -131,6 +234,8 @@ module RequestLogAnalyzer::Tracker
|
|
131
234
|
@categories[category][:sum] += number
|
132
235
|
@categories[category][:min] = number if number < @categories[category][:min]
|
133
236
|
@categories[category][:max] = number if number > @categories[category][:max]
|
237
|
+
|
238
|
+
bucketize(category, number)
|
134
239
|
end
|
135
240
|
|
136
241
|
# Get the number of hits of a specific category.
|
@@ -210,14 +315,16 @@ module RequestLogAnalyzer::Tracker
|
|
210
315
|
{:title => 'Mean', :align => :right, :highlight => (options[:highlight] == :mean), :min_width => 6},
|
211
316
|
{:title => 'StdDev', :align => :right, :highlight => (options[:highlight] == :stddev), :min_width => 6},
|
212
317
|
{:title => 'Min', :align => :right, :highlight => (options[:highlight] == :min), :min_width => 6},
|
213
|
-
{:title => 'Max', :align => :right, :highlight => (options[:highlight] == :max), :min_width => 6}
|
318
|
+
{:title => 'Max', :align => :right, :highlight => (options[:highlight] == :max), :min_width => 6},
|
319
|
+
{:title => '95 %tile', :align => :right, :highlight => (options[:highlight] == :percentile_interval), :min_width => 11}
|
214
320
|
]
|
215
321
|
end
|
216
322
|
|
217
323
|
# Returns a row of statistics information for a report table, given a category
|
218
324
|
def statistics_row(cat)
|
219
325
|
[cat, hits(cat), display_value(sum(cat)), display_value(mean(cat)), display_value(stddev(cat)),
|
220
|
-
display_value(min(cat)), display_value(max(cat))
|
326
|
+
display_value(min(cat)), display_value(max(cat)),
|
327
|
+
display_value(percentile_interval(cat, 95).begin) + '-' + display_value(percentile_interval(cat, 95).end) ]
|
221
328
|
end
|
222
329
|
end
|
223
330
|
end
|
@@ -16,6 +16,13 @@ module RequestLogAnalyzer::Tracker
|
|
16
16
|
options[:value] = options[:traffic] if options[:traffic]
|
17
17
|
options[:total] = true
|
18
18
|
super
|
19
|
+
|
20
|
+
@number_of_buckets = options[:number_of_buckets] || 1000
|
21
|
+
@min_bucket_value = options[:min_bucket_value] ? options[:min_bucket_value].to_f : 1
|
22
|
+
@max_bucket_value = options[:max_bucket_value] ? options[:max_bucket_value].to_f : 1000_000_000_000
|
23
|
+
|
24
|
+
# precalculate the bucket size
|
25
|
+
@bucket_size = (Math.log(@max_bucket_value) - Math.log(@min_bucket_value)) / @number_of_buckets.to_f
|
19
26
|
end
|
20
27
|
|
21
28
|
# Formats the traffic number using x B/kB/MB/GB etc notation
|
@@ -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 = "2010-
|
5
|
+
s.version = "1.9.0"
|
6
|
+
s.date = "2010-09-26"
|
7
7
|
|
8
8
|
s.rubyforge_project = 'r-l-a'
|
9
9
|
|
@@ -43,6 +43,6 @@ Gem::Specification.new do |s|
|
|
43
43
|
|
44
44
|
# The files and test_files directives are set automatically by the release script.
|
45
45
|
# Do not change them by hand, but make sure to add the files to the git repository.
|
46
|
-
s.files = %w(
|
47
|
-
s.test_files = %w(spec/
|
46
|
+
s.files = %w(.gitignore DESIGN.rdoc LICENSE README.rdoc Rakefile bin/request-log-analyzer lib/cli/command_line_arguments.rb lib/cli/database_console.rb lib/cli/database_console_init.rb lib/cli/progressbar.rb lib/cli/tools.rb lib/mixins/gets_memory_protection.rb lib/request_log_analyzer.rb lib/request_log_analyzer/aggregator.rb lib/request_log_analyzer/aggregator/database_inserter.rb lib/request_log_analyzer/aggregator/echo.rb lib/request_log_analyzer/aggregator/summarizer.rb lib/request_log_analyzer/controller.rb lib/request_log_analyzer/database.rb lib/request_log_analyzer/database/base.rb lib/request_log_analyzer/database/connection.rb lib/request_log_analyzer/database/request.rb lib/request_log_analyzer/database/source.rb lib/request_log_analyzer/database/warning.rb lib/request_log_analyzer/file_format.rb lib/request_log_analyzer/file_format/amazon_s3.rb lib/request_log_analyzer/file_format/apache.rb lib/request_log_analyzer/file_format/delayed_job.rb lib/request_log_analyzer/file_format/delayed_job2.rb lib/request_log_analyzer/file_format/delayed_job21.rb lib/request_log_analyzer/file_format/merb.rb lib/request_log_analyzer/file_format/mysql.rb lib/request_log_analyzer/file_format/oink.rb lib/request_log_analyzer/file_format/postgresql.rb lib/request_log_analyzer/file_format/rack.rb lib/request_log_analyzer/file_format/rails.rb lib/request_log_analyzer/file_format/rails3.rb lib/request_log_analyzer/file_format/rails_development.rb lib/request_log_analyzer/filter.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/filter/timespan.rb lib/request_log_analyzer/line_definition.rb lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/mailer.rb lib/request_log_analyzer/output.rb lib/request_log_analyzer/output/fancy_html.rb lib/request_log_analyzer/output/fixed_width.rb lib/request_log_analyzer/output/html.rb lib/request_log_analyzer/request.rb lib/request_log_analyzer/source.rb lib/request_log_analyzer/source/database_loader.rb lib/request_log_analyzer/source/log_parser.rb lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/tracker/duration.rb lib/request_log_analyzer/tracker/frequency.rb lib/request_log_analyzer/tracker/hourly_spread.rb lib/request_log_analyzer/tracker/numeric_value.rb lib/request_log_analyzer/tracker/timespan.rb lib/request_log_analyzer/tracker/traffic.rb request-log-analyzer.gemspec spec/database.yml spec/fixtures/apache_combined.log spec/fixtures/apache_common.log spec/fixtures/decompression.log spec/fixtures/decompression.log.bz2 spec/fixtures/decompression.log.gz spec/fixtures/decompression.log.zip spec/fixtures/decompression.tar.gz spec/fixtures/decompression.tgz spec/fixtures/header_and_footer.log spec/fixtures/merb.log spec/fixtures/merb_prefixed.log spec/fixtures/multiple_files_1.log spec/fixtures/multiple_files_2.log spec/fixtures/mysql_slow_query.log spec/fixtures/oink_22.log spec/fixtures/oink_22_failure.log spec/fixtures/postgresql.log spec/fixtures/rails.db spec/fixtures/rails_1x.log spec/fixtures/rails_22.log spec/fixtures/rails_22_cached.log spec/fixtures/rails_unordered.log spec/fixtures/sinatra.log spec/fixtures/syslog_1x.log spec/fixtures/test_file_format.log spec/fixtures/test_language_combined.log spec/fixtures/test_order.log spec/integration/command_line_usage_spec.rb spec/integration/mailer_spec.rb spec/integration/munin_plugins_rails_spec.rb spec/integration/scout_spec.rb spec/lib/helpers.rb spec/lib/macros.rb spec/lib/matchers.rb spec/lib/mocks.rb spec/lib/testing_format.rb spec/spec_helper.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/controller/controller_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/database/base_class_spec.rb spec/unit/database/connection_spec.rb spec/unit/database/database_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/file_format/apache_format_spec.rb spec/unit/file_format/common_regular_expressions_spec.rb spec/unit/file_format/delayed_job21_format_spec.rb spec/unit/file_format/delayed_job2_format_spec.rb spec/unit/file_format/delayed_job_format_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/mysql_format_spec.rb spec/unit/file_format/oink_format_spec.rb spec/unit/file_format/postgresql_format_spec.rb spec/unit/file_format/rack_format_spec.rb spec/unit/file_format/rails3_format_spec.rb spec/unit/file_format/rails_format_spec.rb spec/unit/filter/anonymize_filter_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/filter/filter_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/mailer_spec.rb spec/unit/request_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/unit/tracker/numeric_value_tracker_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/traffic_tracker_spec.rb tasks/github-gem.rake tasks/request_log_analyzer.rake)
|
47
|
+
s.test_files = %w(spec/integration/command_line_usage_spec.rb spec/integration/mailer_spec.rb spec/integration/munin_plugins_rails_spec.rb spec/integration/scout_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/controller/controller_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/database/base_class_spec.rb spec/unit/database/connection_spec.rb spec/unit/database/database_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/file_format/apache_format_spec.rb spec/unit/file_format/common_regular_expressions_spec.rb spec/unit/file_format/delayed_job21_format_spec.rb spec/unit/file_format/delayed_job2_format_spec.rb spec/unit/file_format/delayed_job_format_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/mysql_format_spec.rb spec/unit/file_format/oink_format_spec.rb spec/unit/file_format/postgresql_format_spec.rb spec/unit/file_format/rack_format_spec.rb spec/unit/file_format/rails3_format_spec.rb spec/unit/file_format/rails_format_spec.rb spec/unit/filter/anonymize_filter_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/filter/filter_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/mailer_spec.rb spec/unit/request_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/unit/tracker/numeric_value_tracker_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/traffic_tracker_spec.rb)
|
48
48
|
end
|
@@ -32,7 +32,7 @@ describe RequestLogAnalyzer, 'running mailer integration' do
|
|
32
32
|
find_string_in_file("From: Request-log-analyzer reporter <contact@railsdoctors.com>", @log_file).should_not be_nil
|
33
33
|
find_string_in_file("Subject: Request log analyzer report - generated on", @log_file).should_not be_nil
|
34
34
|
find_string_in_file("Request summary", @log_file).should_not be_nil
|
35
|
-
find_string_in_file("
|
35
|
+
find_string_in_file("PeopleControll | 1 | 0.04s | 0.04s | 0.00s | 0.04s | 0.04s | 0.04s-0.04s", @log_file).should_not be_nil
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should allow a custom mail subject" do
|
@@ -66,7 +66,7 @@ describe RequestLogAnalyzer, 'running mailer integration' do
|
|
66
66
|
find_string_in_file("To: <root@localhost>", @log_file).should_not be_nil
|
67
67
|
find_string_in_file("From: Request-log-analyzer reporter <contact@railsdoctors.com>", @log_file).should_not be_nil
|
68
68
|
find_string_in_file('<h1>Request-log-analyzer summary report</h1>', @log_file).should_not be_nil
|
69
|
-
find_string_in_file('<td class="alt">0.29s</td></tr><tr><td>DashboardController#index.html [GET]</td>', @log_file).should_not be_nil
|
69
|
+
find_string_in_file('<td class="alt">0.29s-0.30s</td></tr><tr><td>DashboardController#index.html [GET]</td>', @log_file).should_not be_nil
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -94,7 +94,7 @@ class Mailtrap
|
|
94
94
|
@port = port
|
95
95
|
@once = once
|
96
96
|
@msgfile = msgfile
|
97
|
-
|
97
|
+
|
98
98
|
File.open( @msgfile, "a" ) do |file|
|
99
99
|
file.puts "\n* Mailtrap started at #{@host}:#{port}\n"
|
100
100
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::FileFormat::DelayedJob do
|
4
|
+
|
5
|
+
it "should be a valid file format" do
|
6
|
+
RequestLogAnalyzer::FileFormat.load(:delayed_job).should be_valid
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#parse_line' do
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@file_format = RequestLogAnalyzer::FileFormat.load(:delayed_job21)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should parse a :job_lock line correctly" do
|
16
|
+
line = "2010-05-17T17:37:34+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob"
|
17
|
+
@file_format.should parse_line(line).as(:job_lock).and_capture(:timestamp => 20100517173734,
|
18
|
+
:job => 'S3FileJob', :host => 'hostname.co.uk', :pid => 11888)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should parse a :job_completed line correctly" do
|
22
|
+
line = '2010-05-17T17:37:35+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 1.0676'
|
23
|
+
@file_format.should parse_line(line).as(:job_completed).and_capture(:timestamp => 20100517173735,
|
24
|
+
:duration => 1.0676, :host => 'hostname.co.uk', :pid => 11888, :job => 'S3FileJob')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#parse_io' do
|
29
|
+
before(:each) do
|
30
|
+
@log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:delayed_job21))
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should parse a batch of completed jobs without warnings" do
|
34
|
+
fragment = <<-EOLOG
|
35
|
+
2010-05-17T17:36:44+0000: *** Starting job worker delayed_job host:hostname.co.uk pid:11888
|
36
|
+
2010-05-17T17:37:34+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob
|
37
|
+
2010-05-17T17:37:35+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 1.0676
|
38
|
+
2010-05-17T17:37:35+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob
|
39
|
+
2010-05-17T17:37:37+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 1.4407
|
40
|
+
2010-05-17T17:37:37+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob
|
41
|
+
2010-05-17T17:37:44+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 6.9374
|
42
|
+
2010-05-17T17:37:44+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] 3 jobs processed at 0.3163 j/s, 0 failed ...
|
43
|
+
2010-05-19T11:47:26+0000: Exiting...
|
44
|
+
EOLOG
|
45
|
+
|
46
|
+
request_counter.should_receive(:hit!).exactly(3).times
|
47
|
+
@log_parser.should_not_receive(:warn)
|
48
|
+
|
49
|
+
@log_parser.parse_io(StringIO.new(fragment)) do |request|
|
50
|
+
request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::DelayedJob21::Request)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -27,7 +27,9 @@ describe RequestLogAnalyzer::Tracker::Duration do
|
|
27
27
|
it "should generate a YAML output" do
|
28
28
|
@tracker.update(request(:category => 'a', :duration => 0.2))
|
29
29
|
@tracker.update(request(:category => 'b', :duration => 0.2))
|
30
|
-
@tracker.to_yaml_object.should
|
30
|
+
@tracker.to_yaml_object.keys.should =~ ['a', 'b']
|
31
|
+
@tracker.to_yaml_object['a'].should include(:min => 0.2, :hits => 1, :max => 0.2, :mean => 0.2, :sum => 0.2, :sum_of_squares => 0.0)
|
32
|
+
@tracker.to_yaml_object['b'].should include(:min => 0.2, :hits => 1, :max => 0.2, :mean => 0.2, :sum => 0.2, :sum_of_squares => 0.0)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
@@ -22,7 +22,7 @@ describe RequestLogAnalyzer::Tracker::NumericValue do
|
|
22
22
|
@tracker.categories['b'][:sum].should == 4
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
|
27
27
|
context 'dynamic category' do
|
28
28
|
before(:each) do
|
@@ -40,11 +40,12 @@ describe RequestLogAnalyzer::Tracker::NumericValue do
|
|
40
40
|
@tracker.categories['slow'][:sum].should == 4
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
44
|
-
describe '#update' do
|
45
43
|
|
44
|
+
describe '#update' do
|
46
45
|
before(:each) do
|
47
|
-
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:value => :duration, :category => :category
|
46
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:value => :duration, :category => :category,
|
47
|
+
:min_bucket_value => 0.0001, :max_bucket_value => 1000)
|
48
|
+
|
48
49
|
@tracker.prepare
|
49
50
|
|
50
51
|
@tracker.update(request(:category => 'a', :duration => 0.4))
|
@@ -80,7 +81,25 @@ describe RequestLogAnalyzer::Tracker::NumericValue do
|
|
80
81
|
it "should calculate the duration standard deviation correctly" do
|
81
82
|
@tracker.stddev('a').should be_close(0.1, 0.000001)
|
82
83
|
end
|
83
|
-
|
84
|
+
|
85
|
+
it "should calculate the bucket spread correctly" do
|
86
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
87
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
88
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
89
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
90
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
91
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
92
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
93
|
+
# 0.2, 0.3 and 0.4 are already there, so, 10 values in total
|
94
|
+
|
95
|
+
@tracker.median('a').should be_close(0.3, 0.01)
|
96
|
+
|
97
|
+
@tracker.percentile_interval('a', 80).begin.should be_close(0.3, 0.01)
|
98
|
+
@tracker.percentile_interval('a', 80).end.should be_close(0.3, 0.01)
|
99
|
+
@tracker.percentile_interval('a', 90).begin.should be_close(0.2, 0.01)
|
100
|
+
@tracker.percentile_interval('a', 90).end.should be_close(0.4, 0.01)
|
101
|
+
end
|
102
|
+
end
|
84
103
|
|
85
104
|
describe '#report' do
|
86
105
|
before(:each) do
|
@@ -113,9 +132,9 @@ describe RequestLogAnalyzer::Tracker::NumericValue do
|
|
113
132
|
it "should generate a YAML output" do
|
114
133
|
@tracker.update(request(:category => 'a', :blah => 2))
|
115
134
|
@tracker.update(request(:category => 'b', :blah => 3))
|
116
|
-
@tracker.to_yaml_object.should
|
117
|
-
|
118
|
-
|
135
|
+
@tracker.to_yaml_object.keys.should =~ ['a', 'b']
|
136
|
+
@tracker.to_yaml_object['a'].should include(:min => 2, :hits => 1, :max => 2, :mean => 2.0, :sum => 2, :sum_of_squares => 0.0)
|
137
|
+
@tracker.to_yaml_object['b'].should include(:min => 3, :hits => 1, :max => 3, :mean => 3.0, :sum => 3, :sum_of_squares => 0.0)
|
119
138
|
end
|
120
139
|
end
|
121
140
|
|
@@ -161,6 +180,4 @@ describe RequestLogAnalyzer::Tracker::NumericValue do
|
|
161
180
|
@tracker.display_value(9000_000_001_001_000).should eql('9000T')
|
162
181
|
end
|
163
182
|
end
|
164
|
-
|
165
|
-
|
166
183
|
end
|
data/tasks/github-gem.rake
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'rake/tasklib'
|
4
4
|
require 'date'
|
5
|
-
require '
|
5
|
+
require 'set'
|
6
6
|
|
7
7
|
module GithubGem
|
8
8
|
|
@@ -24,7 +24,7 @@ module GithubGem
|
|
24
24
|
|
25
25
|
class RakeTasks
|
26
26
|
|
27
|
-
attr_reader :gemspec, :modified_files
|
27
|
+
attr_reader :gemspec, :modified_files
|
28
28
|
attr_accessor :gemspec_file, :task_namespace, :main_include, :root_dir, :spec_pattern, :test_pattern, :remote, :remote_branch, :local_branch
|
29
29
|
|
30
30
|
# Initializes the settings, yields itself for configuration
|
@@ -33,7 +33,7 @@ module GithubGem
|
|
33
33
|
@gemspec_file = GithubGem.detect_gemspec_file
|
34
34
|
@task_namespace = task_namespace
|
35
35
|
@main_include = GithubGem.detect_main_include
|
36
|
-
@modified_files =
|
36
|
+
@modified_files = Set.new
|
37
37
|
@root_dir = Dir.pwd
|
38
38
|
@test_pattern = 'test/**/*_test.rb'
|
39
39
|
@spec_pattern = 'spec/**/*_spec.rb'
|
@@ -43,13 +43,16 @@ module GithubGem
|
|
43
43
|
|
44
44
|
yield(self) if block_given?
|
45
45
|
|
46
|
-
@git = Git.open(@root_dir)
|
47
46
|
load_gemspec!
|
48
47
|
define_tasks!
|
49
48
|
end
|
50
49
|
|
51
50
|
protected
|
52
51
|
|
52
|
+
def git
|
53
|
+
@git ||= ENV['GIT'] || 'git'
|
54
|
+
end
|
55
|
+
|
53
56
|
# Define Unit test tasks
|
54
57
|
def define_test_tasks!
|
55
58
|
require 'rake/testtask'
|
@@ -165,7 +168,7 @@ module GithubGem
|
|
165
168
|
# in the repository and the spec/test file pattern.
|
166
169
|
def manifest_task
|
167
170
|
# Load all the gem's files using "git ls-files"
|
168
|
-
repository_files = git
|
171
|
+
repository_files = `#{git} ls-files`.split("\n")
|
169
172
|
test_files = Dir[test_pattern] + Dir[spec_pattern]
|
170
173
|
|
171
174
|
update_gemspec(:files, repository_files)
|
@@ -180,7 +183,7 @@ module GithubGem
|
|
180
183
|
end
|
181
184
|
|
182
185
|
def newest_version
|
183
|
-
git.
|
186
|
+
`#{git} tag`.split("\n").map { |tag| tag.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max || Gem::Version.new('0.0.0')
|
184
187
|
end
|
185
188
|
|
186
189
|
def next_version(increment = nil)
|
@@ -223,58 +226,45 @@ module GithubGem
|
|
223
226
|
|
224
227
|
# Checks whether the current branch is not diverged from the remote branch
|
225
228
|
def check_not_diverged_task
|
226
|
-
raise "The current branch is diverged from the remote branch!" if git
|
229
|
+
raise "The current branch is diverged from the remote branch!" if `#{git} rev-list HEAD..#{remote}/#{remote_branch}`.split("\n").any?
|
227
230
|
end
|
228
231
|
|
229
232
|
# Checks whether the repository status ic clean
|
230
233
|
def check_clean_status_task
|
231
|
-
raise "The current working copy contains modifications" if git.
|
234
|
+
raise "The current working copy contains modifications" if `#{git} ls-files -m`.split("\n").any?
|
232
235
|
end
|
233
236
|
|
234
237
|
# Checks whether the current branch is correct
|
235
238
|
def check_current_branch_task
|
236
|
-
raise "Currently not on #{local_branch} branch!" unless git
|
239
|
+
raise "Currently not on #{local_branch} branch!" unless `#{git} branch`.split("\n").detect { |b| /^\* / =~ b } == "* #{local_branch}"
|
237
240
|
end
|
238
241
|
|
239
242
|
# Fetches the latest updates from Github
|
240
243
|
def fetch_origin_task
|
241
|
-
git
|
244
|
+
sh git, 'fetch', remote
|
242
245
|
end
|
243
246
|
|
244
247
|
# Commits every file that has been changed by the release task.
|
245
248
|
def commit_modified_files_task
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
+
really_modified = `#{git} ls-files -m #{modified_files.entries.join(' ')}`.split("\n")
|
250
|
+
if really_modified.any?
|
251
|
+
really_modified.each { |file| sh git, 'add', file }
|
252
|
+
sh git, 'commit', '-m', "Released #{gemspec.name} gem version #{gemspec.version}."
|
249
253
|
end
|
250
254
|
end
|
251
255
|
|
252
256
|
# Adds a tag for the released version
|
253
257
|
def tag_version_task
|
254
|
-
git
|
258
|
+
sh git, 'tag', '-a', "#{gemspec.name}-#{gemspec.version}", '-m', "Released #{gemspec.name} gem version #{gemspec.version}."
|
255
259
|
end
|
256
260
|
|
257
261
|
# Pushes the changes and tag to github
|
258
262
|
def github_release_task
|
259
|
-
git
|
263
|
+
sh git, 'push', '--tags', remote, remote_branch
|
260
264
|
end
|
261
265
|
|
262
|
-
# # Checks whether Rubyforge is configured properly
|
263
|
-
# def check_rubyforge_task
|
264
|
-
# # Login no longer necessary when using rubyforge 2.0.0 gem
|
265
|
-
# # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
|
266
|
-
# output = `rubyforge names`.split("\n")
|
267
|
-
# raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
|
268
|
-
# raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
|
269
|
-
# end
|
270
|
-
|
271
|
-
# # Task to release the .gem file toRubyforge.
|
272
|
-
# def rubyforge_release_task
|
273
|
-
# sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
274
|
-
# end
|
275
|
-
|
276
266
|
def gemcutter_release_task
|
277
|
-
sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
267
|
+
sh "gem", 'push', "pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
278
268
|
end
|
279
269
|
|
280
270
|
# Gem release task.
|
@@ -357,15 +347,13 @@ module GithubGem
|
|
357
347
|
open(__FILE__, "w") { |file| file.write(response.body) }
|
358
348
|
end
|
359
349
|
|
360
|
-
relative_file = File.expand_path(__FILE__).sub(%r[^#{
|
361
|
-
if git
|
362
|
-
git
|
363
|
-
git
|
364
|
-
puts "Updated to latest version of gem release management tasks."
|
350
|
+
relative_file = File.expand_path(__FILE__).sub(%r[^#{@root_dir}/], '')
|
351
|
+
if `#{git} ls-files -m #{relative_file}`.split("\n").any?
|
352
|
+
sh git, 'add', relative_file
|
353
|
+
sh git, 'commit', '-m', "Updated to latest gem release management tasks."
|
365
354
|
else
|
366
355
|
puts "Release managament tasks already are at the latest version."
|
367
356
|
end
|
368
357
|
end
|
369
|
-
|
370
358
|
end
|
371
359
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: request-log-analyzer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 51
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 1.9.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Willem van Bergen
|
@@ -15,16 +16,18 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-
|
19
|
+
date: 2010-09-26 00:00:00 +02:00
|
19
20
|
default_executable: request-log-analyzer
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: rake
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
25
27
|
requirements:
|
26
28
|
- - ">="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
28
31
|
segments:
|
29
32
|
- 0
|
30
33
|
version: "0"
|
@@ -34,9 +37,11 @@ dependencies:
|
|
34
37
|
name: rspec
|
35
38
|
prerelease: false
|
36
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
37
41
|
requirements:
|
38
42
|
- - ">="
|
39
43
|
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
40
45
|
segments:
|
41
46
|
- 0
|
42
47
|
version: "0"
|
@@ -46,9 +51,11 @@ dependencies:
|
|
46
51
|
name: activerecord
|
47
52
|
prerelease: false
|
48
53
|
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
49
55
|
requirements:
|
50
56
|
- - ">="
|
51
57
|
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
52
59
|
segments:
|
53
60
|
- 0
|
54
61
|
version: "0"
|
@@ -58,9 +65,11 @@ dependencies:
|
|
58
65
|
name: sqlite3-ruby
|
59
66
|
prerelease: false
|
60
67
|
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
61
69
|
requirements:
|
62
70
|
- - ">="
|
63
71
|
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
64
73
|
segments:
|
65
74
|
- 0
|
66
75
|
version: "0"
|
@@ -70,9 +79,11 @@ dependencies:
|
|
70
79
|
name: git
|
71
80
|
prerelease: false
|
72
81
|
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
73
83
|
requirements:
|
74
84
|
- - ">="
|
75
85
|
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
76
87
|
segments:
|
77
88
|
- 0
|
78
89
|
version: "0"
|
@@ -82,9 +93,11 @@ dependencies:
|
|
82
93
|
name: gemcutter
|
83
94
|
prerelease: false
|
84
95
|
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
85
97
|
requirements:
|
86
98
|
- - ">="
|
87
99
|
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
88
101
|
segments:
|
89
102
|
- 0
|
90
103
|
version: "0"
|
@@ -101,142 +114,144 @@ extensions: []
|
|
101
114
|
extra_rdoc_files:
|
102
115
|
- README.rdoc
|
103
116
|
files:
|
104
|
-
-
|
105
|
-
-
|
106
|
-
-
|
107
|
-
- lib/request_log_analyzer/output/fancy_html.rb
|
117
|
+
- .gitignore
|
118
|
+
- DESIGN.rdoc
|
119
|
+
- LICENSE
|
108
120
|
- README.rdoc
|
121
|
+
- Rakefile
|
122
|
+
- bin/request-log-analyzer
|
123
|
+
- lib/cli/command_line_arguments.rb
|
124
|
+
- lib/cli/database_console.rb
|
125
|
+
- lib/cli/database_console_init.rb
|
109
126
|
- lib/cli/progressbar.rb
|
110
|
-
-
|
111
|
-
- lib/request_log_analyzer/file_format/rails_development.rb
|
112
|
-
- spec/fixtures/rails_22.log
|
113
|
-
- spec/unit/file_format/delayed_job2_format_spec.rb
|
114
|
-
- spec/fixtures/test_order.log
|
115
|
-
- spec/fixtures/header_and_footer.log
|
127
|
+
- lib/cli/tools.rb
|
116
128
|
- lib/mixins/gets_memory_protection.rb
|
117
|
-
-
|
118
|
-
-
|
119
|
-
- lib/request_log_analyzer/
|
120
|
-
- lib/request_log_analyzer/
|
121
|
-
- lib/request_log_analyzer/
|
122
|
-
-
|
123
|
-
-
|
124
|
-
- spec/unit/filter/filter_spec.rb
|
125
|
-
- spec/unit/aggregator/summarizer_spec.rb
|
126
|
-
- lib/request_log_analyzer/file_format/rails.rb
|
127
|
-
- spec/database.yml
|
128
|
-
- spec/unit/tracker/numeric_value_tracker_spec.rb
|
129
|
-
- spec/spec_helper.rb
|
129
|
+
- lib/request_log_analyzer.rb
|
130
|
+
- lib/request_log_analyzer/aggregator.rb
|
131
|
+
- lib/request_log_analyzer/aggregator/database_inserter.rb
|
132
|
+
- lib/request_log_analyzer/aggregator/echo.rb
|
133
|
+
- lib/request_log_analyzer/aggregator/summarizer.rb
|
134
|
+
- lib/request_log_analyzer/controller.rb
|
135
|
+
- lib/request_log_analyzer/database.rb
|
130
136
|
- lib/request_log_analyzer/database/base.rb
|
131
|
-
-
|
132
|
-
-
|
133
|
-
-
|
134
|
-
- spec/fixtures/oink_22.log
|
135
|
-
- spec/fixtures/sinatra.log
|
137
|
+
- lib/request_log_analyzer/database/connection.rb
|
138
|
+
- lib/request_log_analyzer/database/request.rb
|
139
|
+
- lib/request_log_analyzer/database/source.rb
|
136
140
|
- lib/request_log_analyzer/database/warning.rb
|
137
|
-
-
|
138
|
-
-
|
139
|
-
- lib/request_log_analyzer/
|
140
|
-
- spec/fixtures/rails_22_cached.log
|
141
|
-
- lib/request_log_analyzer/tracker/traffic.rb
|
142
|
-
- spec/unit/file_format/format_autodetection_spec.rb
|
143
|
-
- lib/request_log_analyzer/filter/field.rb
|
141
|
+
- lib/request_log_analyzer/file_format.rb
|
142
|
+
- lib/request_log_analyzer/file_format/amazon_s3.rb
|
143
|
+
- lib/request_log_analyzer/file_format/apache.rb
|
144
144
|
- lib/request_log_analyzer/file_format/delayed_job.rb
|
145
|
+
- lib/request_log_analyzer/file_format/delayed_job2.rb
|
146
|
+
- lib/request_log_analyzer/file_format/delayed_job21.rb
|
145
147
|
- lib/request_log_analyzer/file_format/merb.rb
|
148
|
+
- lib/request_log_analyzer/file_format/mysql.rb
|
146
149
|
- lib/request_log_analyzer/file_format/oink.rb
|
150
|
+
- lib/request_log_analyzer/file_format/postgresql.rb
|
151
|
+
- lib/request_log_analyzer/file_format/rack.rb
|
152
|
+
- lib/request_log_analyzer/file_format/rails.rb
|
153
|
+
- lib/request_log_analyzer/file_format/rails3.rb
|
154
|
+
- lib/request_log_analyzer/file_format/rails_development.rb
|
155
|
+
- lib/request_log_analyzer/filter.rb
|
147
156
|
- lib/request_log_analyzer/filter/anonymize.rb
|
148
|
-
- lib/request_log_analyzer/
|
149
|
-
-
|
150
|
-
- lib/request_log_analyzer/file_format.rb
|
151
|
-
- lib/cli/database_console.rb
|
152
|
-
- spec/integration/mailer_spec.rb
|
153
|
-
- spec/fixtures/merb.log
|
157
|
+
- lib/request_log_analyzer/filter/field.rb
|
158
|
+
- lib/request_log_analyzer/filter/timespan.rb
|
154
159
|
- lib/request_log_analyzer/line_definition.rb
|
155
|
-
- spec/unit/tracker/frequency_tracker_spec.rb
|
156
|
-
- spec/unit/mailer_spec.rb
|
157
|
-
- spec/fixtures/postgresql.log
|
158
|
-
- spec/lib/mocks.rb
|
159
|
-
- lib/request_log_analyzer/tracker/hourly_spread.rb
|
160
|
-
- spec/unit/file_format/rails3_format_spec.rb
|
161
|
-
- spec/fixtures/syslog_1x.log
|
162
|
-
- lib/request_log_analyzer/source.rb
|
163
|
-
- lib/request_log_analyzer/file_format/rails3.rb
|
164
|
-
- spec/unit/controller/log_processor_spec.rb
|
165
|
-
- spec/unit/tracker/hourly_spread_spec.rb
|
166
|
-
- spec/unit/filter/field_filter_spec.rb
|
167
|
-
- DESIGN.rdoc
|
168
160
|
- lib/request_log_analyzer/log_processor.rb
|
169
|
-
-
|
170
|
-
-
|
171
|
-
-
|
172
|
-
- spec/unit/database/base_class_spec.rb
|
173
|
-
- lib/request_log_analyzer/aggregator/database_inserter.rb
|
174
|
-
- lib/request_log_analyzer/database/connection.rb
|
175
|
-
- lib/request_log_analyzer/aggregator.rb
|
176
|
-
- lib/request_log_analyzer/database.rb
|
177
|
-
- spec/unit/file_format/rails_format_spec.rb
|
178
|
-
- lib/request_log_analyzer/source/database_loader.rb
|
161
|
+
- lib/request_log_analyzer/mailer.rb
|
162
|
+
- lib/request_log_analyzer/output.rb
|
163
|
+
- lib/request_log_analyzer/output/fancy_html.rb
|
179
164
|
- lib/request_log_analyzer/output/fixed_width.rb
|
180
|
-
- spec/integration/command_line_usage_spec.rb
|
181
|
-
- tasks/request_log_analyzer.rake
|
182
|
-
- lib/request_log_analyzer/tracker/duration.rb
|
183
|
-
- spec/fixtures/test_language_combined.log
|
184
|
-
- bin/request-log-analyzer
|
185
|
-
- lib/request_log_analyzer/tracker.rb
|
186
|
-
- tasks/github-gem.rake
|
187
|
-
- lib/cli/command_line_arguments.rb
|
188
|
-
- lib/request_log_analyzer.rb
|
189
|
-
- .gitignore
|
190
165
|
- lib/request_log_analyzer/output/html.rb
|
191
|
-
- lib/request_log_analyzer/
|
192
|
-
- lib/
|
193
|
-
- lib/request_log_analyzer/
|
194
|
-
-
|
195
|
-
- lib/request_log_analyzer/
|
196
|
-
-
|
197
|
-
- spec/unit/tracker/duration_tracker_spec.rb
|
198
|
-
- spec/fixtures/test_file_format.log
|
199
|
-
- lib/request_log_analyzer/aggregator/summarizer.rb
|
200
|
-
- spec/fixtures/oink_22_failure.log
|
201
|
-
- spec/unit/filter/timespan_filter_spec.rb
|
202
|
-
- spec/unit/file_format/common_regular_expressions_spec.rb
|
203
|
-
- spec/unit/file_format/merb_format_spec.rb
|
204
|
-
- spec/unit/file_format/file_format_api_spec.rb
|
205
|
-
- lib/request_log_analyzer/file_format/delayed_job2.rb
|
206
|
-
- spec/unit/file_format/rack_format_spec.rb
|
207
|
-
- spec/unit/file_format/mysql_format_spec.rb
|
208
|
-
- lib/request_log_analyzer/file_format/mysql.rb
|
209
|
-
- spec/fixtures/decompression.log.gz
|
166
|
+
- lib/request_log_analyzer/request.rb
|
167
|
+
- lib/request_log_analyzer/source.rb
|
168
|
+
- lib/request_log_analyzer/source/database_loader.rb
|
169
|
+
- lib/request_log_analyzer/source/log_parser.rb
|
170
|
+
- lib/request_log_analyzer/tracker.rb
|
171
|
+
- lib/request_log_analyzer/tracker/duration.rb
|
210
172
|
- lib/request_log_analyzer/tracker/frequency.rb
|
173
|
+
- lib/request_log_analyzer/tracker/hourly_spread.rb
|
174
|
+
- lib/request_log_analyzer/tracker/numeric_value.rb
|
175
|
+
- lib/request_log_analyzer/tracker/timespan.rb
|
176
|
+
- lib/request_log_analyzer/tracker/traffic.rb
|
211
177
|
- request-log-analyzer.gemspec
|
178
|
+
- spec/database.yml
|
179
|
+
- spec/fixtures/apache_combined.log
|
212
180
|
- spec/fixtures/apache_common.log
|
213
|
-
-
|
214
|
-
- spec/
|
215
|
-
-
|
216
|
-
- lib/request_log_analyzer/tracker/timespan.rb
|
217
|
-
- spec/lib/macros.rb
|
218
|
-
- spec/integration/scout_spec.rb
|
219
|
-
- spec/unit/controller/controller_spec.rb
|
220
|
-
- lib/request_log_analyzer/mailer.rb
|
221
|
-
- lib/cli/tools.rb
|
222
|
-
- spec/unit/tracker/timespan_tracker_spec.rb
|
223
|
-
- spec/lib/testing_format.rb
|
224
|
-
- spec/lib/matchers.rb
|
225
|
-
- lib/request_log_analyzer/controller.rb
|
226
|
-
- spec/unit/tracker/tracker_api_spec.rb
|
227
|
-
- lib/request_log_analyzer/request.rb
|
228
|
-
- spec/unit/file_format/oink_format_spec.rb
|
229
|
-
- spec/fixtures/multiple_files_2.log
|
230
|
-
- spec/unit/database/database_spec.rb
|
181
|
+
- spec/fixtures/decompression.log
|
182
|
+
- spec/fixtures/decompression.log.bz2
|
183
|
+
- spec/fixtures/decompression.log.gz
|
231
184
|
- spec/fixtures/decompression.log.zip
|
185
|
+
- spec/fixtures/decompression.tar.gz
|
232
186
|
- spec/fixtures/decompression.tgz
|
233
|
-
-
|
234
|
-
- spec/
|
187
|
+
- spec/fixtures/header_and_footer.log
|
188
|
+
- spec/fixtures/merb.log
|
189
|
+
- spec/fixtures/merb_prefixed.log
|
190
|
+
- spec/fixtures/multiple_files_1.log
|
191
|
+
- spec/fixtures/multiple_files_2.log
|
235
192
|
- spec/fixtures/mysql_slow_query.log
|
193
|
+
- spec/fixtures/oink_22.log
|
194
|
+
- spec/fixtures/oink_22_failure.log
|
195
|
+
- spec/fixtures/postgresql.log
|
196
|
+
- spec/fixtures/rails.db
|
197
|
+
- spec/fixtures/rails_1x.log
|
198
|
+
- spec/fixtures/rails_22.log
|
199
|
+
- spec/fixtures/rails_22_cached.log
|
200
|
+
- spec/fixtures/rails_unordered.log
|
201
|
+
- spec/fixtures/sinatra.log
|
202
|
+
- spec/fixtures/syslog_1x.log
|
203
|
+
- spec/fixtures/test_file_format.log
|
204
|
+
- spec/fixtures/test_language_combined.log
|
205
|
+
- spec/fixtures/test_order.log
|
206
|
+
- spec/integration/command_line_usage_spec.rb
|
207
|
+
- spec/integration/mailer_spec.rb
|
208
|
+
- spec/integration/munin_plugins_rails_spec.rb
|
209
|
+
- spec/integration/scout_spec.rb
|
236
210
|
- spec/lib/helpers.rb
|
237
|
-
- lib/
|
238
|
-
- lib/
|
211
|
+
- spec/lib/macros.rb
|
212
|
+
- spec/lib/matchers.rb
|
213
|
+
- spec/lib/mocks.rb
|
214
|
+
- spec/lib/testing_format.rb
|
215
|
+
- spec/spec_helper.rb
|
216
|
+
- spec/unit/aggregator/database_inserter_spec.rb
|
217
|
+
- spec/unit/aggregator/summarizer_spec.rb
|
218
|
+
- spec/unit/controller/controller_spec.rb
|
219
|
+
- spec/unit/controller/log_processor_spec.rb
|
220
|
+
- spec/unit/database/base_class_spec.rb
|
221
|
+
- spec/unit/database/connection_spec.rb
|
222
|
+
- spec/unit/database/database_spec.rb
|
223
|
+
- spec/unit/file_format/amazon_s3_format_spec.rb
|
239
224
|
- spec/unit/file_format/apache_format_spec.rb
|
225
|
+
- spec/unit/file_format/common_regular_expressions_spec.rb
|
226
|
+
- spec/unit/file_format/delayed_job21_format_spec.rb
|
227
|
+
- spec/unit/file_format/delayed_job2_format_spec.rb
|
228
|
+
- spec/unit/file_format/delayed_job_format_spec.rb
|
229
|
+
- spec/unit/file_format/file_format_api_spec.rb
|
230
|
+
- spec/unit/file_format/format_autodetection_spec.rb
|
231
|
+
- spec/unit/file_format/line_definition_spec.rb
|
232
|
+
- spec/unit/file_format/merb_format_spec.rb
|
233
|
+
- spec/unit/file_format/mysql_format_spec.rb
|
234
|
+
- spec/unit/file_format/oink_format_spec.rb
|
235
|
+
- spec/unit/file_format/postgresql_format_spec.rb
|
236
|
+
- spec/unit/file_format/rack_format_spec.rb
|
237
|
+
- spec/unit/file_format/rails3_format_spec.rb
|
238
|
+
- spec/unit/file_format/rails_format_spec.rb
|
239
|
+
- spec/unit/filter/anonymize_filter_spec.rb
|
240
|
+
- spec/unit/filter/field_filter_spec.rb
|
241
|
+
- spec/unit/filter/filter_spec.rb
|
242
|
+
- spec/unit/filter/timespan_filter_spec.rb
|
243
|
+
- spec/unit/mailer_spec.rb
|
244
|
+
- spec/unit/request_spec.rb
|
245
|
+
- spec/unit/source/log_parser_spec.rb
|
246
|
+
- spec/unit/tracker/duration_tracker_spec.rb
|
247
|
+
- spec/unit/tracker/frequency_tracker_spec.rb
|
248
|
+
- spec/unit/tracker/hourly_spread_spec.rb
|
249
|
+
- spec/unit/tracker/numeric_value_tracker_spec.rb
|
250
|
+
- spec/unit/tracker/timespan_tracker_spec.rb
|
251
|
+
- spec/unit/tracker/tracker_api_spec.rb
|
252
|
+
- spec/unit/tracker/traffic_tracker_spec.rb
|
253
|
+
- tasks/github-gem.rake
|
254
|
+
- tasks/request_log_analyzer.rake
|
240
255
|
has_rdoc: true
|
241
256
|
homepage: http://railsdoctors.com
|
242
257
|
licenses: []
|
@@ -252,64 +267,69 @@ rdoc_options:
|
|
252
267
|
require_paths:
|
253
268
|
- lib
|
254
269
|
required_ruby_version: !ruby/object:Gem::Requirement
|
270
|
+
none: false
|
255
271
|
requirements:
|
256
272
|
- - ">="
|
257
273
|
- !ruby/object:Gem::Version
|
274
|
+
hash: 3
|
258
275
|
segments:
|
259
276
|
- 0
|
260
277
|
version: "0"
|
261
278
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
279
|
+
none: false
|
262
280
|
requirements:
|
263
281
|
- - ">="
|
264
282
|
- !ruby/object:Gem::Version
|
283
|
+
hash: 3
|
265
284
|
segments:
|
266
285
|
- 0
|
267
286
|
version: "0"
|
268
287
|
requirements:
|
269
288
|
- To use the database inserter, ActiveRecord and an appropriate database adapter are required.
|
270
289
|
rubyforge_project: r-l-a
|
271
|
-
rubygems_version: 1.3.
|
290
|
+
rubygems_version: 1.3.7
|
272
291
|
signing_key:
|
273
292
|
specification_version: 3
|
274
293
|
summary: A command line tool to analyze request logs for Apache, Rails, Merb, MySQL and other web application servers
|
275
294
|
test_files:
|
276
|
-
- spec/
|
277
|
-
- spec/unit/filter/anonymize_filter_spec.rb
|
278
|
-
- spec/unit/file_format/delayed_job2_format_spec.rb
|
279
|
-
- spec/unit/file_format/line_definition_spec.rb
|
280
|
-
- spec/unit/request_spec.rb
|
281
|
-
- spec/unit/filter/filter_spec.rb
|
282
|
-
- spec/unit/aggregator/summarizer_spec.rb
|
283
|
-
- spec/unit/tracker/numeric_value_tracker_spec.rb
|
284
|
-
- spec/unit/aggregator/database_inserter_spec.rb
|
285
|
-
- spec/unit/database/connection_spec.rb
|
286
|
-
- spec/unit/file_format/postgresql_format_spec.rb
|
287
|
-
- spec/unit/file_format/format_autodetection_spec.rb
|
295
|
+
- spec/integration/command_line_usage_spec.rb
|
288
296
|
- spec/integration/mailer_spec.rb
|
289
|
-
- spec/
|
290
|
-
- spec/
|
291
|
-
- spec/unit/
|
297
|
+
- spec/integration/munin_plugins_rails_spec.rb
|
298
|
+
- spec/integration/scout_spec.rb
|
299
|
+
- spec/unit/aggregator/database_inserter_spec.rb
|
300
|
+
- spec/unit/aggregator/summarizer_spec.rb
|
301
|
+
- spec/unit/controller/controller_spec.rb
|
292
302
|
- spec/unit/controller/log_processor_spec.rb
|
293
|
-
- spec/unit/tracker/hourly_spread_spec.rb
|
294
|
-
- spec/unit/filter/field_filter_spec.rb
|
295
|
-
- spec/unit/source/log_parser_spec.rb
|
296
303
|
- spec/unit/database/base_class_spec.rb
|
297
|
-
- spec/unit/
|
298
|
-
- spec/
|
304
|
+
- spec/unit/database/connection_spec.rb
|
305
|
+
- spec/unit/database/database_spec.rb
|
299
306
|
- spec/unit/file_format/amazon_s3_format_spec.rb
|
300
|
-
- spec/unit/
|
301
|
-
- spec/unit/filter/timespan_filter_spec.rb
|
307
|
+
- spec/unit/file_format/apache_format_spec.rb
|
302
308
|
- spec/unit/file_format/common_regular_expressions_spec.rb
|
303
|
-
- spec/unit/file_format/
|
309
|
+
- spec/unit/file_format/delayed_job21_format_spec.rb
|
310
|
+
- spec/unit/file_format/delayed_job2_format_spec.rb
|
311
|
+
- spec/unit/file_format/delayed_job_format_spec.rb
|
304
312
|
- spec/unit/file_format/file_format_api_spec.rb
|
305
|
-
- spec/unit/file_format/
|
313
|
+
- spec/unit/file_format/format_autodetection_spec.rb
|
314
|
+
- spec/unit/file_format/line_definition_spec.rb
|
315
|
+
- spec/unit/file_format/merb_format_spec.rb
|
306
316
|
- spec/unit/file_format/mysql_format_spec.rb
|
307
|
-
- spec/unit/
|
308
|
-
- spec/
|
309
|
-
- spec/unit/
|
317
|
+
- spec/unit/file_format/oink_format_spec.rb
|
318
|
+
- spec/unit/file_format/postgresql_format_spec.rb
|
319
|
+
- spec/unit/file_format/rack_format_spec.rb
|
320
|
+
- spec/unit/file_format/rails3_format_spec.rb
|
321
|
+
- spec/unit/file_format/rails_format_spec.rb
|
322
|
+
- spec/unit/filter/anonymize_filter_spec.rb
|
323
|
+
- spec/unit/filter/field_filter_spec.rb
|
324
|
+
- spec/unit/filter/filter_spec.rb
|
325
|
+
- spec/unit/filter/timespan_filter_spec.rb
|
326
|
+
- spec/unit/mailer_spec.rb
|
327
|
+
- spec/unit/request_spec.rb
|
328
|
+
- spec/unit/source/log_parser_spec.rb
|
329
|
+
- spec/unit/tracker/duration_tracker_spec.rb
|
330
|
+
- spec/unit/tracker/frequency_tracker_spec.rb
|
331
|
+
- spec/unit/tracker/hourly_spread_spec.rb
|
332
|
+
- spec/unit/tracker/numeric_value_tracker_spec.rb
|
310
333
|
- spec/unit/tracker/timespan_tracker_spec.rb
|
311
334
|
- spec/unit/tracker/tracker_api_spec.rb
|
312
|
-
- spec/unit/
|
313
|
-
- spec/unit/database/database_spec.rb
|
314
|
-
- spec/integration/munin_plugins_rails_spec.rb
|
315
|
-
- spec/unit/file_format/apache_format_spec.rb
|
335
|
+
- spec/unit/tracker/traffic_tracker_spec.rb
|