bracken 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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.0', 'Bracken, at present, is a glorified logfile tailer.') do |spec|
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
@@ -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
@@ -0,0 +1,4 @@
1
+ # To run this example:
2
+ # RUBYOPT=rubygems ./bin/bracken -c examples/system.rb
3
+
4
+ file '/var/log/system.log'
@@ -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
@@ -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
- working_directory.join(path).open(mode) { |file| file.puts(contents) }
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
@@ -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
  """
@@ -23,7 +23,7 @@ module Bracken
23
23
  end
24
24
 
25
25
  def file(path, &block)
26
- configuration.files << Logfile.new(path)
26
+ configuration.files << Logfile.new(path, configuration.options.number_of_lines)
27
27
 
28
28
  if block_given?
29
29
  instance_eval(&block)
@@ -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 PATH', 'Read configuration from PATH.', '[/etc/bracken.rb]') do |path|
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
@@ -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
- @path = path
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 -f #{path}")
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__)[-10]
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.0
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.0
127
+ - bracken-0.1.1
125
128
  - --inline-source
126
129
  require_paths:
127
130
  - lib