ringbarker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-09-12
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
@@ -0,0 +1,11 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/ringbarker
6
+ lib/ringbarker.rb
7
+ lib/ringbarker/parser.rb
8
+ lib/ringbarker/entry.rb
9
+ spec/entry_spec.rb
10
+ spec/parser_spec.rb
11
+ spec/spec_helper.rb
@@ -0,0 +1,62 @@
1
+ ringbarker
2
+ by Lachie Cox
3
+ http://blog.smartbomb.com.au
4
+
5
+ == DESCRIPTION:
6
+
7
+ A simple parser for Rails logs.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Parses the Rails log.
12
+ * Recognises Processing...Completed blocks.
13
+ * Recognises Processing...exception...Rendering rescue blocks.
14
+ * Collects the fluff between Processing blocks too.
15
+ * Does as little interpretation of the parsed requests as possible. This is left up to the client.
16
+ * Needs better doco.
17
+
18
+ == SYNOPSIS:
19
+
20
+ require 'rubygems'
21
+ require 'ringbarker'
22
+
23
+ @parser = Ringbarker::Parser.new
24
+ @entries = []
25
+
26
+ @log_lines.each do |line|
27
+ @parser << line
28
+ @parser.dequeue.each {|entry| @entries << entry}
29
+ end
30
+
31
+ == REQUIREMENTS:
32
+
33
+ * None
34
+
35
+ == INSTALL:
36
+
37
+ * sudo gem install ringbarker
38
+
39
+ == LICENSE:
40
+
41
+ (The MIT License)
42
+
43
+ Copyright (c) 2007 Lachie Cox
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining
46
+ a copy of this software and associated documentation files (the
47
+ 'Software'), to deal in the Software without restriction, including
48
+ without limitation the rights to use, copy, modify, merge, publish,
49
+ distribute, sublicense, and/or sell copies of the Software, and to
50
+ permit persons to whom the Software is furnished to do so, subject to
51
+ the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be
54
+ included in all copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
57
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
58
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
59
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
60
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
61
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
62
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require 'spec'
6
+ require 'spec/rake/spectask'
7
+ require './lib/ringbarker.rb'
8
+
9
+ Hoe.new('ringbarker', Ringbarker::VERSION) do |p|
10
+ p.rubyforge_name = 'rails-oceania'
11
+ p.author = 'Lachie Cox'
12
+ p.email = 'lachie@smartbomb.com.au'
13
+ p.summary = 'simple Rails log parser'
14
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
15
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
16
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
17
+
18
+ p.test_globs = ["spec/**/*_spec.rb"]
19
+ end
20
+
21
+
22
+ class Hoe
23
+ def run_testsx(multi=false)
24
+
25
+ end
26
+ end
27
+
28
+
29
+ desc "Run the specs under spec"
30
+ Spec::Rake::SpecTask.new do |t|
31
+ t.spec_opts = ['--options', "spec/spec.opts"]
32
+ t.spec_files = FileList['spec/*_spec.rb']
33
+ end
34
+
35
+ # vim: syntax=Ruby
File without changes
@@ -0,0 +1,6 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'ringbarker/parser'
3
+
4
+ module Ringbarker
5
+ VERSION = '0.0.1'
6
+ end
@@ -0,0 +1,98 @@
1
+
2
+
3
+ module Ringbarker
4
+ module StringHelpers
5
+ def starts_with?(prefix)
6
+ to_s[0..(prefix.to_s.length - 1)] == prefix.to_s
7
+ end
8
+ end
9
+ end
10
+
11
+ class String
12
+ include Ringbarker::StringHelpers
13
+ end
14
+
15
+
16
+ class Ringbarker::Entry
17
+ attr_reader :lines
18
+ attr_reader :controller, :action, :verb, :ip
19
+ attr_reader :session_id, :parameters, :http_code, :complete
20
+ attr_reader :fluff
21
+
22
+ attr_accessor :requested_at
23
+
24
+ def initialize(lines=[],complete=false,fluff=false)
25
+ @lines = lines
26
+ @complete = complete
27
+ @fluff = fluff
28
+ end
29
+
30
+ def self.new_from_fluff(lines,requested_at)
31
+ f = new(lines.dup,true,true)
32
+ f.requested_at = Time.at(requested_at)
33
+ f
34
+ end
35
+
36
+ def << line
37
+ if @lines.empty?
38
+ parse_header(line)
39
+ elsif line.starts_with? 'Completed'
40
+ parse_completed(line)
41
+ elsif line.starts_with? 'Rendering'
42
+ parse_rendering(line)
43
+ end
44
+
45
+ @lines << line
46
+ end
47
+
48
+ def requested_at_seconds
49
+ self.requested_at.to_i
50
+ end
51
+
52
+ def complete?; @complete; end
53
+ def fluff?; @fluff; end
54
+
55
+
56
+ COMPLETED_RE = /(\d+) \w+ \[http:\/\/[^\]]+\]$/
57
+ def parse_completed line
58
+ if m = line.match(COMPLETED_RE)
59
+ @http_code = m[1].to_i
60
+ @complete = true
61
+ end
62
+ end
63
+
64
+ RENDERING_RE = %r{^Rendering.*rescues/layout\.rhtml \((\d+)}
65
+ def parse_rendering line
66
+ if m = line.match(RENDERING_RE)
67
+ @http_code = m[1].to_i
68
+ @complete = true
69
+ end
70
+ end
71
+
72
+ PROCESSING_RE = /^Processing (\w+)\#(\w+) \(for ([\d\.]+) at ([\d-]{10} [\d:]{8})\) \[([A-Z]+)\]/
73
+ def parse_header(line)
74
+ if match = line.match(PROCESSING_RE)
75
+ _,@controller,@action,@ip,requested_at,verb = *match
76
+ @verb = verb.downcase.to_sym
77
+ @requested_at = Time.parse(requested_at)
78
+ end
79
+ end
80
+
81
+ SESSION_ID_RE = /\s+Session ID: ([a-zA-Z\d]+)/
82
+ PARAMS_RE = /^\s+Parameters: (.*)$/
83
+
84
+ def parse_details line
85
+ case line
86
+ when SESSION_ID_RE then set_session_id(*$~)
87
+ when PARAMS_RE then set_params(*$~)
88
+ end
89
+ end
90
+
91
+ def set_session_id(_,id)
92
+ @session_id = id
93
+ end
94
+
95
+ def set_params(_,params)
96
+ @parameters = params
97
+ end
98
+ end
@@ -0,0 +1,56 @@
1
+ require 'ringbarker/entry'
2
+
3
+ module Ringbarker
4
+ class Parser
5
+ attr_reader :entries
6
+
7
+ def initialize
8
+ @entries = []
9
+ @fluff = []
10
+ @last_time = 0
11
+ @current_entry = false
12
+ end
13
+
14
+ def <<(line)
15
+ if line[/^Processing/]
16
+ collect_fluff
17
+
18
+ @entries << @current_entry = Entry.new
19
+ elsif !@current_entry && !line.strip.empty?
20
+ @fluff << line
21
+ end
22
+
23
+ @current_entry << line if @current_entry
24
+ end
25
+
26
+ def collect_fluff
27
+ return if @fluff.empty?
28
+ @entries << Entry.new_from_fluff(@fluff,@last_time)
29
+ @fluff = []
30
+ end
31
+
32
+ def cleanup_dequeue
33
+ collect_fluff unless @current_entry
34
+ dequeue
35
+ end
36
+
37
+ def dequeue
38
+ deq = if @entries.empty?
39
+ []
40
+ elsif @entries.last.complete?
41
+ deq = @entries.dup
42
+ @entries = []
43
+ @current_entry = nil
44
+ deq
45
+ else
46
+ deq = @entries[0..-2]
47
+ @entries = @entries[-1..-1]
48
+ deq
49
+ end
50
+
51
+ @last_time = deq.last.requested_at_seconds unless deq.empty?
52
+
53
+ deq
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,136 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Ringbarker::Entry, "parsing the header" do
4
+ before do
5
+ @entry = Ringbarker::Entry.new
6
+ @entry.parse_header('Processing LogeyeController#index (for 127.0.0.1 at 2007-09-07 17:52:13) [GET]')
7
+ end
8
+
9
+ it "should have controller" do
10
+ @entry.controller.should == 'LogeyeController'
11
+ end
12
+
13
+ it "should have action" do
14
+ @entry.action.should == 'index'
15
+ end
16
+
17
+ it "should have ip" do
18
+ @entry.ip.should == '127.0.0.1'
19
+ end
20
+
21
+ it "should have verb" do
22
+ @entry.verb.should == :get
23
+ end
24
+
25
+ it "should have reqested_at" do
26
+ @entry.requested_at.should == Time.at(1189151533)
27
+ end
28
+
29
+ it "should have requested_at_seconds" do
30
+ @entry.requested_at_seconds.should == 1189151533
31
+ end
32
+
33
+ it "should not be complete" do
34
+ @entry.should_not be_complete
35
+ end
36
+ end
37
+
38
+ describe Ringbarker::Entry, "created from fluff" do
39
+ before do
40
+ fluff = [
41
+ "fluff 1",
42
+ "fluff 2"
43
+ ]
44
+ @entry = Ringbarker::Entry.new_from_fluff fluff, 0
45
+ end
46
+
47
+ it "should have 2 lines" do
48
+ @entry.should have(2).lines
49
+ end
50
+
51
+ it "should be complete" do
52
+ @entry.should be_complete
53
+ end
54
+ end
55
+
56
+ describe Ringbarker::Entry, "parsing a session id line" do
57
+ before do
58
+ @entry = Ringbarker::Entry.new
59
+ @entry.parse_details ' Session ID: c8a758cf873b429aaf06c4b8832ce241'
60
+ end
61
+
62
+ it "should have session_id" do
63
+ @entry.session_id.should == 'c8a758cf873b429aaf06c4b8832ce241'
64
+ end
65
+ end
66
+
67
+ describe Ringbarker::Entry, "parsing a parameters line" do
68
+ before do
69
+ @entry = Ringbarker::Entry.new
70
+ @entry.parse_details ' Parameters: {"action"=>"index", "controller"=>"logeye"}'
71
+ end
72
+
73
+ it "should have parameters" do
74
+ @entry.parameters.should == '{"action"=>"index", "controller"=>"logeye"}'
75
+ end
76
+ end
77
+
78
+ describe Ringbarker::Entry, "parsing a completed line" do
79
+ before do
80
+ @entry = Ringbarker::Entry.new
81
+ @entry.parse_completed 'Completed in 0.00119 (841 reqs/sec) | Rendering: 0.00004 (3%) | 200 OK [http://0.0.0.0/logeye]'
82
+ end
83
+
84
+ it "should have http code" do
85
+ @entry.http_code.should == 200
86
+ end
87
+
88
+ it "should be complete" do
89
+ @entry.should be_complete
90
+ end
91
+ end
92
+
93
+ describe Ringbarker::Entry, "parsing a line beginning with completed" do
94
+ before do
95
+ @entry = Ringbarker::Entry.new
96
+ @entry.parse_completed 'Completed n00by d00beez'
97
+ end
98
+
99
+ it "should not have http code" do
100
+ @entry.http_code.should be_nil
101
+ end
102
+
103
+ it "should not be complete" do
104
+ @entry.should_not be_complete
105
+ end
106
+ end
107
+
108
+ describe Ringbarker::Entry, "parsing a Rendered rescue line" do
109
+ before do
110
+ @entry = Ringbarker::Entry.new
111
+ @entry.parse_rendering 'Rendering /opt/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/templates/rescues/layout.rhtml (404 Page Not Found)'
112
+ end
113
+
114
+ it "should should have http code" do
115
+ @entry.http_code.should == 404
116
+ end
117
+
118
+ it "should be complete" do
119
+ @entry.should be_complete
120
+ end
121
+ end
122
+
123
+ describe Ringbarker::Entry, "parsing a normal Rendered line" do
124
+ before do
125
+ @entry = Ringbarker::Entry.new
126
+ @entry.parse_rendering 'Rendering widgets/show'
127
+ end
128
+
129
+ it "should should not have http code" do
130
+ @entry.http_code.should be_nil
131
+ end
132
+
133
+ it "should not be complete" do
134
+ @entry.should_not be_complete
135
+ end
136
+ end
@@ -0,0 +1,112 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+
4
+ describe Ringbarker do
5
+ before do
6
+ @parser = Ringbarker::Parser.new
7
+ end
8
+
9
+ it "should have no entries" do
10
+ @parser.should have(0).entries
11
+ end
12
+ end
13
+
14
+ describe Ringbarker, "with one request" do
15
+ before do
16
+ @parser = Ringbarker::Parser.new
17
+ @lines = [
18
+ 'guffle',
19
+ '',
20
+ 'Processing LogeyeController#index (for 127.0.0.1 at 2007-09-07 17:41:49) [GET]',
21
+ ' Session ID: c8a758cf873b429aaf06c4b8832ce241',
22
+ ' Parameters: {"action"=>"index", "controller"=>"logeye"}',
23
+ '',
24
+ ''
25
+ ]
26
+
27
+ @lines.each {|line| @parser << line}
28
+ end
29
+
30
+
31
+ it "should have two entry" do
32
+ @parser.should have(2).entries
33
+ end
34
+
35
+ it "should have fluff lines as first line" do
36
+ @parser.entries.first.lines.first.should == 'guffle'
37
+ end
38
+
39
+ it "should have fluff as first line" do
40
+ @parser.entries.first.should be_fluff
41
+ end
42
+
43
+ it "should have processing line as first in first entry" do
44
+ @parser.entries.last.lines.first.should == 'Processing LogeyeController#index (for 127.0.0.1 at 2007-09-07 17:41:49) [GET]'
45
+ end
46
+
47
+ it "should have two entry until next Processing line" do
48
+ @parser << "another line"
49
+ @parser.should have(2).entries
50
+ end
51
+
52
+ it "should have three entries after second Processing line" do
53
+ @parser << "another line"
54
+ @parser << ''
55
+ @parser << "Processing LogeyeController#index (for 127.0.0.1 at 2007-09-07 17:52:13) [GET]"
56
+ @parser.should have(3).entries
57
+ end
58
+
59
+ it "should still have three entries after second Processing line and more lines" do
60
+ @parser << "another line"
61
+ @parser << ''
62
+ @parser << "Processing LogeyeController#index (for 127.0.0.1 at 2007-09-07 17:52:13) [GET]"
63
+ @parser << 'some more'
64
+ @parser.should have(3).entries
65
+ end
66
+ end
67
+
68
+ describe Ringbarker, "with 3 entries, after dequeuing" do
69
+ before do
70
+ @parser = Ringbarker::Parser.new
71
+ @parser.entries << @e1 = Ringbarker::Entry.new
72
+ @parser.entries << @e2 = Ringbarker::Entry.new
73
+ @parser.entries << @e3 = Ringbarker::Entry.new
74
+
75
+ @e1.instance_variable_set("@complete",true)
76
+ @e2.instance_variable_set("@complete",true)
77
+
78
+ @deq = @parser.dequeue
79
+ end
80
+
81
+ it "should should have dequeued 2 entries" do
82
+ @deq.should == [@e1,@e2]
83
+ end
84
+
85
+ it "should not dequeue more" do
86
+ @parser.dequeue.should == []
87
+ end
88
+
89
+ it "should have 1 entry" do
90
+ @parser.entries.should == [@e3]
91
+ end
92
+
93
+ it "should dequeue last entry upon completion" do
94
+ @e3.instance_variable_set("@complete",true)
95
+ @parser.dequeue.should == [@e3]
96
+ end
97
+ end
98
+
99
+ describe Ringbarker, "with no entries, after dequeuing" do
100
+ before do
101
+ @parser = Ringbarker::Parser.new
102
+ @deq = @parser.dequeue
103
+ end
104
+
105
+ it "should dequeue nothing" do
106
+ @deq.should == []
107
+ end
108
+
109
+ it "should have empty array of entries" do
110
+ @parser.entries.should == []
111
+ end
112
+ end
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ require File.dirname(__FILE__)+'/../lib/ringbarker'
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: ringbarker
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-09-19 00:00:00 +10:00
8
+ summary: simple Rails log parser
9
+ require_paths:
10
+ - lib
11
+ email: lachie@smartbomb.com.au
12
+ homepage: " by Lachie Cox"
13
+ rubyforge_project: rails-oceania
14
+ description: "== FEATURES/PROBLEMS: * Parses the Rails log. * Recognises Processing...Completed blocks. * Recognises Processing...exception...Rendering rescue blocks. * Collects the fluff between Processing blocks too. * Does as little interpretation of the parsed requests as possible. This is left up to the client. * Needs better doco. == SYNOPSIS: require 'rubygems' require 'ringbarker' @parser = Ringbarker::Parser.new @entries = []"
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Lachie Cox
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - bin/ringbarker
37
+ - lib/ringbarker.rb
38
+ - lib/ringbarker/parser.rb
39
+ - lib/ringbarker/entry.rb
40
+ - spec/entry_spec.rb
41
+ - spec/parser_spec.rb
42
+ - spec/spec_helper.rb
43
+ test_files:
44
+ - spec/entry_spec.rb
45
+ - spec/parser_spec.rb
46
+ rdoc_options:
47
+ - --main
48
+ - README.txt
49
+ extra_rdoc_files:
50
+ - History.txt
51
+ - Manifest.txt
52
+ - README.txt
53
+ executables:
54
+ - ringbarker
55
+ extensions: []
56
+
57
+ requirements: []
58
+
59
+ dependencies:
60
+ - !ruby/object:Gem::Dependency
61
+ name: hoe
62
+ version_requirement:
63
+ version_requirements: !ruby/object:Gem::Version::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 1.3.0
68
+ version: