request-log-analyzer 1.7.0 → 1.10.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/.gitignore +4 -1
- data/DESIGN.rdoc +0 -1
- data/Gemfile +2 -0
- data/README.rdoc +16 -5
- data/bin/request-log-analyzer +4 -2
- data/lib/cli/database_console_init.rb +1 -1
- data/lib/cli/tools.rb +2 -1
- data/lib/mixins/gets_memory_protection.rb +1 -1
- data/lib/request_log_analyzer/aggregator/summarizer.rb +2 -2
- data/lib/request_log_analyzer/aggregator.rb +3 -3
- data/lib/request_log_analyzer/controller.rb +42 -36
- data/lib/request_log_analyzer/database.rb +5 -3
- data/lib/request_log_analyzer/file_format/apache.rb +19 -28
- data/lib/request_log_analyzer/file_format/delayed_job2.rb +38 -0
- data/lib/request_log_analyzer/file_format/delayed_job21.rb +39 -0
- data/lib/request_log_analyzer/file_format/haproxy.rb +138 -0
- data/lib/request_log_analyzer/file_format/oink.rb +96 -0
- data/lib/request_log_analyzer/file_format/postgresql.rb +7 -6
- data/lib/request_log_analyzer/file_format/rails.rb +4 -4
- data/lib/request_log_analyzer/file_format/rails3.rb +34 -11
- data/lib/request_log_analyzer/file_format/w3c.rb +56 -0
- data/lib/request_log_analyzer/file_format.rb +33 -10
- data/lib/request_log_analyzer/filter.rb +3 -5
- data/lib/request_log_analyzer/output/fancy_html.rb +0 -5
- data/lib/request_log_analyzer/output.rb +6 -7
- data/lib/request_log_analyzer/request.rb +17 -3
- data/lib/request_log_analyzer/source/log_parser.rb +3 -1
- data/lib/request_log_analyzer/source.rb +2 -6
- data/lib/request_log_analyzer/tracker/duration.rb +7 -0
- data/lib/request_log_analyzer/tracker/numeric_value.rb +123 -12
- data/lib/request_log_analyzer/tracker/traffic.rb +7 -0
- data/lib/request_log_analyzer/tracker.rb +6 -5
- data/lib/request_log_analyzer.rb +36 -17
- data/request-log-analyzer.gemspec +9 -6
- data/spec/fixtures/oink_22.log +19 -0
- data/spec/fixtures/oink_22_failure.log +17 -0
- data/spec/fixtures/postgresql.log +29 -2980
- data/spec/integration/command_line_usage_spec.rb +4 -4
- data/spec/integration/mailer_spec.rb +20 -4
- data/spec/integration/munin_plugins_rails_spec.rb +1 -1
- data/spec/integration/scout_spec.rb +1 -1
- data/spec/lib/helpers.rb +2 -2
- data/spec/lib/macros.rb +1 -1
- data/spec/lib/matchers.rb +1 -1
- data/spec/lib/mocks.rb +1 -1
- data/spec/spec_helper.rb +10 -10
- data/spec/unit/aggregator/database_inserter_spec.rb +1 -1
- data/spec/unit/aggregator/summarizer_spec.rb +1 -1
- data/spec/unit/controller/controller_spec.rb +1 -1
- data/spec/unit/controller/log_processor_spec.rb +1 -1
- data/spec/unit/database/base_class_spec.rb +1 -1
- data/spec/unit/database/connection_spec.rb +1 -1
- data/spec/unit/database/database_spec.rb +1 -1
- data/spec/unit/file_format/amazon_s3_format_spec.rb +1 -1
- data/spec/unit/file_format/apache_format_spec.rb +18 -1
- data/spec/unit/file_format/common_regular_expressions_spec.rb +1 -1
- data/spec/unit/file_format/delayed_job21_format_spec.rb +60 -0
- data/spec/unit/file_format/delayed_job2_format_spec.rb +60 -0
- data/spec/unit/file_format/delayed_job_format_spec.rb +2 -2
- data/spec/unit/file_format/file_format_api_spec.rb +2 -2
- data/spec/unit/file_format/format_autodetection_spec.rb +7 -7
- data/spec/unit/file_format/haproxy_format_spec.rb +84 -0
- data/spec/unit/file_format/line_definition_spec.rb +1 -1
- data/spec/unit/file_format/merb_format_spec.rb +1 -1
- data/spec/unit/file_format/mysql_format_spec.rb +1 -1
- data/spec/unit/file_format/oink_format_spec.rb +105 -0
- data/spec/unit/file_format/postgresql_format_spec.rb +24 -46
- data/spec/unit/file_format/rack_format_spec.rb +1 -1
- data/spec/unit/file_format/rails3_format_spec.rb +41 -14
- data/spec/unit/file_format/rails_format_spec.rb +11 -1
- data/spec/unit/file_format/w3c_format_spec.rb +46 -0
- data/spec/unit/filter/anonymize_filter_spec.rb +1 -1
- data/spec/unit/filter/field_filter_spec.rb +1 -1
- data/spec/unit/filter/filter_spec.rb +1 -1
- data/spec/unit/filter/timespan_filter_spec.rb +1 -1
- data/spec/unit/mailer_spec.rb +1 -1
- data/spec/unit/request_spec.rb +1 -1
- data/spec/unit/source/log_parser_spec.rb +1 -1
- data/spec/unit/tracker/duration_tracker_spec.rb +4 -2
- data/spec/unit/tracker/frequency_tracker_spec.rb +1 -1
- data/spec/unit/tracker/hourly_spread_spec.rb +1 -1
- data/spec/unit/tracker/numeric_value_tracker_spec.rb +38 -17
- data/spec/unit/tracker/timespan_tracker_spec.rb +1 -1
- data/spec/unit/tracker/tracker_api_spec.rb +1 -1
- data/spec/unit/tracker/traffic_tracker_spec.rb +1 -1
- data/tasks/github-gem.rake +97 -60
- data/tasks/request_log_analyzer.rake +102 -0
- metadata +198 -153
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'
|
|
@@ -68,23 +71,23 @@ module GithubGem
|
|
|
68
71
|
|
|
69
72
|
# Defines RSpec tasks
|
|
70
73
|
def define_rspec_tasks!
|
|
71
|
-
require '
|
|
74
|
+
require 'rspec/core/rake_task'
|
|
72
75
|
|
|
73
76
|
namespace(:spec) do
|
|
74
77
|
desc "Verify all RSpec examples for #{gemspec.name}"
|
|
75
|
-
|
|
76
|
-
t.
|
|
78
|
+
RSpec::Core::RakeTask.new(:basic) do |t|
|
|
79
|
+
t.pattern = spec_pattern
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
|
|
80
|
-
|
|
81
|
-
t.
|
|
82
|
-
t.
|
|
83
|
+
RSpec::Core::RakeTask.new(:specdoc) do |t|
|
|
84
|
+
t.pattern = spec_pattern
|
|
85
|
+
t.rspec_opts = ['--format', 'documentation', '--color']
|
|
83
86
|
end
|
|
84
87
|
|
|
85
88
|
desc "Run RCov on specs for #{gemspec.name}"
|
|
86
|
-
|
|
87
|
-
t.
|
|
89
|
+
RSpec::Core::RakeTask.new(:rcov) do |t|
|
|
90
|
+
t.pattern = spec_pattern
|
|
88
91
|
t.rcov = true
|
|
89
92
|
t.rcov_opts = ['--exclude', '"spec/*,gems/*"', '--rails']
|
|
90
93
|
end
|
|
@@ -127,8 +130,22 @@ module GithubGem
|
|
|
127
130
|
release_tasks = [:release_checks, :set_version, :build, :github_release, :gemcutter_release]
|
|
128
131
|
# release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
|
|
129
132
|
|
|
130
|
-
desc "Release a new
|
|
133
|
+
desc "Release a new version of the gem using the VERSION environment variable"
|
|
131
134
|
task(:release => release_tasks) { release_task }
|
|
135
|
+
|
|
136
|
+
namespace(:release) do
|
|
137
|
+
desc "Release the next version of the gem, by incrementing the last version segment by 1"
|
|
138
|
+
task(:next => [:next_version] + release_tasks) { release_task }
|
|
139
|
+
|
|
140
|
+
desc "Release the next version of the gem, using a patch increment (0.0.1)"
|
|
141
|
+
task(:patch => [:next_patch_version] + release_tasks) { release_task }
|
|
142
|
+
|
|
143
|
+
desc "Release the next version of the gem, using a minor increment (0.1.0)"
|
|
144
|
+
task(:minor => [:next_minor_version] + release_tasks) { release_task }
|
|
145
|
+
|
|
146
|
+
desc "Release the next version of the gem, using a major increment (1.0.0)"
|
|
147
|
+
task(:major => [:next_major_version] + release_tasks) { release_task }
|
|
148
|
+
end
|
|
132
149
|
|
|
133
150
|
# task(:check_rubyforge) { check_rubyforge_task }
|
|
134
151
|
# task(:rubyforge_release) { rubyforge_release_task }
|
|
@@ -137,6 +154,11 @@ module GithubGem
|
|
|
137
154
|
task(:tag_version) { tag_version_task }
|
|
138
155
|
task(:commit_modified_files) { commit_modified_files_task }
|
|
139
156
|
|
|
157
|
+
task(:next_version) { next_version_task }
|
|
158
|
+
task(:next_patch_version) { next_version_task(:patch) }
|
|
159
|
+
task(:next_minor_version) { next_version_task(:minor) }
|
|
160
|
+
task(:next_major_version) { next_version_task(:major) }
|
|
161
|
+
|
|
140
162
|
desc "Updates the gem release tasks with the latest version on Github"
|
|
141
163
|
task(:update_tasks) { update_tasks_task }
|
|
142
164
|
end
|
|
@@ -146,7 +168,7 @@ module GithubGem
|
|
|
146
168
|
# in the repository and the spec/test file pattern.
|
|
147
169
|
def manifest_task
|
|
148
170
|
# Load all the gem's files using "git ls-files"
|
|
149
|
-
repository_files = git
|
|
171
|
+
repository_files = `#{git} ls-files`.split("\n")
|
|
150
172
|
test_files = Dir[test_pattern] + Dir[spec_pattern]
|
|
151
173
|
|
|
152
174
|
update_gemspec(:files, repository_files)
|
|
@@ -160,6 +182,32 @@ module GithubGem
|
|
|
160
182
|
sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
|
161
183
|
end
|
|
162
184
|
|
|
185
|
+
def newest_version
|
|
186
|
+
`#{git} tag`.split("\n").map { |tag| tag.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max || Gem::Version.new('0.0.0')
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def next_version(increment = nil)
|
|
190
|
+
next_version = newest_version.segments
|
|
191
|
+
increment_index = case increment
|
|
192
|
+
when :micro then 3
|
|
193
|
+
when :patch then 2
|
|
194
|
+
when :minor then 1
|
|
195
|
+
when :major then 0
|
|
196
|
+
else next_version.length - 1
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
next_version[increment_index] ||= 0
|
|
200
|
+
next_version[increment_index] = next_version[increment_index].succ
|
|
201
|
+
((increment_index + 1)...next_version.length).each { |i| next_version[i] = 0 }
|
|
202
|
+
|
|
203
|
+
Gem::Version.new(next_version.join('.'))
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def next_version_task(increment = nil)
|
|
207
|
+
ENV['VERSION'] = next_version(increment).version
|
|
208
|
+
puts "Releasing version #{ENV['VERSION']}..."
|
|
209
|
+
end
|
|
210
|
+
|
|
163
211
|
# Updates the version number in the gemspec file, the VERSION constant in the main
|
|
164
212
|
# include file and the contents of the VERSION file.
|
|
165
213
|
def version_task
|
|
@@ -172,74 +220,58 @@ module GithubGem
|
|
|
172
220
|
|
|
173
221
|
def check_version_task
|
|
174
222
|
raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
|
|
175
|
-
proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
|
|
176
|
-
#
|
|
177
|
-
newest_version = git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max
|
|
178
|
-
raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version && newest_version >= proposed_version
|
|
223
|
+
proposed_version = Gem::Version.new((ENV['VERSION'] || gemspec.version).dup)
|
|
224
|
+
raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version >= proposed_version
|
|
179
225
|
end
|
|
180
226
|
|
|
181
227
|
# Checks whether the current branch is not diverged from the remote branch
|
|
182
228
|
def check_not_diverged_task
|
|
183
|
-
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?
|
|
184
230
|
end
|
|
185
231
|
|
|
186
232
|
# Checks whether the repository status ic clean
|
|
187
233
|
def check_clean_status_task
|
|
188
|
-
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?
|
|
189
235
|
end
|
|
190
236
|
|
|
191
237
|
# Checks whether the current branch is correct
|
|
192
238
|
def check_current_branch_task
|
|
193
|
-
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}"
|
|
194
240
|
end
|
|
195
241
|
|
|
196
242
|
# Fetches the latest updates from Github
|
|
197
243
|
def fetch_origin_task
|
|
198
|
-
git
|
|
244
|
+
sh git, 'fetch', remote
|
|
199
245
|
end
|
|
200
246
|
|
|
201
247
|
# Commits every file that has been changed by the release task.
|
|
202
248
|
def commit_modified_files_task
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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}."
|
|
206
253
|
end
|
|
207
254
|
end
|
|
208
255
|
|
|
209
256
|
# Adds a tag for the released version
|
|
210
257
|
def tag_version_task
|
|
211
|
-
git
|
|
258
|
+
sh git, 'tag', '-a', "#{gemspec.name}-#{gemspec.version}", '-m', "Released #{gemspec.name} gem version #{gemspec.version}."
|
|
212
259
|
end
|
|
213
260
|
|
|
214
261
|
# Pushes the changes and tag to github
|
|
215
262
|
def github_release_task
|
|
216
|
-
git
|
|
263
|
+
sh git, 'push', '--tags', remote, remote_branch
|
|
217
264
|
end
|
|
218
265
|
|
|
219
|
-
# # Checks whether Rubyforge is configured properly
|
|
220
|
-
# def check_rubyforge_task
|
|
221
|
-
# # Login no longer necessary when using rubyforge 2.0.0 gem
|
|
222
|
-
# # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
|
|
223
|
-
# output = `rubyforge names`.split("\n")
|
|
224
|
-
# raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
|
|
225
|
-
# raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
|
|
226
|
-
# end
|
|
227
|
-
|
|
228
|
-
# # Task to release the .gem file toRubyforge.
|
|
229
|
-
# def rubyforge_release_task
|
|
230
|
-
# sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
|
231
|
-
# end
|
|
232
|
-
|
|
233
266
|
def gemcutter_release_task
|
|
234
|
-
sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
|
267
|
+
sh "gem", 'push', "pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
|
235
268
|
end
|
|
236
269
|
|
|
237
270
|
# Gem release task.
|
|
238
271
|
# All work is done by the task's dependencies, so just display a release completed message.
|
|
239
272
|
def release_task
|
|
240
273
|
puts
|
|
241
|
-
puts
|
|
242
|
-
puts "Released #{gemspec.name} version #{gemspec.version}"
|
|
274
|
+
puts "Release successful."
|
|
243
275
|
end
|
|
244
276
|
|
|
245
277
|
private
|
|
@@ -299,30 +331,35 @@ module GithubGem
|
|
|
299
331
|
|
|
300
332
|
# Reload the gemspec so the changes are incorporated
|
|
301
333
|
load_gemspec!
|
|
334
|
+
|
|
335
|
+
# Also mark the Gemfile.lock file as changed because of the new version.
|
|
336
|
+
modified_files << 'Gemfile.lock' if File.exist?(File.join(root_dir, 'Gemfile.lock'))
|
|
302
337
|
end
|
|
303
338
|
end
|
|
304
339
|
|
|
305
340
|
# Updates the tasks file using the latest file found on Github
|
|
306
341
|
def update_tasks_task
|
|
307
|
-
require 'net/
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
342
|
+
require 'net/https'
|
|
343
|
+
require 'uri'
|
|
344
|
+
|
|
345
|
+
uri = URI.parse('https://github.com/wvanbergen/github-gem/raw/master/tasks/github-gem.rake')
|
|
346
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
347
|
+
http.use_ssl = true
|
|
348
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
349
|
+
response = http.request(Net::HTTP::Get.new(uri.path))
|
|
350
|
+
|
|
351
|
+
if Net::HTTPSuccess === response
|
|
314
352
|
open(__FILE__, "w") { |file| file.write(response.body) }
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
353
|
+
relative_file = File.expand_path(__FILE__).sub(%r[^#{@root_dir}/], '')
|
|
354
|
+
if `#{git} ls-files -m #{relative_file}`.split("\n").any?
|
|
355
|
+
sh git, 'add', relative_file
|
|
356
|
+
sh git, 'commit', '-m', "Updated to latest gem release management tasks."
|
|
357
|
+
else
|
|
358
|
+
puts "Release managament tasks already are at the latest version."
|
|
359
|
+
end
|
|
322
360
|
else
|
|
323
|
-
|
|
361
|
+
raise "Download failed with HTTP status #{response.code}!"
|
|
324
362
|
end
|
|
325
363
|
end
|
|
326
|
-
|
|
327
364
|
end
|
|
328
365
|
end
|
|
@@ -23,4 +23,106 @@ namespace :rla do
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Split a single logfile into multiple multiple logfiles based on PID information
|
|
27
|
+
# provided in the log lines.
|
|
28
|
+
#
|
|
29
|
+
# Usage:
|
|
30
|
+
# rake rla:split_log FILE=logfile
|
|
31
|
+
#
|
|
32
|
+
# Example:
|
|
33
|
+
# $> rake rla:split_log FILE=log/development.log
|
|
34
|
+
# Splitting the Rails log file by pid using the request-log-analyzer gem.
|
|
35
|
+
#
|
|
36
|
+
# Log file was split into the following files:
|
|
37
|
+
# split_log_development.catchall.log # <- log lines without a pid
|
|
38
|
+
# split_log_development.14634.log
|
|
39
|
+
# split_log_development.31277.log
|
|
40
|
+
# split_log_development.31279.log
|
|
41
|
+
#
|
|
42
|
+
# To analyze type:
|
|
43
|
+
# request-log-analyzer /log/split_log_development.*.log
|
|
44
|
+
desc "Split a logfile into seperate files by PID"
|
|
45
|
+
task :split do
|
|
46
|
+
|
|
47
|
+
if ENV['FILE']
|
|
48
|
+
logfile = ENV['FILE']
|
|
49
|
+
if logfile.nil?
|
|
50
|
+
puts "Please provide a logfile to split"
|
|
51
|
+
exit(0)
|
|
52
|
+
elsif !File.exist?(logfile)
|
|
53
|
+
puts "the logfile name you provided can not be found"
|
|
54
|
+
exit(0)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Inline class def. Ugly, yet portable.
|
|
58
|
+
class LogSplitter
|
|
59
|
+
attr_reader :files_by_pid, :catchall, :filename, :rla_call_string
|
|
60
|
+
|
|
61
|
+
# All generated files should contain this prefix to allow for easy glob file matches
|
|
62
|
+
PREFIX = 'split_log_'
|
|
63
|
+
# The logfile pattern that captures the pid, this will be log format specific. Using Logging::Logger
|
|
64
|
+
# we define: Logging::Layouts::Pattern(:pattern => "%d pid:%p [%c:%l] %m [%F:%L]\n")
|
|
65
|
+
# PID_PATTERN = Regexp.union(/.*\[(\d+)\]\:/, /pid:(\d+)/)
|
|
66
|
+
PID_PATTERN = /(?-mix:.*\[(\d+)\]\:)|(?-mix:pid:(\d+))/ #
|
|
67
|
+
|
|
68
|
+
# Currently expects the filename to exist in the local directory for ease of implementation
|
|
69
|
+
def initialize(filename_to_split)
|
|
70
|
+
@filename = filename_to_split
|
|
71
|
+
directory = File.dirname(@filename) + '/'
|
|
72
|
+
directory = '' if @directory == './'
|
|
73
|
+
basename = @filename.split('/').last.gsub('.log', '')
|
|
74
|
+
@rla_call_string = "#{directory}#{PREFIX}#{basename}.*.log"
|
|
75
|
+
|
|
76
|
+
@files_by_pid =
|
|
77
|
+
Hash.new {|hash, pid_key| hash[pid_key] = File.open("#{directory}#{PREFIX}#{basename}.#{pid_key}.log", 'w') }
|
|
78
|
+
@catchall = File.open("#{directory}#{PREFIX}#{basename}.catchall.log", 'w')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def split
|
|
82
|
+
last_pid = nil
|
|
83
|
+
File.open(filename, 'r') do |f|
|
|
84
|
+
while(line = f.gets)
|
|
85
|
+
outfile =
|
|
86
|
+
if match_data = line.match(PID_PATTERN)
|
|
87
|
+
pid = match_data.captures[0]
|
|
88
|
+
last_pid = pid
|
|
89
|
+
files_by_pid[pid]
|
|
90
|
+
elsif last_pid
|
|
91
|
+
# handle cases where a single log call results in multiple lines of output.
|
|
92
|
+
files_by_pid[last_pid]
|
|
93
|
+
else
|
|
94
|
+
catchall
|
|
95
|
+
end
|
|
96
|
+
outfile.puts line
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def close_files
|
|
102
|
+
@files_by_pid.values.map(&:close)
|
|
103
|
+
@catchall.close
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
# End inline class def
|
|
107
|
+
|
|
108
|
+
puts "Splitting the Rails log file by pid using the request-log-analyzer gem."
|
|
109
|
+
|
|
110
|
+
log_splitter = LogSplitter.new(logfile)
|
|
111
|
+
log_splitter.split
|
|
112
|
+
log_splitter.close_files
|
|
113
|
+
|
|
114
|
+
puts ''
|
|
115
|
+
puts ''
|
|
116
|
+
puts 'Log file was split into the following files:'
|
|
117
|
+
puts ' ' + log_splitter.catchall.path
|
|
118
|
+
log_splitter.files_by_pid.values.each {|f| puts ' ' + f.path }
|
|
119
|
+
puts ''
|
|
120
|
+
puts 'To analyze type:'
|
|
121
|
+
puts " request-log-analyzer #{log_splitter.rla_call_string}"
|
|
122
|
+
puts ''
|
|
123
|
+
puts ''
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
|
|
26
128
|
end
|