fluent-plugin-hash-forward 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a216c4741f2a87d809deb2a2dcd6006f4315056b
4
- data.tar.gz: db7b1ca95255839c9a3134eacb34e3d580d75daf
3
+ metadata.gz: a0afb6cf6c53fa7e63173685f40958889da2f770
4
+ data.tar.gz: e6a1bc25cc85e1d075cb4bc48579a77dc4a71958
5
5
  SHA512:
6
- metadata.gz: bbff18a4bcb208ded9babba3f8f11992b62fa033285aa17b73f3ca0de441cfcea2b58eed8b6a4bbecf68ab2bb92250c543abf4bf0f22ac1fcc089f1f2846a285
7
- data.tar.gz: afe9ed287898a602f6bacf7d1fdc18eb226587e11c6ae2d82a97957028bd0f358a2e93cc72df235b86a4720a70af06865f6d405a55a8c526a9a8faed2820116d
6
+ metadata.gz: 0075b38f21756454e85d18632e7d57d3994c14491b119494560142e379c6bd6e4b968ee42b147bd118d4cd53ace4cc65888f2a19e40b25418ecc59ba439fecc6
7
+ data.tar.gz: c8b4a6b1361a1c17a78aaf022729c37e8ea09be612fc870c062559b154182422c0e5f740646825e215a62cd31a96a7cab0037ae392e22c686f64576e3781af04
@@ -1,3 +1,15 @@
1
+ # 0.3.1 (2013/12/11)
2
+
3
+ Changes
4
+
5
+ * Change default `keepalive` option to false
6
+
7
+ # 0.3.0 (2013/12/11)
8
+
9
+ Enhancement
10
+
11
+ * Add `keepalive` and `keepalive_time` option
12
+
1
13
  # 0.2.0 (2013/11/02)
2
14
 
3
15
  Enhancement
data/README.md CHANGED
@@ -31,6 +31,15 @@ Basically same with out\_forward plugin. See [http://docs.fluentd.org/articles/o
31
31
 
32
32
  Following parameters are additionally available:
33
33
 
34
+
35
+ * keepalive (bool)
36
+
37
+ Keepalive connection. Default is `false`.
38
+
39
+ * keepalive_time (time)
40
+
41
+ Keepalive expired time. Default is nil (which means to keep connection as long as possible).
42
+
34
43
  * hash\_key\_slice *min*..*max*
35
44
 
36
45
  Use sliced `tag` as a hash key to determine a forwarding node. Default: use entire `tag`.
@@ -3,10 +3,10 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "fluent-plugin-hash-forward"
6
- s.version = "0.2.0"
7
- s.authors = ["Ryosuke IWANAGA", "Naotoshi SEO"]
6
+ s.version = "0.3.1"
7
+ s.authors = ["Ryosuke IWANAGA", "Naotoshi Seo"]
8
8
  s.email = ["riywo.jp@gmail.com", "sonots@gmail.com"]
9
- s.homepage = "https://github.com/riywo/fluent-plugin-hash-forward"
9
+ s.homepage = "https://github.com/sonots/fluent-plugin-hash-forward"
10
10
  s.summary = %q{Fluentd plugin to keep forwarding messsages of a specific tag pattern to a specific node}
11
11
  s.description = s.summary
12
12
  s.licenses = ["MIT"]
@@ -4,6 +4,8 @@ class Fluent::HashForwardOutput < Fluent::ForwardOutput
4
4
  Fluent::Plugin.register_output('hash_forward', self)
5
5
 
6
6
  config_param :hash_key_slice, :string, :default => nil
7
+ config_param :keepalive, :bool, :default => false
8
+ config_param :keepalive_time, :time, :default => nil # infinite
7
9
 
8
10
  def configure(conf)
9
11
  super
@@ -22,6 +24,10 @@ class Fluent::HashForwardOutput < Fluent::ForwardOutput
22
24
  @standby_weight_array = build_weight_array(@standby_nodes)
23
25
 
24
26
  @cache_nodes = {}
27
+ @sock = {}
28
+ @sock_expired_at = {}
29
+ @mutex = {}
30
+ @watcher_interval = 1
25
31
  end
26
32
 
27
33
  # for test
@@ -31,13 +37,35 @@ class Fluent::HashForwardOutput < Fluent::ForwardOutput
31
37
  attr_reader :standby_weight_array
32
38
  attr_accessor :hash_key_slice_lindex
33
39
  attr_accessor :hash_key_slice_rindex
40
+ attr_accessor :watcher_interval
41
+
42
+ def start
43
+ super
44
+ start_watcher
45
+ end
46
+
47
+ def shutdown
48
+ super
49
+ stop_watcher
50
+ end
51
+
52
+ def start_watcher
53
+ if @keepalive and @keepalive_time
54
+ @watcher = Thread.new(&method(:watch_keepalive_time))
55
+ end
56
+ end
57
+
58
+ def stop_watcher
59
+ if @watcher
60
+ @watcher.terminate
61
+ @watcher.join
62
+ end
63
+ end
34
64
 
35
65
  # Override
36
66
  def write_objects(tag, chunk)
37
67
  return if chunk.empty?
38
-
39
68
  error = nil
40
-
41
69
  nodes = nodes(tag)
42
70
 
43
71
  # below is just copy from out_forward
@@ -64,8 +92,8 @@ class Fluent::HashForwardOutput < Fluent::ForwardOutput
64
92
  def rebuild_weight_array
65
93
  end
66
94
 
95
+ # This is just a partial copy from ForwardOuput#rebuild_weight_array
67
96
  def build_weight_array(nodes)
68
- # below is just a partial copy from out_forward#rebuild_weight_array
69
97
  weight_array = []
70
98
  gcd = nodes.map {|n| n.weight }.inject(0) {|r,w| r.gcd(w) }
71
99
  nodes.each {|n|
@@ -104,4 +132,96 @@ class Fluent::HashForwardOutput < Fluent::ForwardOutput
104
132
  sliced = tags[@hash_key_slice_lindex..@hash_key_slice_rindex]
105
133
  return sliced.nil? ? "" : sliced.join('.')
106
134
  end
135
+
136
+ # Override for keepalive
137
+ def send_data(node, tag, chunk)
138
+ get_mutex(node).synchronize do
139
+ sock = get_sock[node]
140
+ unless sock
141
+ sock = reconnect(node)
142
+ end
143
+
144
+ begin
145
+ sock_write(sock, tag, chunk)
146
+ node.heartbeat(false)
147
+ rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNABORTED, Errno::ETIMEDOUT => e
148
+ $log.warn "out_hash_forward: #{e.class} #{e.message}"
149
+ sock = reconnect(node)
150
+ retry
151
+ end
152
+ end
153
+ end
154
+
155
+ def reconnect(node)
156
+ sock = connect(node)
157
+ opt = [1, @send_timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
158
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
159
+
160
+ opt = [@send_timeout.to_i, 0].pack('L!L!') # struct timeval
161
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, opt)
162
+
163
+ if @keepalive
164
+ get_sock[node] = sock
165
+ get_sock_expired_at[node] = Time.now + @keepalive_time if @keepalive_time
166
+ end
167
+
168
+ sock
169
+ end
170
+
171
+ def sock_write(sock, tag, chunk)
172
+ # beginArray(2)
173
+ sock.write FORWARD_HEADER
174
+
175
+ # writeRaw(tag)
176
+ sock.write tag.to_msgpack # tag
177
+
178
+ # beginRaw(size)
179
+ sz = chunk.size
180
+ #if sz < 32
181
+ # # FixRaw
182
+ # sock.write [0xa0 | sz].pack('C')
183
+ #elsif sz < 65536
184
+ # # raw 16
185
+ # sock.write [0xda, sz].pack('Cn')
186
+ #else
187
+ # raw 32
188
+ sock.write [0xdb, sz].pack('CN')
189
+ #end
190
+
191
+ # writeRawBody(packed_es)
192
+ chunk.write_to(sock)
193
+ end
194
+
195
+ # watcher thread callback
196
+ def watch_keepalive_time
197
+ while true
198
+ sleep @watcher_interval
199
+ thread_ids = @sock.keys
200
+ thread_ids.each do |thread_id|
201
+ @sock[thread_id].each do |node, sock|
202
+ @mutex[thread_id][node].synchronize do
203
+ next unless sock_expired_at = @sock_expired_at[thread_id][node]
204
+ next unless Time.now >= sock_expired_at
205
+ sock.close rescue IOError if sock
206
+ @sock[thread_id][node] = nil
207
+ @sock_expired_at[thread_id][node] = nil
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ def get_mutex(node)
215
+ thread_id = Thread.current.object_id
216
+ @mutex[thread_id] ||= {}
217
+ @mutex[thread_id][node] ||= Mutex.new
218
+ end
219
+
220
+ def get_sock
221
+ @sock[Thread.current.object_id] ||= {}
222
+ end
223
+
224
+ def get_sock_expired_at
225
+ @sock_expired_at[Thread.current.object_id] ||= {}
226
+ end
107
227
  end
@@ -117,7 +117,7 @@ describe Fluent::HashForwardOutput do
117
117
  <server>
118
118
  host 192.168.1.3
119
119
  port 24224
120
- weight 1
120
+ weight 100
121
121
  </server>
122
122
  <server>
123
123
  host 192.168.1.4
@@ -189,10 +189,10 @@ describe Fluent::HashForwardOutput do
189
189
  let(:tag2) { 'test.tag2' }
190
190
  let(:config) { CONFIG + %[hash_key_slice 0..-2] }
191
191
  before do
192
- @node1 = driver.nodes(tag1).first
192
+ @node = driver.nodes(tag1).first
193
193
  end
194
- it 'should forward to the different node' do
195
- expect(driver.nodes(tag2).first).to eq(@node1)
194
+ it 'should forward to the same node' do
195
+ expect(driver.nodes(tag2).first).to eq(@node)
196
196
  end
197
197
  end
198
198
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-hash-forward
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryosuke IWANAGA
8
- - Naotoshi SEO
8
+ - Naotoshi Seo
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-02 00:00:00.000000000 Z
12
+ date: 2013-12-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
@@ -99,7 +99,7 @@ files:
99
99
  - lib/fluent/plugin/out_hash_forward.rb
100
100
  - spec/out_hash_forward_spec.rb
101
101
  - spec/spec_helper.rb
102
- homepage: https://github.com/riywo/fluent-plugin-hash-forward
102
+ homepage: https://github.com/sonots/fluent-plugin-hash-forward
103
103
  licenses:
104
104
  - MIT
105
105
  metadata: {}