bracken 0.1.0 → 0.1.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.
- data/Rakefile +1 -1
- data/bracken.gemspec +50 -0
- data/examples/syslog.rb +13 -0
- data/examples/system.rb +4 -0
- data/features/step_definitions/bracken_steps.rb +4 -0
- data/features/support/env.rb +9 -1
- data/features/tailing.feature +28 -0
- data/lib/bracken/configuration/builder.rb +1 -1
- data/lib/bracken/configuration/options.rb +7 -1
- data/lib/bracken/logfile.rb +6 -4
- data/test/configuration_options_test.rb +21 -0
- data/test/logfile_test.rb +2 -2
- metadata +5 -2
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ rescue LoadError
|
|
4
4
|
abort 'Please `gem install shoe` to get started.'
|
5
5
|
end
|
6
6
|
|
7
|
-
Shoe.tie('bracken', '0.1.
|
7
|
+
Shoe.tie('bracken', '0.1.1', 'Bracken, at present, is a glorified logfile tailer.') do |spec|
|
8
8
|
spec.add_runtime_dependency 'open4'
|
9
9
|
|
10
10
|
spec.add_development_dependency 'cucumber'
|
data/bracken.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{bracken}
|
5
|
+
s.version = "0.1.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Matthew Todd"]
|
9
|
+
s.date = %q{2009-10-28}
|
10
|
+
s.default_executable = %q{bracken}
|
11
|
+
s.email = %q{matthew.todd@gmail.com}
|
12
|
+
s.executables = ["bracken"]
|
13
|
+
s.extra_rdoc_files = ["README.rdoc"]
|
14
|
+
s.files = ["Rakefile", "bracken.gemspec", "README.rdoc", "bin/bracken", "examples/console.rb", "examples/syslog.rb", "examples/system.rb", "features/step_definitions", "features/step_definitions/bracken_steps.rb", "features/support", "features/support/env.rb", "features/tailing.feature", "lib/bracken", "lib/bracken/application.rb", "lib/bracken/configuration", "lib/bracken/configuration/builder.rb", "lib/bracken/configuration/options.rb", "lib/bracken/configuration.rb", "lib/bracken/logfile", "lib/bracken/logfile/filter.rb", "lib/bracken/logfile/stream.rb", "lib/bracken/logfile.rb", "lib/bracken.rb", "test/configuration_builder_test.rb", "test/configuration_options_test.rb", "test/configuration_test.rb", "test/logfile_filter_test.rb", "test/logfile_test.rb", "test/test_helper.rb"]
|
15
|
+
s.rdoc_options = ["--main", "README.rdoc", "--title", "bracken-0.1.1", "--inline-source"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubygems_version = %q{1.3.5}
|
18
|
+
s.summary = %q{Bracken, at present, is a glorified logfile tailer.}
|
19
|
+
|
20
|
+
if s.respond_to? :specification_version then
|
21
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
|
+
s.specification_version = 3
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
25
|
+
s.add_development_dependency(%q<shoe>, [">= 0"])
|
26
|
+
s.add_runtime_dependency(%q<open4>, [">= 0"])
|
27
|
+
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
28
|
+
s.add_development_dependency(%q<fakefs>, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<jeremymcanally-matchy>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<redgreen>, [">= 0"])
|
31
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<shoe>, [">= 0"])
|
34
|
+
s.add_dependency(%q<open4>, [">= 0"])
|
35
|
+
s.add_dependency(%q<cucumber>, [">= 0"])
|
36
|
+
s.add_dependency(%q<fakefs>, [">= 0"])
|
37
|
+
s.add_dependency(%q<jeremymcanally-matchy>, [">= 0"])
|
38
|
+
s.add_dependency(%q<redgreen>, [">= 0"])
|
39
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
40
|
+
end
|
41
|
+
else
|
42
|
+
s.add_dependency(%q<shoe>, [">= 0"])
|
43
|
+
s.add_dependency(%q<open4>, [">= 0"])
|
44
|
+
s.add_dependency(%q<cucumber>, [">= 0"])
|
45
|
+
s.add_dependency(%q<fakefs>, [">= 0"])
|
46
|
+
s.add_dependency(%q<jeremymcanally-matchy>, [">= 0"])
|
47
|
+
s.add_dependency(%q<redgreen>, [">= 0"])
|
48
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
49
|
+
end
|
50
|
+
end
|
data/examples/syslog.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# To run this example:
|
2
|
+
# RUBYOPT=rubygems ./bin/bracken -c examples/syslog.rb
|
3
|
+
|
4
|
+
path = '/Users/mtodd/Code/hcts-logfiles/syslog.0'
|
5
|
+
# path = '/var/log/syslog'
|
6
|
+
|
7
|
+
file(path) do
|
8
|
+
on 'dovecot', /pop3-login/
|
9
|
+
on 'fetchmail', /reading message/
|
10
|
+
on 'fetchmail', /skipping message/
|
11
|
+
on 'postfix/smtp', /bounce/
|
12
|
+
on 'pppd', /peer authentication/
|
13
|
+
end
|
data/examples/system.rb
ADDED
@@ -6,6 +6,10 @@ When /^another process appends "([^\"]*)" to "([^\"]*)"$/ do |contents, path|
|
|
6
6
|
write_to_file(path, contents, 'a')
|
7
7
|
end
|
8
8
|
|
9
|
+
When /^another process renames "([^\"]*)" to "([^\"]*)"$/ do |old_path, new_path|
|
10
|
+
rename_file(old_path, new_path)
|
11
|
+
end
|
12
|
+
|
9
13
|
When /^I run (.*)$/ do |command|
|
10
14
|
run(command)
|
11
15
|
end
|
data/features/support/env.rb
CHANGED
@@ -12,8 +12,12 @@ class WorkingDirectory
|
|
12
12
|
@working_directory ||= Pathname.new(Dir.mktmpdir)
|
13
13
|
end
|
14
14
|
|
15
|
+
def rename_file(old_path, new_path)
|
16
|
+
file(old_path).rename(file(new_path))
|
17
|
+
end
|
18
|
+
|
15
19
|
def write_to_file(path, contents, mode='w')
|
16
|
-
|
20
|
+
file(path).open(mode) { |file| file.puts(contents) }
|
17
21
|
end
|
18
22
|
|
19
23
|
def run(command)
|
@@ -30,6 +34,10 @@ class WorkingDirectory
|
|
30
34
|
|
31
35
|
private
|
32
36
|
|
37
|
+
def file(path)
|
38
|
+
working_directory.join(path)
|
39
|
+
end
|
40
|
+
|
33
41
|
def rejigger_the_path(command)
|
34
42
|
"/usr/bin/env -i PATH='#{PROJECT_ROOT.join('bin')}:#{ENV['PATH']}' RUBYLIB='#{PROJECT_ROOT.join('lib')}' RUBYOPT=rubygems #{command}"
|
35
43
|
end
|
data/features/tailing.feature
CHANGED
@@ -17,6 +17,34 @@ Feature: Tailing
|
|
17
17
|
When another process appends "Line Two" to "syslog"
|
18
18
|
Then I should see "Line Two" on standard out
|
19
19
|
|
20
|
+
Scenario: Tailing a file that gets rotated away
|
21
|
+
Given these are the contents of "config.rb":
|
22
|
+
"""
|
23
|
+
file 'syslog'
|
24
|
+
"""
|
25
|
+
And these are the contents of "syslog":
|
26
|
+
"""
|
27
|
+
Line One
|
28
|
+
"""
|
29
|
+
When I run bracken -c config.rb
|
30
|
+
Then I should see "Line One" on standard out
|
31
|
+
When another process renames "syslog" to "syslog.0"
|
32
|
+
And another process appends "Line Two" to "syslog"
|
33
|
+
Then I should see "Line Two" on standard out
|
34
|
+
|
35
|
+
Scenario: Tailing a file with a custom number of lines
|
36
|
+
Given these are the contents of "config.rb":
|
37
|
+
"""
|
38
|
+
file 'syslog'
|
39
|
+
"""
|
40
|
+
And these are the contents of "syslog":
|
41
|
+
"""
|
42
|
+
Line One
|
43
|
+
Line Two
|
44
|
+
"""
|
45
|
+
When I run bracken -c config.rb -n 1
|
46
|
+
Then I should see "Line Two" on standard out
|
47
|
+
|
20
48
|
Scenario: Tailing and filtering an existing file
|
21
49
|
Given these are the contents of "config.rb":
|
22
50
|
"""
|
@@ -5,18 +5,24 @@ module Bracken
|
|
5
5
|
|
6
6
|
class Options
|
7
7
|
attr_reader :configuration_file
|
8
|
+
attr_reader :number_of_lines
|
8
9
|
|
9
10
|
def initialize
|
10
11
|
@configuration_file = '/etc/bracken.rb'
|
12
|
+
@number_of_lines = 1000
|
11
13
|
end
|
12
14
|
|
13
15
|
def parse(arguments)
|
14
16
|
arguments.extend(::OptionParser::Arguable)
|
15
17
|
|
16
18
|
arguments.options do |opts|
|
17
|
-
opts.on('-c', '--config-file
|
19
|
+
opts.on('-c', '--config-file=PATH', 'Read configuration from PATH.', '[/etc/bracken.rb]') do |path|
|
18
20
|
@configuration_file = path
|
19
21
|
end
|
22
|
+
|
23
|
+
opts.on('-n', '--lines=N', Integer, 'Tail the last N lines from each file.', '[1000]') do |number|
|
24
|
+
@number_of_lines = number
|
25
|
+
end
|
20
26
|
end.parse!
|
21
27
|
end
|
22
28
|
end
|
data/lib/bracken/logfile.rb
CHANGED
@@ -5,16 +5,18 @@ require 'open4'
|
|
5
5
|
module Bracken
|
6
6
|
class Logfile
|
7
7
|
attr_reader :filters
|
8
|
+
attr_reader :number_of_lines
|
8
9
|
attr_reader :path
|
9
10
|
|
10
|
-
def initialize(path)
|
11
|
-
@filters
|
12
|
-
@
|
11
|
+
def initialize(path, number_of_lines)
|
12
|
+
@filters = []
|
13
|
+
@number_of_lines = number_of_lines
|
14
|
+
@path = path
|
13
15
|
end
|
14
16
|
|
15
17
|
def stream
|
16
18
|
@stream ||= begin
|
17
|
-
pid, _, out, _ = Open4.popen4("tail -
|
19
|
+
pid, _, out, _ = Open4.popen4("tail -n #{number_of_lines} -F #{path}")
|
18
20
|
|
19
21
|
out.extend(Stream)
|
20
22
|
out.logfile = self
|
@@ -18,5 +18,26 @@ class ConfigurationOptionsTest < Test::Unit::TestCase
|
|
18
18
|
@options.parse(%w(--config-file config.rb))
|
19
19
|
@options.configuration_file.should == 'config.rb'
|
20
20
|
end
|
21
|
+
|
22
|
+
should 'default the number of lines to 1000' do
|
23
|
+
@options.parse(%w())
|
24
|
+
@options.number_of_lines.should == 1000
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'use the number of lines from -n' do
|
28
|
+
@options.parse(%w(-n 10))
|
29
|
+
@options.number_of_lines.should == 10
|
30
|
+
end
|
31
|
+
|
32
|
+
should 'use the number of lines from --lines' do
|
33
|
+
@options.parse(%w(--lines 10))
|
34
|
+
@options.number_of_lines.should == 10
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'require a number for number of lines' do
|
38
|
+
lambda {
|
39
|
+
@options.parse(%w(--lines a))
|
40
|
+
}.should raise_error(OptionParser::InvalidArgument)
|
41
|
+
end
|
21
42
|
end
|
22
43
|
end
|
data/test/logfile_test.rb
CHANGED
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), 'test_helper')
|
|
3
3
|
class LogfileTest < Test::Unit::TestCase
|
4
4
|
context '#stream' do
|
5
5
|
setup do
|
6
|
-
@logfile = Logfile.new(__FILE__)
|
6
|
+
@logfile = Logfile.new(__FILE__, 5)
|
7
7
|
end
|
8
8
|
|
9
9
|
should 'return a selectable, killable IO object tailing the file' do
|
@@ -12,7 +12,7 @@ class LogfileTest < Test::Unit::TestCase
|
|
12
12
|
stream = reads.first
|
13
13
|
|
14
14
|
begin
|
15
|
-
stream.gets.should == File.readlines(__FILE__)[-
|
15
|
+
stream.gets.should == File.readlines(__FILE__)[-5]
|
16
16
|
ensure
|
17
17
|
stream.kill
|
18
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bracken
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Todd
|
@@ -92,9 +92,12 @@ extra_rdoc_files:
|
|
92
92
|
- README.rdoc
|
93
93
|
files:
|
94
94
|
- Rakefile
|
95
|
+
- bracken.gemspec
|
95
96
|
- README.rdoc
|
96
97
|
- bin/bracken
|
97
98
|
- examples/console.rb
|
99
|
+
- examples/syslog.rb
|
100
|
+
- examples/system.rb
|
98
101
|
- features/step_definitions/bracken_steps.rb
|
99
102
|
- features/support/env.rb
|
100
103
|
- features/tailing.feature
|
@@ -121,7 +124,7 @@ rdoc_options:
|
|
121
124
|
- --main
|
122
125
|
- README.rdoc
|
123
126
|
- --title
|
124
|
-
- bracken-0.1.
|
127
|
+
- bracken-0.1.1
|
125
128
|
- --inline-source
|
126
129
|
require_paths:
|
127
130
|
- lib
|