woodchuck-json-event 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 934e85e0c487748ecef4e8de1d7ff7be93722345
4
+ data.tar.gz: 031380d504b95b856152aa14dec8dbb92a1d5c51
5
+ SHA512:
6
+ metadata.gz: 420ecaab3d337c2cb091c3d88fff3f3e6133752faa83a4e81807e423b5d10bbf1f854c648bedab421408b6016fa2cecb816925a30886263766e07df760a5c3db
7
+ data.tar.gz: 4a147dd5e96fa9b521e1122bc7608e4901cb6074de5827f1b246456b1e73f9c263734ae610f7b16f8bed3cc1cbc13ebd82c93a308621ea54b45981a521a71ba0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ spec/fixtures
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format doc
data/Gemfile ADDED
@@ -0,0 +1,30 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in woodchuck.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ end
9
+
10
+ group :doc do
11
+ gem 'yard', '~> 0.8.2.1'
12
+ gem 'redcarpet', '~> 2.1.1'
13
+ end
14
+
15
+ group :test do
16
+ gem 'guard', '~> 1.3.2'
17
+ gem 'guard-rspec', '~> 1.2.1'
18
+ gem 'guard-spork', '~> 1.1.0'
19
+ gem 'rb-fsevent', '~> 0.9.1'
20
+ gem 'growl', '~> 1.0.3'
21
+ gem 'simplecov', '~> 0.6.4'
22
+ gem 'timecop', '~> 0.4.6'
23
+ end
24
+
25
+ # JSON
26
+ # gem 'json', :platform => :jruby
27
+ gem 'yajl-ruby', :platform => [ :ruby_18, :ruby_19 ]
28
+
29
+ # OpenSSL
30
+ gem 'jruby-openssl', :platform => :jruby
data/Guardfile ADDED
@@ -0,0 +1,13 @@
1
+ ignore %r{^spec/fixtures/}
2
+
3
+ guard 'rspec', :version => 2, :cli => "--color --format doc" do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+ watch(%r{^spec/support/.+.rb$}) { "spec" }
8
+ end
9
+
10
+ guard 'spork' do
11
+ watch('spec/spec_helper.rb')
12
+ watch(%r{^spec/support/.+.rb$}) { "spec" }
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Dan Ryan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Woodchuck
2
+
3
+ A lightweight log shipper for logstash written in Ruby.
4
+
5
+ Inspired by [beaver](https://github.com/josegonzalez/beaver) and [logstash](https://github.com/logstash/logstash) itself. Fair warning, it's a work in progress ;)
6
+
7
+ ## Installation
8
+
9
+ Install as a gem:
10
+
11
+ $ gem install woodchuck
12
+
13
+ And then execute:
14
+
15
+ $ woodchuck
16
+
17
+ ## Usage
18
+ ```bash
19
+ woodchuck --files /var/log/syslog,/var/log/apache/**/*,/var/log/nginx/*.log --output redis
20
+ ```
21
+
22
+ ### Options
23
+ ```
24
+ * -h, --help - Help!
25
+ * -l, --log-level - Log verbosity. [ debug, warn, info, error, fatal ]
26
+ * -p, --paths - A comma-separated list of files to watch for changes (file globbing is accepted).
27
+ * -o, --output - The output to send to [ stdout, redis ]
28
+ * -f, --format - Input line format
29
+ ```
30
+ ## Coming soon
31
+
32
+ * Handy config format for multiple files and outputs
33
+ * regular expressions (why not!)
34
+ * ZeroMQ and TCP output support
35
+ * Performance enhancements
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc "Run specs"
5
+ RSpec::Core::RakeTask.new(:spec) {|t|}
6
+
7
+ namespace :spec do
8
+ desc "Clean up rbx compiled files and run spec suite"
9
+ RSpec::Core::RakeTask.new(:ci) { |t| Dir.glob("**/*.rbc").each {|f| FileUtils.rm_f(f) } }
10
+ end
11
+
12
+ desc "Run guard"
13
+ task :guard do
14
+ sh %{bundle exec guard start}
15
+ end
16
+
17
+ desc "Run spork"
18
+ task :spork do
19
+ sh %{bundle exec spork}
20
+ end
data/bin/woodchuck ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.dirname(__FILE__) + '/../lib' unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
+
5
+ require 'woodchuck'
6
+
7
+ opts = Woodchuck::Runner.read
8
+ Woodchuck::Runner.run(opts)
@@ -0,0 +1,58 @@
1
+ require 'yajl'
2
+ require 'socket'
3
+ require 'thread'
4
+
5
+ require 'woodchuck/output'
6
+ require 'woodchuck/input'
7
+ require 'woodchuck/input/plain'
8
+ require 'woodchuck/input/json_event'
9
+
10
+ class Woodchuck::Agent
11
+
12
+ attr_accessor :logger, :watcher, :watcher_thread, :paths, :output, :input_format
13
+
14
+ def initialize(options={})
15
+ @paths = options[:paths]
16
+ options[:log_level] ||= :info
17
+ @logger = Woodchuck::Logger.new(::STDOUT)
18
+ @logger.level = options[:log_level]
19
+ @mutex = Mutex.new
20
+ @output = case options[:output]
21
+ when :zeromq
22
+ Woodchuck::Output::ZeroMQ.new(options[:log_level])
23
+ when :redis
24
+ Woodchuck::Output::Redis.new(options[:log_level])
25
+ else
26
+ Woodchuck::Output::STDOUT.new(options[:log_level])
27
+ end
28
+ @input_format = case options[:input_format]
29
+ when :json_event
30
+ Woodchuck::Input::JsonEvent.new
31
+ else
32
+ Woodchuck::Input::Plain.new
33
+ end
34
+
35
+ @watcher = Woodchuck::Watcher.new(self, options[:log_level], @input_format, @paths)
36
+ end
37
+
38
+ def start(blocking=false)
39
+ @mutex.synchronize do
40
+ return if @stop == false
41
+ @stop = false
42
+ end
43
+ @watcher_thread = Thread.new { @watcher.start }
44
+ @watcher_thread.join if blocking
45
+ end
46
+
47
+ def stop
48
+ @mutex.synchronize do
49
+ return if @stop == true
50
+ @stop = true
51
+ end
52
+ Thread.kill(@watcher_thread) if @watcher_thread
53
+ end
54
+
55
+ def inspect
56
+ to_s
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Woodchuck::Config
2
+ DEFAULT_OUTPUT = :stdout
3
+ end
@@ -0,0 +1,46 @@
1
+ require 'woodchuck/logger'
2
+
3
+ class Woodchuck::Event
4
+
5
+ attr_accessor :source_path, :source_host, :timestamp, :source, :message, :fields, :tags, :type
6
+
7
+ def initialize(init_hsh)
8
+ @source_path = init_hsh["@source_path"] || init_hsh[:source_path]
9
+ @source_host = init_hsh["@source_host"] || init_hsh[:source_host]
10
+ @timestamp = init_hsh["@timestamp"] || init_hsh[:timestamp]
11
+ @source = init_hsh["@source"] || init_hsh[:source]
12
+ @message = init_hsh["@message"] || init_hsh[:message]
13
+ @fields = init_hsh["@fields"] || init_hsh[:fields]
14
+ @tags = init_hsh["@tags"] || init_hsh[:tags]
15
+ @type = init_hsh["@type"] || init_hsh[:type]
16
+ end
17
+
18
+ def method_missing(symbol, *args, &block)
19
+ if to_hash.has_key?(symbol)
20
+ to_hash
21
+ else
22
+ super(symbol, *args, &block)
23
+ end
24
+ end
25
+
26
+ def to_hash
27
+ {
28
+ '@source' => source.to_s,
29
+ '@type' => type,
30
+ '@tags' => tags,
31
+ '@fields' => fields,
32
+ '@timestamp' => timestamp,
33
+ '@source_host' => source_host,
34
+ '@source_path' => source_path,
35
+ '@message' => message
36
+ }
37
+ end
38
+
39
+ def to_json(*args)
40
+ to_hash.to_json(*args)
41
+ end
42
+
43
+ def to_s
44
+ to_json
45
+ end
46
+ end
@@ -0,0 +1,19 @@
1
+ require 'json'
2
+
3
+ class Woodchuck::Input::Plain < Woodchuck::Input
4
+ protected
5
+
6
+ def prepare_hash(path, line)
7
+ super(path, line).merge(
8
+ parse_json(line)
9
+ )
10
+ end
11
+
12
+ def parse_json(line)
13
+ begin
14
+ JSON.parse(line)
15
+ rescue
16
+ {}
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'json'
2
+
3
+ class Woodchuck::Input::JsonEvent < Woodchuck::Input
4
+ protected
5
+
6
+ def prepare_hash(path, line)
7
+ super(path, line).merge(
8
+ parse_json(line)
9
+ )
10
+ end
11
+
12
+ def parse_json(line)
13
+ begin
14
+ JSON.parse(line)
15
+ rescue
16
+ {}
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ class Woodchuck::Input::Plain < Woodchuck::Input
2
+ protected
3
+
4
+ def prepare_hash(path, line)
5
+ super(path, line).merge(
6
+ {
7
+ :message => line.strip
8
+ }
9
+ )
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'socket'
2
+
3
+ class Woodchuck::Input
4
+
5
+ def create(path, line)
6
+ Woodchuck::Event.new(prepare_hash(path, line))
7
+ end
8
+
9
+ protected
10
+
11
+ def prepare_hash(path, line)
12
+ host = Socket.gethostname
13
+
14
+ {
15
+ :source_path => path,
16
+ :line => line,
17
+ :source_host => host,
18
+ :timestamp => Time.now.utc.iso8601(6),
19
+ :source => Addressable::URI.new(:scheme => 'file', :host => host, :path => path),
20
+ :type => 'file',
21
+ :fields => {},
22
+ :tags => []
23
+ }
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'cabin'
2
+
3
+ module Woodchuck
4
+ class Logger < Cabin::Channel
5
+
6
+ def initialize(*args)
7
+ super()
8
+
9
+ subscribe(args[0])
10
+
11
+ metrics.channel = Cabin::Channel.new
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ require 'redis'
2
+ require 'redis/namespace'
3
+
4
+ class Woodchuck::Output::Redis < Woodchuck::Output
5
+ attr_accessor :url, :host, :port, :db, :namespace
6
+
7
+ def initialize(log_level)
8
+ super(log_level)
9
+ @type = :redis
10
+ @url = Addressable::URI.parse(ENV['REDIS_URL'] || 'redis://localhost:6379/9')
11
+ @namespace = ENV['REDIS_NAMESPACE'] || 'logstash:woodchuck'
12
+ end
13
+
14
+ def redis
15
+ client = ::Redis.new(:url => url)
16
+ ::Redis::Namespace.new(namespace, :redis => client)
17
+ end
18
+
19
+ def handle(event)
20
+ redis.lpush("events", event.to_json)
21
+ @logger.info "Logging event to Redis", event.to_hash
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ require 'woodchuck/output'
2
+
3
+ class Woodchuck::Output::STDOUT < Woodchuck::Output
4
+ def initialize(log_level)
5
+ super(log_level)
6
+ @type = :stdout
7
+ end
8
+
9
+ def handle(event)
10
+ @logger.info "Logging event to STDOUT", event.to_hash
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'woodchuck/output'
2
+
3
+ class Woodchuck::Output::ZeroMQ < Woodchuck::Output
4
+ def initialize(log_level)
5
+ super(log_level)
6
+ @type = :zeromq
7
+ end
8
+
9
+ def handle(event)
10
+ @logger.info event.message, event.to_hash
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ require 'socket'
2
+
3
+ class Woodchuck::Output
4
+ attr_accessor :type, :logger, :host
5
+
6
+ def initialize(log_level)
7
+ @host = Socket.gethostname
8
+ @logger = Woodchuck::Logger.new(::STDOUT)
9
+ @logger.level = log_level
10
+ end
11
+
12
+ def handle(event)
13
+ true
14
+ end
15
+ end
@@ -0,0 +1,47 @@
1
+ require 'fallen'
2
+
3
+ module Woodchuck::Runner
4
+ extend Fallen
5
+ # extend Fallen::CLI
6
+ extend self
7
+
8
+ def logger
9
+ @logger ||= Woodchuck::Logger.new(STDOUT)
10
+ end
11
+
12
+ def logger=(log)
13
+ @logger = log
14
+ end
15
+
16
+ def read(args=ARGV)
17
+ options = {}
18
+
19
+ optparse = OptionParser.new do |opts|
20
+ opts.on('-l', '--log-level [LOG_LEVEL]', [:debug, :warn, :info, :error, :fatal], 'set the log level') do |level|
21
+ options[:log_level] = level.to_sym
22
+ end
23
+ opts.on('-o', '--output [OUTPUT]', 'set the output') do |output|
24
+ options[:output] = output.to_sym
25
+ end
26
+ opts.on('-p', '--paths [PATHS]', Array, 'A list of file paths to watch') do |paths|
27
+ options[:paths] = paths
28
+ end
29
+ opts.on('-f', '--format [FORMAT]', [:plain, :json_event], 'Input line format') do |input_format|
30
+ options[:input_format] = input_format
31
+ end
32
+ end
33
+ optparse.parse!(args)
34
+ options
35
+ end
36
+
37
+ def run(options={})
38
+ #puts options.inspect
39
+ agent = Woodchuck::Agent.new(options)
40
+ agent.start(true)
41
+ Signal.trap('INT') do
42
+ @logger.warn :signal => signal
43
+ agent.stop
44
+ exit 0
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ require "eventmachine-tail"
2
+
3
+ class Woodchuck::TailReader < EventMachine::FileTail
4
+
5
+ attr_accessor :input_format, :output
6
+
7
+ def self.static_init(input_format, output)
8
+ @@input_format = input_format
9
+ @@output = output
10
+ end
11
+
12
+ def initialize(path, startpos = -1)
13
+ super(path, startpos)
14
+ @input_format = @@input_format
15
+ @output = @@output
16
+
17
+ @buffer = BufferedTokenizer.new
18
+ end
19
+
20
+ def receive_data(data)
21
+ @buffer.extract(data).each do |line|
22
+ @output.handle(@input_format.create(path, line))
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,3 @@
1
+ module Woodchuck
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,38 @@
1
+ require "eventmachine"
2
+ require "eventmachine-tail"
3
+ require 'addressable/uri'
4
+ require 'yajl'
5
+ require 'socket'
6
+ require 'time'
7
+ require 'thread'
8
+ require 'forwardable'
9
+ require 'woodchuck/tail_reader'
10
+
11
+ class Woodchuck::Watcher
12
+ extend Forwardable
13
+
14
+ attr_accessor :paths, :logger, :events, :agent, :input_format
15
+ def_delegator :@agent, :output, :output
16
+
17
+ def initialize(agent, log_level, input_format, *paths)
18
+ @agent = agent
19
+ @logger = Woodchuck::Logger.new(::STDOUT)
20
+ @logger.level = log_level unless log_level.nil?
21
+ @paths = paths.flatten.compact
22
+ @input_format = input_format
23
+ end
24
+
25
+ def start
26
+ Woodchuck::TailReader.static_init(input_format, output)
27
+
28
+ EventMachine.run do
29
+ paths.each do |path|
30
+ EventMachine::FileGlobWatchTail.new(path, Woodchuck::TailReader)
31
+ end
32
+ end
33
+ end
34
+
35
+ def inspect
36
+ to_s
37
+ end
38
+ end
data/lib/woodchuck.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'optparse'
2
+
3
+ require 'woodchuck/version'
4
+
5
+ require 'woodchuck/logger'
6
+ require 'woodchuck/agent'
7
+ require 'woodchuck/watcher'
8
+ require 'woodchuck/event'
9
+ require 'woodchuck/output'
10
+ require 'woodchuck/output/stdout'
11
+ require 'woodchuck/output/redis'
12
+ require 'woodchuck/output/zeromq'
13
+
14
+ require 'woodchuck/runner'
15
+
16
+ module Woodchuck
17
+
18
+ end
File without changes
File without changes
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'spork'
3
+
4
+ Spork.prefork do
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'bundler'
8
+ Bundler.require
9
+
10
+ require 'rspec'
11
+ require 'timecop'
12
+ # require 'fakefs'
13
+ require 'fileutils'
14
+
15
+ require 'woodchuck'
16
+
17
+ RSpec.configure do |config|
18
+ config.before do
19
+ Timecop.freeze
20
+ # FakeFS.activate!
21
+ end
22
+ config.after do
23
+ Timecop.return
24
+ # FakeFS.deactivate!
25
+ end
26
+ end
27
+ end
28
+
29
+ Spork.each_run do
30
+ # This code will be run each time you run your specs.
31
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
32
+
33
+ end
34
+
35
+ # Crash loud in tests!
36
+ Thread.abort_on_exception = true
@@ -0,0 +1,34 @@
1
+ require 'tmpdir'
2
+ require 'pathname'
3
+ require 'fileutils'
4
+
5
+ # stolen with love from the Listen gem
6
+ include FileUtils
7
+
8
+ # Prepares temporary fixture-directories and
9
+ # cleans them afterwards.
10
+ #
11
+ # @param [Fixnum] number_of_directories the number of fixture-directories to make
12
+ #
13
+ # @yield [path1, path2, ...] the empty fixture-directories
14
+ # @yieldparam [String] path the path to a fixture directory
15
+ #
16
+
17
+ def fixture_path
18
+ Pathname.new(File.expand_path(File.join(pwd, "spec/fixtures/#{Time.now.to_f.to_s.sub('.', '') + rand(9999).to_s}")))
19
+ end
20
+
21
+ def fixtures(fixt_path=nil)
22
+ path = fixt_path || fixture_path
23
+ current_pwd = pwd
24
+
25
+ # Create the path
26
+ mkdir_p path
27
+ cd path
28
+
29
+ yield(path)
30
+
31
+ ensure
32
+ cd current_pwd
33
+ rm_rf(path) if File.exists?(path)
34
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+ require 'pp'
4
+
5
+ describe Woodchuck::Agent do
6
+ describe '#initialize' do
7
+ let(:logfile) { Tempfile.new("foobar") }
8
+
9
+ subject { described_class.new }
10
+
11
+ it 'sets a logger' do
12
+ subject.logger.should be_a Woodchuck::Logger
13
+ end
14
+ it 'sets a tailer' do
15
+ subject.watcher.should be_a Woodchuck::Watcher
16
+ end
17
+ end
18
+
19
+ describe '#start' do
20
+ let(:path) { fixture_path }
21
+ let(:log_dir) { path + "**/*" }
22
+ let(:log_file) { File.open(path + 'foo', 'w+') }
23
+ let(:timestamp) { Time.now.utc.iso8601(6) }
24
+
25
+ subject { described_class.new(log_dir.to_s) }
26
+
27
+ before do
28
+ Socket.stub(:gethostname).and_return("example.com")
29
+
30
+ fixtures path do
31
+ touch log_file
32
+ end
33
+ end
34
+
35
+ after do
36
+ subject.stop
37
+ end
38
+
39
+ it 'gets a list of events' do
40
+ subject.start
41
+ log_file.write("a message!\n")
42
+ log_file.flush
43
+ # subject.watcher.events.size.should == 1
44
+ end
45
+ # it do
46
+ # subject.events.size.should == 1
47
+ # end
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Woodchuck::Watcher do
5
+ describe '#initialize' do
6
+ let(:logfile) { Tempfile.new("foobar") }
7
+
8
+ subject { described_class.new(logfile) }
9
+
10
+ it 'sets a logger' do
11
+ subject.logger.should be_a Woodchuck::Logger
12
+ end
13
+ it 'sets a tailer' do
14
+ subject.tailer.should be_a FileWatch::Tail
15
+ end
16
+ it 'sets the watched paths' do
17
+ subject.paths.should == [logfile]
18
+ end
19
+ end
20
+
21
+ # describe '#run' do
22
+ # let(:logfile) { Tempfile.new("foobar") }
23
+ # let(:path) { fixture_path }
24
+ # let(:timestamp) { Time.now.utc.iso8601(6) }
25
+ # subject { described_class.new(logfile) }
26
+ #
27
+ # before do
28
+ # Socket.stub(:gethostname).and_return("example.com")
29
+ # # subject.run
30
+ # # logfile.write("a message!\n")
31
+ # # logfile.flush
32
+ # end
33
+ #
34
+ # # it do
35
+ # # subject.events.size.should == 1
36
+ # # end
37
+ # end
38
+ end
data/woodchuck.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'woodchuck/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "woodchuck"
8
+ gem.version = Woodchuck::VERSION
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.authors = ["Dan Ryan"]
11
+ gem.email = ["dan@appliedawesome.com"]
12
+ # gem.description = %q{TODO: Write a gem description}
13
+ gem.summary = %q{lightweight log shipper for logstash}
14
+ gem.homepage = "https://github.com/danryan/woodchuck"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ # gem.add_dependency 'listen', '~> 0.5.0'
22
+ gem.add_dependency 'eventmachine-tail', '~> 0.6.3'
23
+ gem.add_dependency 'yajl-ruby', '~> 1.1.0'
24
+ gem.add_dependency 'cabin', '~> 0.4.4'
25
+ gem.add_dependency 'addressable', '~> 2.3.2'
26
+ gem.add_dependency 'redis', '~> 3.0.1'
27
+ gem.add_dependency 'redis-namespace', '~> 1.2.1'
28
+ gem.add_dependency 'fallen', '~> 0.0.1'
29
+
30
+ gem.add_development_dependency 'bundler'
31
+ gem.add_development_dependency 'rspec', '~> 2.11.0'
32
+ gem.add_development_dependency 'spork', '~> 1.0.0.rc3'
33
+ gem.add_development_dependency 'timecop', '~> 0.4.6'
34
+ end
metadata ADDED
@@ -0,0 +1,239 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: woodchuck-json-event
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dan Ryan
8
+ - David Pech
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine-tail
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: 0.6.3
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 0.6.3
28
+ - !ruby/object:Gem::Dependency
29
+ name: yajl-ruby
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.1.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 1.1.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: cabin
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: 0.4.4
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.4.4
56
+ - !ruby/object:Gem::Dependency
57
+ name: addressable
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 2.3.2
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.3.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: redis
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 3.0.1
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: 3.0.1
84
+ - !ruby/object:Gem::Dependency
85
+ name: redis-namespace
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ version: 1.2.1
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: 1.2.1
98
+ - !ruby/object:Gem::Dependency
99
+ name: fallen
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ~>
103
+ - !ruby/object:Gem::Version
104
+ version: 0.0.1
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: 0.0.1
112
+ - !ruby/object:Gem::Dependency
113
+ name: bundler
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ~>
131
+ - !ruby/object:Gem::Version
132
+ version: 2.11.0
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ version: 2.11.0
140
+ - !ruby/object:Gem::Dependency
141
+ name: spork
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ~>
145
+ - !ruby/object:Gem::Version
146
+ version: 1.0.0.rc3
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ~>
152
+ - !ruby/object:Gem::Version
153
+ version: 1.0.0.rc3
154
+ - !ruby/object:Gem::Dependency
155
+ name: timecop
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ~>
159
+ - !ruby/object:Gem::Version
160
+ version: 0.4.6
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ~>
166
+ - !ruby/object:Gem::Version
167
+ version: 0.4.6
168
+ description:
169
+ email:
170
+ - dan@appliedawesome.com
171
+ - davidpechcz@gmail.com
172
+ executables:
173
+ - woodchuck
174
+ extensions: []
175
+ extra_rdoc_files: []
176
+ files:
177
+ - .gitignore
178
+ - .rspec
179
+ - Gemfile
180
+ - Guardfile
181
+ - LICENSE.txt
182
+ - README.md
183
+ - Rakefile
184
+ - bin/woodchuck
185
+ - lib/woodchuck.rb
186
+ - lib/woodchuck/agent.rb
187
+ - lib/woodchuck/config.rb
188
+ - lib/woodchuck/event.rb
189
+ - lib/woodchuck/input.rb
190
+ - lib/woodchuck/input/json.rb
191
+ - lib/woodchuck/input/json_event.rb
192
+ - lib/woodchuck/input/plain.rb
193
+ - lib/woodchuck/logger.rb
194
+ - lib/woodchuck/output.rb
195
+ - lib/woodchuck/output/redis.rb
196
+ - lib/woodchuck/output/stdout.rb
197
+ - lib/woodchuck/output/zeromq.rb
198
+ - lib/woodchuck/runner.rb
199
+ - lib/woodchuck/tail_reader.rb
200
+ - lib/woodchuck/version.rb
201
+ - lib/woodchuck/watcher.rb
202
+ - spec/.fixtures/13469547385549766486/foo/bar
203
+ - spec/.fixtures/13469550171330562865/foo/bar
204
+ - spec/spec_helper.rb
205
+ - spec/support/fixtures_helper.rb
206
+ - spec/woodchuck/agent_spec.rb
207
+ - spec/woodchuck/watcher_spec.rb
208
+ - woodchuck.gemspec
209
+ homepage: https://github.com/pechdavid/woodchuck
210
+ licenses: []
211
+ metadata: {}
212
+ post_install_message:
213
+ rdoc_options: []
214
+ require_paths:
215
+ - lib
216
+ required_ruby_version: !ruby/object:Gem::Requirement
217
+ requirements:
218
+ - - '>='
219
+ - !ruby/object:Gem::Version
220
+ version: '0'
221
+ required_rubygems_version: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - '>='
224
+ - !ruby/object:Gem::Version
225
+ version: '0'
226
+ requirements: []
227
+ rubyforge_project:
228
+ rubygems_version: 2.0.0
229
+ signing_key:
230
+ specification_version: 4
231
+ summary: lightweight log shipper for logstash with enhanced input options
232
+ test_files:
233
+ - spec/.fixtures/13469547385549766486/foo/bar
234
+ - spec/.fixtures/13469550171330562865/foo/bar
235
+ - spec/spec_helper.rb
236
+ - spec/support/fixtures_helper.rb
237
+ - spec/woodchuck/agent_spec.rb
238
+ - spec/woodchuck/watcher_spec.rb
239
+ has_rdoc: