fluent-plugin-kafka 0.0.18 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35a323b016500c1df85bc9631d27aceefe63f633
4
- data.tar.gz: c7d13cda1a73ad277400c8aa4ff58e27fdf31a49
3
+ metadata.gz: 498665d29438e6b21a3425138b42d0d69fa9bc95
4
+ data.tar.gz: 20c8b8bc1458035a52aa9492bb83fe4f5beee0d0
5
5
  SHA512:
6
- metadata.gz: 6524c04bcd2fb424fe0332be575116bf1106eb517f7a25297dd7430da0a46f2901a5417b84c9244a56f626860c02a6ce05ec74303946c5c5b9d5584575bc3c7d
7
- data.tar.gz: 0aba3a07b0a558c8d172a861634f7aae517b1827b069041198e78b27bc2988be045b85784d3d9a99f8e9bea8449ec1ab8e1c0fc11f7e05cc6916cce31c3fa2db
6
+ metadata.gz: c5c1ab553c03c001dd80b471d9c6b30a9356750c12e464b232728e54574e4e68a9e9f6f041ea995b1f6a0c3670d96040c2219df3b02e42e4ab93e285c8a302df
7
+ data.tar.gz: fbfa49c138e08b3dc5a988b932e20e9a33afc993fc7baa6336fd92412f3136bea11a9b42f8d40176eb8b877387545383fe8701af6d9a28202f75f41aa593504a
data/README.md CHANGED
@@ -19,7 +19,7 @@ Or install it yourself as:
19
19
 
20
20
  ## Usage
21
21
 
22
- ### Input plugin
22
+ ### Input plugin (type 'kafka')
23
23
 
24
24
  <source>
25
25
  type kafka
@@ -64,6 +64,33 @@ Supports a start of processing from the assigned offset for specific topics.
64
64
 
65
65
  See also [Poseidon::PartitionConsumer](http://www.rubydoc.info/github/bpot/poseidon/Poseidon/PartitionConsumer) for more detailed documentation about Poseidon.
66
66
 
67
+ ### Input plugin (type 'kafka_group', supports kafka group)
68
+
69
+ <source>
70
+ type kafka_group
71
+ brokers <list of broker-host:port, separate with comma, must set>
72
+ zookeepers <list of broker-host:port, separate with comma, must set>
73
+ consumer_group <consumer group name, must set>
74
+ topics <listening topics(separate with comma',')>
75
+ format <input text type (text|json|ltsv|msgpack)>
76
+ message_key <key (Optional, for text format only, default is message)>
77
+ add_prefix <tag prefix (Optional)>
78
+ add_suffix <tag suffix (Optional)>
79
+ max_bytes (integer) :default => nil (Use default of Poseidon)
80
+ max_wait_ms (integer) :default => nil (Use default of Poseidon)
81
+ min_bytes (integer) :default => nil (Use default of Poseidon)
82
+ socket_timeout_ms (integer) :default => nil (Use default of Poseidon)
83
+ </source>
84
+
85
+ Supports following Poseidon::PartitionConsumer options.
86
+
87
+ - max_bytes — default: 1048576 (1MB) — Maximum number of bytes to fetch
88
+ - max_wait_ms — default: 100 (100ms) — How long to block until the server sends us data.
89
+ - min_bytes — default: 1 (Send us data as soon as it is ready) — Smallest amount of data the server should send us.
90
+ - socket_timeout_ms - default: 10000 (10s) - How long to wait for reply from server. Should be higher than max_wait_ms.
91
+
92
+ See also [Poseidon::PartitionConsumer](http://www.rubydoc.info/github/bpot/poseidon/Poseidon/PartitionConsumer) for more detailed documentation about Poseidon.
93
+
67
94
  ### Output plugin (non-buffered)
68
95
 
69
96
  <match *.**>
@@ -12,9 +12,9 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
13
  gem.name = "fluent-plugin-kafka"
14
14
  gem.require_paths = ["lib"]
15
- gem.version = '0.0.18'
15
+ gem.version = '0.1.0'
16
16
  gem.add_dependency 'fluentd'
17
- gem.add_dependency 'poseidon'
17
+ gem.add_dependency 'poseidon_cluster'
18
18
  gem.add_dependency 'ltsv'
19
19
  gem.add_dependency 'yajl-ruby'
20
20
  gem.add_dependency 'msgpack'
@@ -0,0 +1,160 @@
1
+ module Fluent
2
+
3
+ class KafkaInput < Input
4
+ Plugin.register_input('kafka_group', self)
5
+
6
+ config_param :brokers, :string
7
+ config_param :zookeepers, :string
8
+ config_param :consumer_group, :string, :default => nil
9
+ config_param :topics, :string
10
+ config_param :interval, :integer, :default => 1 # seconds
11
+ config_param :format, :string, :default => 'json' # (json|text|ltsv)
12
+ config_param :message_key, :string, :default => 'message' # for 'text' format only
13
+ config_param :add_prefix, :string, :default => nil
14
+ config_param :add_suffix, :string, :default => nil
15
+
16
+ # poseidon PartitionConsumer options
17
+ config_param :max_bytes, :integer, :default => nil
18
+ config_param :max_wait_ms, :integer, :default => nil
19
+ config_param :min_bytes, :integer, :default => nil
20
+ config_param :socket_timeout_ms, :integer, :default => nil
21
+
22
+ def initialize
23
+ super
24
+ require 'poseidon_cluster'
25
+ end
26
+
27
+ def _config_to_array(config)
28
+ config_array = config.split(',').map {|k| k.strip }
29
+ if config_array.empty?
30
+ raise ConfigError, "kafka_group: '#{config}' is a required parameter"
31
+ end
32
+ config_array
33
+ end
34
+
35
+ private :_config_to_array
36
+
37
+ def configure(conf)
38
+ super
39
+ @broker_list = _config_to_array(@brokers)
40
+ @zookeeper_list = _config_to_array(@zookeepers)
41
+ @topic_list = _config_to_array(@topics)
42
+
43
+ unless @consumer_group
44
+ raise ConfigError, "kafka_group: 'consumer_group' is a required parameter"
45
+ end
46
+ $log.info "Will watch for topics #{@topic_list} at brokers " \
47
+ "#{@broker_list}, zookeepers #{@zookeeper_list} and group " \
48
+ "'#{@consumer_group}'"
49
+
50
+ case @format
51
+ when 'json'
52
+ require 'yajl'
53
+ when 'ltsv'
54
+ require 'ltsv'
55
+ when 'msgpack'
56
+ require 'msgpack'
57
+ end
58
+ end
59
+
60
+ def start
61
+ @loop = Coolio::Loop.new
62
+ opt = {}
63
+ opt[:max_bytes] = @max_bytes if @max_bytes
64
+ opt[:max_wait_ms] = @max_wait_ms if @max_wait_ms
65
+ opt[:min_bytes] = @min_bytes if @min_bytes
66
+ opt[:socket_timeout_ms] = @socket_timeout_ms if @socket_timeout_ms
67
+
68
+ @topic_watchers = @topic_list.map {|topic|
69
+ TopicWatcher.new(topic, @broker_list, @zookeeper_list, @consumer_group,
70
+ interval, @format, @message_key, @add_prefix,
71
+ @add_suffix, opt)
72
+ }
73
+ @topic_watchers.each {|tw|
74
+ tw.attach(@loop)
75
+ }
76
+ @thread = Thread.new(&method(:run))
77
+ end
78
+
79
+ def shutdown
80
+ @loop.stop
81
+ end
82
+
83
+ def run
84
+ @loop.run
85
+ rescue
86
+ $log.error "unexpected error", :error=>$!.to_s
87
+ $log.error_backtrace
88
+ end
89
+
90
+ class TopicWatcher < Coolio::TimerWatcher
91
+ def initialize(topic, broker_list, zookeeper_list, consumer_group,
92
+ interval, format, message_key, add_prefix, add_suffix,
93
+ options)
94
+ @topic = topic
95
+ @callback = method(:consume)
96
+ @format = format
97
+ @message_key = message_key
98
+ @add_prefix = add_prefix
99
+ @add_suffix = add_suffix
100
+
101
+ @consumer = Poseidon::ConsumerGroup.new(
102
+ consumer_group,
103
+ broker_list,
104
+ zookeeper_list,
105
+ topic,
106
+ options
107
+ )
108
+
109
+ super(interval, true)
110
+ end
111
+
112
+ def on_timer
113
+ @callback.call
114
+ rescue
115
+ # TODO log?
116
+ $log.error $!.to_s
117
+ $log.error_backtrace
118
+ end
119
+
120
+ def consume
121
+ es = MultiEventStream.new
122
+ tag = @topic
123
+ tag = @add_prefix + "." + tag if @add_prefix
124
+ tag = tag + "." + @add_suffix if @add_suffix
125
+
126
+ @consumer.fetch do |partition, bulk|
127
+ bulk.each do |msg|
128
+ begin
129
+ msg_record = parse_line(msg.value)
130
+ es.add(Time.now.to_i, msg_record)
131
+ rescue
132
+ $log.warn msg_record.to_s, :error=>$!.to_s
133
+ $log.debug_backtrace
134
+ end
135
+ end
136
+ end
137
+
138
+ unless es.empty?
139
+ Engine.emit_stream(tag, es)
140
+ end
141
+ end
142
+
143
+ def parse_line(record)
144
+ parsed_record = {}
145
+ case @format
146
+ when 'json'
147
+ parsed_record = Yajl::Parser.parse(record)
148
+ when 'ltsv'
149
+ parsed_record = LTSV.parse(record)
150
+ when 'msgpack'
151
+ parsed_record = MessagePack.unpack(record)
152
+ when 'text'
153
+ parsed_record[@message_key] = record
154
+ end
155
+ parsed_record
156
+ end
157
+ end
158
+ end
159
+
160
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-kafka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.18
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hidemasa Togashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-29 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: poseidon
28
+ name: poseidon_cluster
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '>='
@@ -107,6 +107,7 @@ files:
107
107
  - Rakefile
108
108
  - fluent-plugin-kafka.gemspec
109
109
  - lib/fluent/plugin/in_kafka.rb
110
+ - lib/fluent/plugin/in_kafka_group.rb
110
111
  - lib/fluent/plugin/out_kafka.rb
111
112
  - lib/fluent/plugin/out_kafka_buffered.rb
112
113
  - test/helper.rb