fluent-tail 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: 13b33dca730d228105b39647de7cf4810d485faa
4
+ data.tar.gz: 8fcbe2060535a0d84a0efe6fce02b17c3c38d12f
5
+ SHA512:
6
+ metadata.gz: 87cbc96521d825e47a4a4d16d6c9e6a8fb6dca34f07b79f9caee632cff6d2d565e82e6af13eca52e100e72cb5d699dd82913ddf6733b5188f3f83995e3fc22b9
7
+ data.tar.gz: 6fbfd0a972be084ee6ff4c0409ad6cedd6d0aa2b7e3690cd8607ef923ebc4190d1283fdf255faaa3e14629abd80c832c7907187d68f1a1600ddeca2a90a305f9
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-tail.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,3 @@
1
+ Copyright (c) 2014 OKUNO Akihiro
2
+
3
+ Apache License, Version 2.0
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # Fluent::Tail
2
+
3
+ Using fluent-tail, you can tail [fluentd](http://fluentd.org/) event stream without any configuration changes.
4
+
5
+ ## Caution
6
+
7
+ Because tool modify the running fluentd process using `drb` and `instance_eval', there is a potential risk that the process could be broken unexpectedly.
8
+
9
+ In addition, this tool might degrade the perfermance of the fluentd process.
10
+
11
+ *Use this tool at your own risk.*
12
+
13
+ ## Installation
14
+
15
+ ```
16
+ $ fluent-gem install fluent-tail
17
+ ```
18
+
19
+ ## Prerequisite
20
+
21
+ `in_debug_agent` plugin is required to be enabled.
22
+
23
+ ```
24
+ <source>
25
+ type debug_agent
26
+ </source>
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ```
32
+ $ fluent-tail <tag_pattern>
33
+ ```
34
+
35
+ You can specify a pattern of tag with the same format as fluentd match tag.
36
+
37
+ e.g.
38
+
39
+
40
+ ```
41
+ $ fluent-tail foo.**
42
+ ```
43
+
44
+ then events with tag, such as "foo" , "foo.bar" and "foo.bar.foo" etc., will be shown in your console.
45
+
46
+ ```
47
+ 2014-03-06 14:22:21 +0900 foo: {"hoge":"fuga"}
48
+ 2014-03-06 14:22:23 +0900 foo.bar: {"hoge":"fuga"}
49
+ 2014-03-06 14:22:27 +0900 foo.bar.foo: {"hoge":"fuga"}
50
+ ```
51
+
52
+ ## Option
53
+
54
+ |parameter|description|default|
55
+ |---|---|---|
56
+ |-h, --host HOST|fluent host|127.0.0.1|
57
+ |-p, --port PORT|debug_agent|24230|
58
+ |-u, --unix PATH|use unix socket instead of tcp||
59
+ |-t, --output-type TYPE|output format of record. available types are 'json' or 'hash'.|json|
60
+
61
+ ## Copyright
62
+
63
+ See LICENSE.txt
64
+
65
+ ## Contributing
66
+
67
+ 1. Fork it ( http://github.com/choplin/fluent-tail/fork )
68
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
69
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
70
+ 4. Push to the branch (`git push origin my-new-feature`)
71
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/fluent-tail ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' unless defined?(gem)
4
+ here = File.dirname(__FILE__)
5
+ $LOAD_PATH << File.expand_path(File.join(here, '..', 'lib'))
6
+ require 'fluent/tail'
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fluent/tail/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fluent-tail"
8
+ spec.version = Fluent::Tail::VERSION
9
+ spec.authors = ["OKUNO Akihiro"]
10
+ spec.email = ["okuno.akihiro@gmail.com"]
11
+ spec.summary = %q{Tools for tailing fluentd stream events}
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/choplin/fluent-tail"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1,5 @@
1
+ module Fluent
2
+ module Tail
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,131 @@
1
+ require 'optparse'
2
+ require 'drb/drb'
3
+ require 'fluent/load'
4
+
5
+ def parse_options
6
+ op = OptionParser.new
7
+ op.banner += ' <pattern>'
8
+
9
+ (class<<self;self;end).module_eval do
10
+ define_method(:usage) do |msg|
11
+ puts op.to_s
12
+ puts "error: #{msg}" if msg
13
+ exit 1
14
+ end
15
+ end
16
+
17
+ opts = {
18
+ host: '127.0.0.1',
19
+ port: 24230,
20
+ unix: nil,
21
+ pattern: nil,
22
+ output_type: :json,
23
+ }
24
+
25
+ op.on('-h', '--host HOST', "fluent host (default: #{opts[:host]})") {|v|
26
+ opts[:host] = v
27
+ }
28
+
29
+ op.on('-p', '--port PORT', "debug_agent tcp port (default: #{opts[:host]})", Integer) {|v|
30
+ opts[:port] = v
31
+ }
32
+
33
+ op.on('-u', '--unix PATH', "use unix socket instead of tcp") {|v|
34
+ opts[:unix] = b
35
+ }
36
+
37
+ op.on('-t', '--output-type TYPE', "output format of record. available types are 'json' or 'hash'. (default: #{opts[:output_type]})") {|v|
38
+ case v.downcase
39
+ when 'json'
40
+ opts[:output_type] = :json
41
+ when 'hash'
42
+ opts[:output_type] = :hash
43
+ else
44
+ raise ConfigError, "output_type must be 'json' or 'hash'"
45
+ end
46
+ }
47
+
48
+ begin
49
+ op.parse!(ARGV)
50
+ opts[:pattern] = ARGV.shift
51
+
52
+ if opts[:pattern].nil?
53
+ usage "a pattern must be specified"
54
+ end
55
+ rescue
56
+ usage $!.to_s
57
+ end
58
+
59
+ opts
60
+ end
61
+
62
+ def format(tag, time, record)
63
+ "#{Time.at(time).localtime} #{tag}: #{@output_proc.call(record)}"
64
+ end
65
+
66
+ def main
67
+ opts = parse_options
68
+
69
+ @output_proc = case opts[:output_type]
70
+ when :json then Proc.new {|record| Yajl.dump(record) }
71
+ when :hash then Proc.new {|record| record.to_s }
72
+ end
73
+
74
+ unless opts[:unix].nil?
75
+ uri = "drbunix:#{opts[:unix]}"
76
+ else
77
+ uri = "druby://#{opts[:host]}:#{opts[:port]}"
78
+ end
79
+
80
+ $remote_engine = DRb::DRbObject.new_with_uri(uri)
81
+
82
+ remote_code = <<-CODE
83
+ alias :original_emit_staream :emit_stream
84
+ @fluent_tail_queue = Queue.new
85
+ @fluent_tail_match_pattern = Fluent::MatchPattern.create("#{opts[:pattern]}")
86
+ @fluent_tail_match_cache = {}
87
+
88
+ def emit_stream(tag, es)
89
+ matched = @fluent_tail_match_cache[tag]
90
+
91
+ if matched.nil?
92
+ matched = @fluent_tail_match_pattern.match(tag)
93
+ @fluent_tail_match_cache[tag] = matched
94
+ end
95
+
96
+ @fluent_tail_queue.push([tag, es.dup]) if matched
97
+
98
+ original_emit_staream(tag, es)
99
+ end
100
+
101
+ def pop
102
+ @fluent_tail_queue.pop
103
+ end
104
+ CODE
105
+
106
+ if $remote_engine.respond_to?(:original_emit_staream)
107
+ abort 'another client has already connected to the server. abort.'
108
+ end
109
+
110
+ begin
111
+ $remote_engine.method_missing(:instance_eval, remote_code)
112
+
113
+ while e = $remote_engine.pop
114
+ tag, es = e
115
+ es.each do |time,record|
116
+ STDOUT.puts format(tag, time, record)
117
+ end
118
+ end
119
+ ensure
120
+ if not $remote_engine.nil? and $remote_engine.respond_to?(:original_emit_staream)
121
+ remote_code = <<-CODE
122
+ @fluent_tail_queue = nil
123
+ alias :emit_stream :original_emit_staream
124
+ undef :original_emit_staream
125
+ CODE
126
+ $remote_engine.method_missing(:instance_eval, remote_code)
127
+ end
128
+ end
129
+ end
130
+
131
+ main
@@ -0,0 +1,11 @@
1
+ <source>
2
+ type debug_agent
3
+ </source>
4
+
5
+ <source>
6
+ type forward
7
+ </source>
8
+
9
+ <match **>
10
+ type stdout
11
+ </match>
@@ -0,0 +1,54 @@
1
+ require 'json'
2
+ require 'spec_helper'
3
+ require 'fluent/tail/version'
4
+
5
+ describe Fluent::Tail do
6
+ TAG_PATTER = 'foo.**'
7
+ CONFIG_PATH = File.join(File.dirname(__FILE__), 'fluent.conf')
8
+ BIN_DIR = File.join(ROOT, 'bin')
9
+
10
+ LOG = File.join(File.dirname(__FILE__), 'test.log')
11
+
12
+ before :all do
13
+ @fluentd_pid = spawn('fluentd', '-c', CONFIG_PATH, out: '/dev/null')
14
+ sleep 2
15
+
16
+ @r,w = IO.pipe
17
+ @fluent_tail_pid = spawn("#{File.join(BIN_DIR, 'fluent-tail')} #{TAG_PATTER}", out: w)
18
+ sleep 1
19
+ end
20
+
21
+ after :all do
22
+ Process.kill(:TERM, @fluent_tail_pid)
23
+ sleep 1
24
+ Process.kill(:TERM, @fluentd_pid)
25
+ Process.waitall
26
+ end
27
+
28
+ it 'have a version number' do
29
+ expect(Fluent::Tail::VERSION).not_to be_nil
30
+ end
31
+
32
+ it 'show matched events' do
33
+ tag = 'foo.bar'
34
+ time = Time.now
35
+ event = {'foo' => 'bar'}
36
+
37
+ client = FluentdClient.connect
38
+ client.write(tag, time.to_i, event)
39
+
40
+ line = @r.gets
41
+ expect(line).to eq("#{time.localtime} #{tag}: #{event.to_json}\n")
42
+ end
43
+
44
+ it 'does not show matched events' do
45
+ tag = 'hoge'
46
+ time = Time.now
47
+ event = {'foo' => 'bar'}
48
+
49
+ client = FluentdClient.connect
50
+ client.write(tag, time.to_i, event)
51
+
52
+ expect {@r.read_nonblock(10)}.to raise_error(Errno::EAGAIN)
53
+ end
54
+ end
@@ -0,0 +1,23 @@
1
+ ROOT = File.expand_path('../../', __FILE__)
2
+ $LOAD_PATH.unshift File.join(ROOT, 'lib')
3
+
4
+ require 'socket'
5
+
6
+
7
+ class FluentdClient
8
+ def self.connect
9
+ conn = TCPSocket.open('127.0.0.1', 24224)
10
+ self.new(conn)
11
+ end
12
+
13
+ def write(tag, time, event)
14
+ @conn.write [tag, time, event].to_json
15
+ end
16
+
17
+ private
18
+
19
+ def initialize(conn)
20
+ @conn = conn
21
+ end
22
+ end
23
+
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-tail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - OKUNO Akihiro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Tools for tailing fluentd stream events
56
+ email:
57
+ - okuno.akihiro@gmail.com
58
+ executables:
59
+ - fluent-tail
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - .rspec
65
+ - .travis.yml
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/fluent-tail
71
+ - fluent-tail.gemspec
72
+ - lib/fluent/tail.rb
73
+ - lib/fluent/tail/version.rb
74
+ - spec/fluent_tail/fluent.conf
75
+ - spec/fluent_tail/tail_spec.rb
76
+ - spec/spec_helper.rb
77
+ homepage: https://github.com/choplin/fluent-tail
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.14
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Tools for tailing fluentd stream events
101
+ test_files:
102
+ - spec/fluent_tail/fluent.conf
103
+ - spec/fluent_tail/tail_spec.rb
104
+ - spec/spec_helper.rb