fluent-plugin-hash-forward 0.2.0 → 0.3.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 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: {}