ringbarker 0.0.1

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.
@@ -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: