edouard-clarity 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
data/script/console ADDED
@@ -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"
data/script/destroy ADDED
@@ -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)
data/script/generate ADDED
@@ -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 on <%= @hostname %> ~ 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'><%= @hostname %></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'/><label for='auto-scroll'>Auto scroll?</label></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 }.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,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: edouard-clarity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.9
5
+ platform: ruby
6
+ authors:
7
+ - "Tobias L\xC3\xBCtke"
8
+ - John Tajima
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-03-23 00:00:00 +01:00
14
+ default_executable: clarity
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: eventmachine
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 0.12.10
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: eventmachine_httpserver
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.2.0
35
+ version:
36
+ - !ruby/object:Gem::Dependency
37
+ name: json
38
+ type: :runtime
39
+ version_requirement:
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 1.0.0
45
+ version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: rubyforge
48
+ type: :development
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.3
55
+ version:
56
+ - !ruby/object:Gem::Dependency
57
+ name: gemcutter
58
+ type: :development
59
+ version_requirement:
60
+ version_requirements: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 0.3.0
65
+ version:
66
+ - !ruby/object:Gem::Dependency
67
+ name: hoe
68
+ type: :development
69
+ version_requirement:
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 2.5.0
75
+ version:
76
+ description: "Clarity - a log search tool\n\
77
+ By John Tajima & Tobi L\xC3\xBCtke\n\n\
78
+ Clarity is a Splunk like web interface for your server log files. It supports \n\
79
+ searching (using grep) as well as trailing log files in realtime. It has been written \n\
80
+ using the event based architecture based on EventMachine and so allows real-time search\n\
81
+ of very large log files. If you hit the browser Stop button it will also kill \n\
82
+ the grep / tail utility. \n\n\
83
+ We wrote Clarity to allow our support staff to use a simple interface to look\n\
84
+ through the various log files in our server farm. The application was such a \n\
85
+ big success internally that we decided to release it as open source."
86
+ email:
87
+ - tobi@shopify.com
88
+ - john@shopify.com
89
+ executables:
90
+ - clarity
91
+ extensions: []
92
+
93
+ extra_rdoc_files:
94
+ - History.txt
95
+ - Manifest.txt
96
+ - PostInstall.txt
97
+ files:
98
+ - History.txt
99
+ - Manifest.txt
100
+ - PostInstall.txt
101
+ - README.rdoc
102
+ - Rakefile
103
+ - bin/clarity
104
+ - config/config.yml.sample
105
+ - lib/clarity.rb
106
+ - lib/clarity/cli.rb
107
+ - lib/clarity/commands/grep_command_builder.rb
108
+ - lib/clarity/commands/hostname_command_builder.rb
109
+ - lib/clarity/commands/tail_command_builder.rb
110
+ - lib/clarity/grep_renderer.rb
111
+ - lib/clarity/process_tree.rb
112
+ - lib/clarity/renderers/log_renderer.rb
113
+ - lib/clarity/server.rb
114
+ - lib/clarity/server/basic_auth.rb
115
+ - lib/clarity/server/chunk_http.rb
116
+ - lib/clarity/server/mime_types.rb
117
+ - public/images/spinner_big.gif
118
+ - public/javascripts/app.js
119
+ - public/stylesheets/app.css
120
+ - script/console
121
+ - script/destroy
122
+ - script/generate
123
+ - test/commands/grep_command_builder_test.rb
124
+ - test/commands/tail_command_builder_test.rb
125
+ - test/files/logfile.log
126
+ - test/test_helper.rb
127
+ - test/test_string_scanner.rb
128
+ - views/_header.html.erb
129
+ - views/_toolbar.html.erb
130
+ - views/error.html.erb
131
+ - views/index.html.erb
132
+ has_rdoc: true
133
+ homepage: http://github.com/tobi/clarity
134
+ licenses: []
135
+
136
+ post_install_message: PostInstall.txt
137
+ rdoc_options:
138
+ - --main
139
+ - README.rdoc
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: "0"
147
+ version:
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: "0"
153
+ version:
154
+ requirements: []
155
+
156
+ rubyforge_project: edouard-clarity
157
+ rubygems_version: 1.3.5
158
+ signing_key:
159
+ specification_version: 3
160
+ summary: Web interface for grep and tail -f
161
+ test_files:
162
+ - test/commands/grep_command_builder_test.rb
163
+ - test/commands/tail_command_builder_test.rb