kastner-clarity 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/clarity.rb'}"
9
+ puts "Loading clarity gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,99 @@
1
+ require 'test_helper'
2
+
3
+ class GrepCommandBuilderTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @params = {
7
+ "file" => "testfile.log",
8
+ "tool" => "grep",
9
+ "term1" => "foo",
10
+ "term2" => nil,
11
+ "term3" => nil
12
+ }
13
+ @command = GrepCommandBuilder.new(@params)
14
+ end
15
+
16
+ def test_create_new_builder
17
+ assert @command.is_a?(GrepCommandBuilder)
18
+ assert_equal "testfile.log", @command.filename
19
+ assert_equal 1, @command.terms.size
20
+ end
21
+
22
+ def test_raises_error_if_no_file
23
+ assert_raises GrepCommandBuilder::InvalidParameterError do
24
+ command = GrepCommandBuilder.new(@params.merge("file" => nil))
25
+ end
26
+ end
27
+
28
+ def test_exec_functions_for_log
29
+ command = GrepCommandBuilder.new(@params)
30
+ assert_equal 1, command.exec_functions.size
31
+ assert_match(/^grep/, command.exec_functions.first)
32
+ end
33
+
34
+ def test_exec_functions_with_multiple_terms_for_log
35
+ command = GrepCommandBuilder.new(@params.merge("term2" => "bar", "term3" => "baz"))
36
+ assert_equal 3, command.exec_functions.size
37
+ assert_match(/^grep/, command.exec_functions[0])
38
+ assert_match(/^grep/, command.exec_functions[1])
39
+ assert_match(/^grep/, command.exec_functions[2])
40
+ end
41
+
42
+ def test_exec_function_with_no_terms_for_log
43
+ command = GrepCommandBuilder.new(@params.merge("term1" => nil))
44
+ assert_equal 1, command.exec_functions.size
45
+ assert_match(/^cat/, command.exec_functions[0])
46
+ end
47
+
48
+ def test_exec_funcations_for_gzip
49
+ command = GrepCommandBuilder.new(@params.merge("file" => "testfile.gz"))
50
+ assert_equal 1, command.exec_functions.size
51
+ assert_match(/^zgrep/, command.exec_functions.first)
52
+ end
53
+
54
+ def test_exec_functions_with_multiple_terms_for_gzip
55
+ command = GrepCommandBuilder.new(@params.merge("file" => "testfile.gz", "term2" => "bar", "term3" => "baz"))
56
+ assert_equal 3, command.exec_functions.size
57
+ assert_match(/^zgrep/, command.exec_functions[0])
58
+ assert_match(/^grep/, command.exec_functions[1])
59
+ assert_match(/^grep/, command.exec_functions[2])
60
+ end
61
+
62
+ def test_exec_function_with_no_terms_for_gzip
63
+ command = GrepCommandBuilder.new(@params.merge("file" => "testfile.gz", "term1" => nil))
64
+ assert_equal 1, command.exec_functions.size
65
+ assert_match "gzcat", command.exec_functions[0]
66
+ end
67
+
68
+ def test_command_for_log
69
+ command = GrepCommandBuilder.new(@params)
70
+ assert_equal "sh -c 'grep -e foo testfile.log'", command.command
71
+ end
72
+
73
+ def test_command_with_no_terms_for_log
74
+ command = GrepCommandBuilder.new(@params.merge("term1" => nil))
75
+ assert_equal "sh -c 'cat testfile.log'", command.command
76
+ end
77
+
78
+ def test_command_with_multiple_terms_for_log
79
+ command = GrepCommandBuilder.new(@params.merge("term2" => "bar", "term3" => "baz"))
80
+ assert_equal "sh -c 'grep -e foo testfile.log | grep -e bar | grep -e baz'", command.command
81
+ end
82
+
83
+ def test_command_for_gzip
84
+ command = GrepCommandBuilder.new(@params.merge("file" => "testfile.gz"))
85
+ assert_equal "sh -c 'zgrep -e foo testfile.gz'", command.command
86
+ end
87
+
88
+ def test_command_with_no_terms_for_gzip
89
+ command = GrepCommandBuilder.new(@params.merge("file" => "testfile.gz","term1" => nil))
90
+ assert_equal "sh -c 'gzcat testfile.gz'", command.command
91
+ end
92
+
93
+ def test_command_with_multiple_terms_for_gzip
94
+ command = GrepCommandBuilder.new(@params.merge("file" => "testfile.gz","term2" => "bar", "term3" => "baz"))
95
+ assert_equal "sh -c 'zgrep -e foo testfile.gz | grep -e bar | grep -e baz'", command.command
96
+ end
97
+
98
+
99
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class TailCommandBuilderTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @params = {
7
+ "file" => "testfile.log",
8
+ "tool" => "tail",
9
+ "term1" => "foo",
10
+ "term2" => nil,
11
+ "term3" => nil
12
+ }
13
+ @command = TailCommandBuilder.new(@params)
14
+ end
15
+
16
+ def test_create_new_builder
17
+ assert @command.is_a?(TailCommandBuilder)
18
+ assert_equal "testfile.log", @command.filename
19
+ assert_equal 1, @command.terms.size
20
+ end
21
+
22
+ def test_raises_error_if_invalid_file
23
+ assert_raises GrepCommandBuilder::InvalidParameterError do
24
+ command = TailCommandBuilder.new(@params.merge("file" => "testfile.gz"))
25
+ end
26
+ end
27
+
28
+ def test_command_for_log
29
+ command = TailCommandBuilder.new(@params)
30
+ assert_equal "sh -c 'tail -n 250 -f testfile.log | grep -e foo'", command.command
31
+ end
32
+
33
+ def test_command_with_no_terms_for_log
34
+ command = TailCommandBuilder.new(@params.merge("term1" => nil))
35
+ assert_equal "sh -c 'tail -n 250 -f testfile.log'", command.command
36
+ end
37
+
38
+ def test_command_with_multiple_terms_for_log
39
+ command = TailCommandBuilder.new(@params.merge("term2" => "bar", "term3" => "baz"))
40
+ assert_equal "sh -c 'tail -n 250 -f testfile.log | grep -e foo | grep -e bar | grep -e baz'", command.command
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ Jul 7 20:12:11 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Processing Admin::ProductsController#index (for 67.70.29.242 at 2009-07-07 20:12:11) [GET]
2
+ Jul 7 20:12:11 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Parameters: {"action"=>"index", "controller"=>"admin/products"}
3
+ Jul 7 20:12:12 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Shop Load (44.5ms) SELECT shops.* FROM shops JOIN domains ON domains.host = 'jessetesting.staging.shopify.com' AND domains.shop_id = shops.id LIMIT 1
4
+ Jul 7 20:12:12 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Subscription Columns (1.4ms) SHOW FIELDS FROM `subscriptions`
5
+ Jul 7 20:12:12 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Subscription Load (11.3ms) SELECT * FROM `subscriptions` WHERE (`subscriptions`.`id` = 500852)
6
+ Jul 7 20:12:13 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Redirected to http://jessetesting.staging.shopify.com/admin/auth/login
7
+ Jul 7 20:12:13 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Filter chain halted as [:ensure_proper_user] rendered_or_redirected.
8
+ Jul 7 20:12:13 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Completed in 118ms (DB: 57) | 302 Found [http://jessetesting.staging.shopify.com/admin/products]
9
+ Jul 7 20:20:00 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Processing Admin::AuthController#login (for 67.70.29.242 at 2009-07-07 20:12:11) [GET]
10
+ Jul 7 20:20:00 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Parameters: {"action"=>"login", "controller"=>"admin/auth"}
11
+ Jul 7 20:30:11 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Shop Load (0.2ms) SELECT shops.* FROM shops JOIN domains ON domains.host = 'jessetesting.staging.shopify.com' AND domains.shop_id = shops.id LIMIT 1
12
+ Jul 7 20:40:11 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Rendering template within layouts/admin/auth
13
+ Jul 7 20:50:11 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Rendering admin/auth/login
14
+ Jul 7 21:00:11 staging rails.shopify[27975]: [jessetesting.staging.shopify.com] Completed in 17ms (View: 10, DB: 0) | 200 OK [http://jessetesting.staging.shopify.com/admin/auth/login]
15
+ Jul 7 22:12:11 10.1.1.1 rails.shopify[27975]: [john.staging.shopify.com] Processing Admin::ProductsController#index (for 67.70.29.242 at 2009-07-07 20:12:11) [GET]
16
+ Jul 7 22:12:11 192.168.5.1 rails.shopify[27975]: [john.staging.shopify.com] Processing Admin::ProductsController#index (for 67.70.29.242 at 2009-07-07 20:12:11) [GET]
17
+ Jul 7 22:12:11 192.168.5.1 rails.shopify[27975]: [john.staging.shopify.com] Processing Admin::ProductsController#index (for 67.70.29.242 at 2009-07-07 20:12:11) [GET]
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ require 'test/unit'
4
+ require 'clarity'
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+ require "strscan"
3
+
4
+ class TestLibraryFileName < Test::Unit::TestCase
5
+
6
+ NewLine = /\n/
7
+ def test_case_name
8
+ s = StringScanner.new('')
9
+ s << "abc\nd"
10
+ assert_equal "abc\n", s.scan_until(NewLine)
11
+ assert_equal nil, s.scan_until(NewLine)
12
+ s << "ef\ng"
13
+ assert_equal "def\n", s.scan_until(NewLine)
14
+ assert_equal nil, s.scan_until(NewLine)
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
2
+ <title>Clarity ~ A Log Search Tool<%= relative_root %></title>
3
+ <link rel="stylesheet" href="<%= relative_root %>/stylesheets/app.css" type="text/css" media="screen">
4
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
5
+ <script src="<%= relative_root %>/javascripts/app.js" type="text/javascript"></script>
@@ -0,0 +1,64 @@
1
+ <div id='toolbar'>
2
+ <div id='header'>
3
+ <h1><a href="/">Clarity</a> <span class='small' style='color:#aaa'>Log Search Tool</span></h1>
4
+ </div>
5
+
6
+ <form id='search' method='get' action='<%= relative_root %>/perform'>
7
+ <table class='actions'>
8
+ <tr>
9
+ <th>Action</th>
10
+ <th>Log File</th>
11
+ <th colspan=5>
12
+ Search Terms
13
+ <span class='note'><a href='#' onclick='Search.clear(); return false;'>clear</a></span>
14
+ </th>
15
+ <th> </th>
16
+ </tr>
17
+ <tr>
18
+ <td id='tool-selector'>
19
+ <input type='radio' name='tool' value='grep' id='grep-tool' checked='checked'> <span class='label' id='grep-label'>Search</span> <br/>
20
+ <input type='radio' name='tool' value='tail' id='tail-tool'> <span class='label' id='tail-label'>Tail</span> <br/>
21
+ </td>
22
+ <td id='file-selector'>
23
+ <select id='file-list' name='file'>
24
+ <% logfiles.map do |f| %>
25
+ <%= "<option value='#{f}'>#{f}</option>\n" %>
26
+ <% end %>
27
+ </select>
28
+ </td>
29
+ <td>
30
+ <input type='text' id='term1' name='term1' />
31
+ </td>
32
+ <td> <span class='and'>AND</span> </td>
33
+ <td>
34
+ <input type='text' id='term2' name='term2' />
35
+ </td>
36
+ <td> <span class='and'>AND</span> </td>
37
+ <td>
38
+ <input type='text' id='term3' name='term3' />
39
+ </td>
40
+ <td>
41
+ <input type='submit' value='Submit' onclick="Search.submit(); return false;"/>
42
+ </td>
43
+ <td>
44
+ </td>
45
+ </tr>
46
+ </table>
47
+ </form>
48
+ </div>
49
+
50
+
51
+ <div id="option-ctrl">
52
+ <ul>
53
+ <li><input type='checkbox' name='enable_scrolling' id='auto-scroll'/><span> Auto scroll?</span></li>
54
+ </ul>
55
+ </div>
56
+
57
+ <script>
58
+ Search.url = "<%= relative_root %>" + Search.url;
59
+ Search.init({ 'grep': <%= logfiles.map {|f| f }.to_json %>,
60
+ 'tail': <%= logfiles.map {|f| f if f =~ /log$/ }.compact.to_json %> },
61
+ <%= params.empty? ? 'null' : params.to_json %> );
62
+
63
+
64
+ </script>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html>
3
+ <head>
4
+ <%= @content_for_header %>
5
+ </head>
6
+ <body>
7
+ <%= @toolbar %>
8
+ <h1>Error</h1>
9
+ <p><%= @error %></p>
10
+ </body>
11
+ </html>
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html>
3
+ <head>
4
+ <%= @content_for_header %>
5
+ </head>
6
+
7
+ <body>
8
+ <%= @toolbar %>
9
+ <div id="results">
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kastner-clarity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.7
5
+ platform: ruby
6
+ authors:
7
+ - "Tobias L\xC3\xBCtke"
8
+ - John Tajima
9
+ - Erik Kastner
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-12-10 00:00:00 -05:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: eventmachine
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 0.12.10
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: eventmachine_httpserver
29
+ type: :runtime
30
+ version_requirement:
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 0.2.0
36
+ version:
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ type: :runtime
40
+ version_requirement:
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.0
46
+ version:
47
+ - !ruby/object:Gem::Dependency
48
+ name: hoe
49
+ type: :development
50
+ version_requirement:
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 2.3.3
56
+ version:
57
+ description: "Clarity - a log search tool\n\
58
+ By John Tajima & Tobi L\xC3\xBCtke\n\n\
59
+ Clarity is a Splunk like web interface for your server log files. It supports \n\
60
+ searching (using grep) as well as trailing log files in realtime. It has been written \n\
61
+ using the event based architecture based on EventMachine and so allows real-time search\n\
62
+ of very large log files. If you hit the browser Stop button it will also kill \n\
63
+ the grep / tail utility. \n\n\
64
+ We wrote Clarity to allow our support staff to use a simple interface to look\n\
65
+ through the various log files in our server farm. The application was such a \n\
66
+ big success internally that we decided to release it as open source."
67
+ email:
68
+ - tobi@shopify.com
69
+ - john@shopify.com
70
+ - kastner@gmail.com
71
+ executables:
72
+ - clarity
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - History.txt
77
+ - Manifest.txt
78
+ - PostInstall.txt
79
+ files:
80
+ - History.txt
81
+ - Manifest.txt
82
+ - PostInstall.txt
83
+ - README.rdoc
84
+ - Rakefile
85
+ - bin/clarity
86
+ - config/config.yml.sample
87
+ - lib/clarity.rb
88
+ - lib/clarity/cli.rb
89
+ - lib/clarity/commands/grep_command_builder.rb
90
+ - lib/clarity/commands/tail_command_builder.rb
91
+ - lib/clarity/grep_renderer.rb
92
+ - lib/clarity/process_tree.rb
93
+ - lib/clarity/renderers/log_renderer.rb
94
+ - lib/clarity/server.rb
95
+ - lib/clarity/server/basic_auth.rb
96
+ - lib/clarity/server/chunk_http.rb
97
+ - lib/clarity/server/mime_types.rb
98
+ - public/images/spinner_big.gif
99
+ - public/javascripts/app.js
100
+ - public/stylesheets/app.css
101
+ - script/console
102
+ - script/destroy
103
+ - script/generate
104
+ - test/commands/grep_command_builder_test.rb
105
+ - test/commands/tail_command_builder_test.rb
106
+ - test/files/logfile.log
107
+ - test/test_helper.rb
108
+ - test/test_string_scanner.rb
109
+ - views/_header.html.erb
110
+ - views/_toolbar.html.erb
111
+ - views/error.html.erb
112
+ - views/index.html.erb
113
+ has_rdoc: true
114
+ homepage: http://github.com/tobi/clarity
115
+ licenses: []
116
+
117
+ post_install_message: PostInstall.txt
118
+ rdoc_options:
119
+ - --main
120
+ - README.rdoc
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: "0"
128
+ version:
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: "0"
134
+ version:
135
+ requirements: []
136
+
137
+ rubyforge_project: kastner-clarity
138
+ rubygems_version: 1.3.5
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: Web interface for grep and tail -f
142
+ test_files:
143
+ - test/commands/grep_command_builder_test.rb
144
+ - test/commands/tail_command_builder_test.rb