fluent-plugin-flume 0.1.3 → 0.2.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 +4 -4
- data/ChangeLog +5 -0
- data/VERSION +1 -1
- data/lib/fluent/plugin/in_flume.rb +144 -148
- data/lib/fluent/plugin/old_thrift/flume.thrift +72 -0
- data/lib/fluent/plugin/old_thrift/flume_constants.rb +8 -0
- data/lib/fluent/plugin/old_thrift/flume_types.rb +72 -0
- data/lib/fluent/plugin/old_thrift/thrift_flume_event_server.rb +219 -0
- data/lib/fluent/plugin/out_flume.rb +73 -74
- data/test/plugin/test_in_flume.rb +2 -4
- data/test/plugin/test_out_flume.rb +8 -9
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d92aa659b736a1e4228653bcf7089cf0844ed412
|
4
|
+
data.tar.gz: 74f103fa74799fdb9ee89debad3a3ce803c360ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1ec6c1fdd6ab7cd36acc3bdef637f4186c4464adec65839abeea0116a1e464240dccf2f88c414127cf88ec6dbea340347eac0fc7f6fbd9dee87012820b50ef6
|
7
|
+
data.tar.gz: fe24084964f0b71d51073c807ede72419dfde1faca46f824b5dbbc7b73875e6c67fba1392905f55cf0254749ae8ae0d1a08d898ce7eb998fb0670f30fe9601b7
|
data/ChangeLog
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -19,175 +19,171 @@
|
|
19
19
|
require 'fluent/input'
|
20
20
|
|
21
21
|
module Fluent
|
22
|
+
class FlumeInput < Input
|
23
|
+
Plugin.register_input('flume', self)
|
24
|
+
|
25
|
+
config_param :port, :integer, :default => 56789
|
26
|
+
config_param :bind, :string, :default => '0.0.0.0'
|
27
|
+
config_param :server_type, :string, :default => 'simple'
|
28
|
+
config_param :is_framed, :bool, :default => false
|
29
|
+
config_param :body_size_limit, :size, :default => 32 * 1024 * 1024
|
30
|
+
config_param :tag_field, :string, :default => nil
|
31
|
+
config_param :default_tag, :string, :default => 'category'
|
32
|
+
config_param :add_prefix, :string, :default => nil
|
33
|
+
config_param :msg_format, :string, :default => 'text'
|
34
|
+
|
35
|
+
unless method_defined?(:log)
|
36
|
+
define_method(:log) { $log }
|
37
|
+
end
|
22
38
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
config_param :tag_field, :string, :default => nil
|
32
|
-
config_param :default_tag, :string, :default => 'category'
|
33
|
-
config_param :add_prefix, :string, :default => nil
|
34
|
-
config_param :msg_format, :string, :default => 'text'
|
35
|
-
|
36
|
-
unless method_defined?(:log)
|
37
|
-
define_method(:log) { $log }
|
38
|
-
end
|
39
|
-
|
40
|
-
def initialize
|
41
|
-
require 'thrift'
|
42
|
-
$:.unshift File.join(File.dirname(__FILE__), 'thrift')
|
43
|
-
require 'flume_types'
|
44
|
-
require 'flume_constants'
|
45
|
-
require 'thrift_flume_event_server'
|
39
|
+
def initialize
|
40
|
+
require 'thrift'
|
41
|
+
require 'fluent/plugin/old_thrift/flume_types'
|
42
|
+
$:.unshift File.join(File.dirname(__FILE__), 'old_thrift')
|
43
|
+
require 'flume_constants'
|
44
|
+
require 'thrift_flume_event_server'
|
45
|
+
super
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
-
|
48
|
+
def start
|
49
|
+
log.debug "listening flume on #{@bind}:#{@port}"
|
50
|
+
log.warn "[in_flume] This plugin is obsoleted for Flume NG. You should consider to use flume-ng-fluentd-sink."
|
51
|
+
|
52
|
+
handler = FluentFlumeHandler.new
|
53
|
+
handler.tag_field = @tag_field
|
54
|
+
handler.default_tag = @default_tag
|
55
|
+
handler.add_prefix = @add_prefix
|
56
|
+
handler.msg_format = @msg_format
|
57
|
+
handler.log = log
|
58
|
+
handler.router = router
|
59
|
+
processor = ThriftFlumeEventServer::Processor.new handler
|
60
|
+
|
61
|
+
@transport = Thrift::ServerSocket.new @bind, @port
|
62
|
+
unless @is_framed
|
63
|
+
transport_factory = Thrift::BufferedTransportFactory.new
|
64
|
+
else
|
65
|
+
raise ConfigError, "in_flume: unsupported is_framed '#{@is_framed}'"
|
66
|
+
end
|
49
67
|
|
50
|
-
|
51
|
-
|
52
|
-
|
68
|
+
unless ['text', 'json'].include? @msg_format
|
69
|
+
raise 'Unknown format: msg_format=#{@msg_format}'
|
70
|
+
end
|
53
71
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
72
|
+
# 2011/09/29 Kazuki Ohta <kazuki.ohta@gmail.com>
|
73
|
+
# This section is a workaround to set strict_read and strict_write option.
|
74
|
+
# Ruby-Thrift 0.7 set them both 'true' in default, but Flume protocol set
|
75
|
+
# them both 'false'.
|
76
|
+
protocol_factory = Thrift::BinaryProtocolFactory.new
|
77
|
+
protocol_factory.instance_eval {|obj|
|
78
|
+
def get_protocol(trans) # override
|
79
|
+
return Thrift::BinaryProtocol.new(trans,
|
80
|
+
strict_read=false,
|
81
|
+
strict_write=false)
|
82
|
+
end
|
83
|
+
}
|
84
|
+
|
85
|
+
case @server_type
|
86
|
+
when 'simple'
|
87
|
+
@server = Thrift::SimpleServer.new processor, @transport, transport_factory, protocol_factory
|
88
|
+
when 'threaded'
|
89
|
+
@server = Thrift::ThreadedServer.new processor, @transport, transport_factory, protocol_factory
|
90
|
+
when 'thread_pool'
|
91
|
+
@server = Thrift::ThreadPoolServer.new processor, @transport, transport_factory, protocol_factory
|
92
|
+
else
|
93
|
+
raise ConfigError, "in_flume: unsupported server_type '#{@server_type}'"
|
94
|
+
end
|
95
|
+
@thread = Thread.new(&method(:run))
|
70
96
|
end
|
71
97
|
|
72
|
-
|
73
|
-
|
98
|
+
def shutdown
|
99
|
+
@transport.close unless @transport.closed?
|
100
|
+
#@thread.join
|
74
101
|
end
|
75
102
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
def get_protocol(trans) # override
|
83
|
-
return Thrift::BinaryProtocol.new(trans,
|
84
|
-
strict_read=false,
|
85
|
-
strict_write=false)
|
86
|
-
end
|
87
|
-
}
|
88
|
-
|
89
|
-
case @server_type
|
90
|
-
when 'simple'
|
91
|
-
@server = Thrift::SimpleServer.new processor, @transport, transport_factory, protocol_factory
|
92
|
-
when 'threaded'
|
93
|
-
@server = Thrift::ThreadedServer.new processor, @transport, transport_factory, protocol_factory
|
94
|
-
when 'thread_pool'
|
95
|
-
@server = Thrift::ThreadPoolServer.new processor, @transport, transport_factory, protocol_factory
|
96
|
-
else
|
97
|
-
raise ConfigError, "in_flume: unsupported server_type '#{@server_type}'"
|
103
|
+
def run
|
104
|
+
log.debug "starting server: #{@server}"
|
105
|
+
@server.serve
|
106
|
+
rescue
|
107
|
+
log.error "unexpected error", :error=>$!.to_s
|
108
|
+
log.error_backtrace
|
98
109
|
end
|
99
|
-
@thread = Thread.new(&method(:run))
|
100
|
-
end
|
101
110
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
attr_accessor :log
|
121
|
-
|
122
|
-
def append(evt)
|
123
|
-
begin
|
124
|
-
record = create_record(evt)
|
125
|
-
if @tag_field
|
126
|
-
tag = evt.fieldss[@tag_field] || @default_tag
|
127
|
-
unless tag
|
128
|
-
return # ignore
|
111
|
+
class FluentFlumeHandler
|
112
|
+
attr_accessor :tag_field
|
113
|
+
attr_accessor :default_tag
|
114
|
+
attr_accessor :add_prefix
|
115
|
+
attr_accessor :msg_format
|
116
|
+
attr_accessor :log
|
117
|
+
attr_accessor :router
|
118
|
+
|
119
|
+
def append(evt)
|
120
|
+
begin
|
121
|
+
record = create_record(evt)
|
122
|
+
if @tag_field
|
123
|
+
tag = evt.fieldss[@tag_field] || @default_tag
|
124
|
+
unless tag
|
125
|
+
return # ignore
|
126
|
+
end
|
127
|
+
else
|
128
|
+
tag = @default_tag
|
129
129
|
end
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
130
|
+
timestamp = evt.timestamp.to_i
|
131
|
+
if @add_prefix
|
132
|
+
router.emit(@add_prefix + '.' + tag, timestamp, record)
|
133
|
+
else
|
134
|
+
router.emit(tag, timestamp, record)
|
135
|
+
end
|
136
|
+
rescue => e
|
137
|
+
log.error "unexpected error", :error=>$!.to_s
|
138
|
+
log.error_backtrace
|
138
139
|
end
|
139
|
-
rescue => e
|
140
|
-
log.error "unexpected error", :error=>$!.to_s
|
141
|
-
log.error_backtrace
|
142
140
|
end
|
143
|
-
end
|
144
141
|
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
def rawAppend(evt)
|
143
|
+
log.error "rawAppend is not implemented yet: #{evt}"
|
144
|
+
end
|
148
145
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
146
|
+
def ackedAppend(evt)
|
147
|
+
begin
|
148
|
+
record = create_record(evt)
|
149
|
+
if @tag_field
|
150
|
+
tag = evt.fieldss[@tag_field] || @default_tag
|
151
|
+
unless tag
|
152
|
+
return # ignore
|
153
|
+
end
|
154
|
+
else
|
155
|
+
tag = @default_tag
|
156
156
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
157
|
+
timestamp = evt.timestamp.to_i
|
158
|
+
if @add_prefix
|
159
|
+
router.emit(@add_prefix + '.' + tag, timestamp, record)
|
160
|
+
else
|
161
|
+
router.emit(tag, timestamp, record)
|
162
|
+
end
|
163
|
+
return EventStatus::ACK
|
164
|
+
rescue => e
|
165
|
+
log.error "unexpected error", :error=>$!.to_s
|
166
|
+
log.error_backtrace
|
167
|
+
return EventStatus::ERR
|
165
168
|
end
|
166
|
-
return EventStatus::ACK
|
167
|
-
rescue => e
|
168
|
-
log.error "unexpected error", :error=>$!.to_s
|
169
|
-
log.error_backtrace
|
170
|
-
return EventStatus::ERR
|
171
169
|
end
|
172
|
-
end
|
173
170
|
|
174
|
-
|
175
|
-
|
171
|
+
def close()
|
172
|
+
end
|
176
173
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
174
|
+
private
|
175
|
+
def create_record(evt)
|
176
|
+
case @msg_format
|
177
|
+
when 'text'
|
178
|
+
return {'message'=>evt.body.force_encoding('UTF-8')}
|
179
|
+
when 'json'
|
180
|
+
js = JSON.parse(evt.body.force_encoding('UTF-8'))
|
181
|
+
raise 'body must be a Hash, if json_body=true' unless js.is_a?(Hash)
|
182
|
+
return js
|
183
|
+
else
|
184
|
+
raise 'Invalid format: #{@msg_format}'
|
185
|
+
end
|
188
186
|
end
|
189
187
|
end
|
190
188
|
end
|
191
189
|
end
|
192
|
-
|
193
|
-
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/**
|
2
|
+
* Licensed to Cloudera, Inc. under one
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
4
|
+
* distributed with this work for additional information
|
5
|
+
* regarding copyright ownership. Cloudera, Inc. licenses this file
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
7
|
+
* "License"); you may not use this file except in compliance
|
8
|
+
* with the License. You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
# flume.thrift
|
19
|
+
#
|
20
|
+
# This thrift interface and service defines a network transport mechanism to move events
|
21
|
+
# from one process/machine to another. At the moment this mirrors the fields of an event
|
22
|
+
# as defined in c.c.f.core.Event.java's code .
|
23
|
+
#
|
24
|
+
# This may change more fields are likely to be added, and the actual format is subject to change.
|
25
|
+
|
26
|
+
# The server has two rpc methods
|
27
|
+
# -- append: which sends an event to the server,
|
28
|
+
# -- close: shuts down this client's connection
|
29
|
+
#
|
30
|
+
# Currently append is oneway, requiring the thrift server to do flow control.
|
31
|
+
|
32
|
+
namespace java com.cloudera.flume.handlers.thrift
|
33
|
+
|
34
|
+
typedef i64 Timestamp
|
35
|
+
|
36
|
+
enum Priority {
|
37
|
+
FATAL = 0,
|
38
|
+
ERROR = 1,
|
39
|
+
WARN = 2,
|
40
|
+
INFO = 3,
|
41
|
+
DEBUG = 4,
|
42
|
+
TRACE = 5
|
43
|
+
}
|
44
|
+
|
45
|
+
enum EventStatus {
|
46
|
+
ACK = 0,
|
47
|
+
COMMITED = 1,
|
48
|
+
ERR = 2
|
49
|
+
}
|
50
|
+
|
51
|
+
struct ThriftFlumeEvent {
|
52
|
+
1: Timestamp timestamp,
|
53
|
+
2: Priority priority,
|
54
|
+
3: binary body,
|
55
|
+
4: i64 nanos,
|
56
|
+
5: string host,
|
57
|
+
6: map<string,binary> fieldss
|
58
|
+
}
|
59
|
+
|
60
|
+
# Instead of using thrift's serialization, we just assume the contents are serialized already.
|
61
|
+
struct RawEvent {
|
62
|
+
1: binary raw
|
63
|
+
}
|
64
|
+
|
65
|
+
service ThriftFlumeEventServer {
|
66
|
+
oneway void append( 1:ThriftFlumeEvent evt ),
|
67
|
+
oneway void rawAppend( 1:RawEvent evt),
|
68
|
+
EventStatus ackedAppend( 1: ThriftFlumeEvent evt ),
|
69
|
+
|
70
|
+
void close(),
|
71
|
+
}
|
72
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.9.3)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'thrift'
|
8
|
+
|
9
|
+
module Priority
|
10
|
+
FATAL = 0
|
11
|
+
ERROR = 1
|
12
|
+
WARN = 2
|
13
|
+
INFO = 3
|
14
|
+
DEBUG = 4
|
15
|
+
TRACE = 5
|
16
|
+
VALUE_MAP = {0 => "FATAL", 1 => "ERROR", 2 => "WARN", 3 => "INFO", 4 => "DEBUG", 5 => "TRACE"}
|
17
|
+
VALID_VALUES = Set.new([FATAL, ERROR, WARN, INFO, DEBUG, TRACE]).freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
module EventStatus
|
21
|
+
ACK = 0
|
22
|
+
COMMITED = 1
|
23
|
+
ERR = 2
|
24
|
+
VALUE_MAP = {0 => "ACK", 1 => "COMMITED", 2 => "ERR"}
|
25
|
+
VALID_VALUES = Set.new([ACK, COMMITED, ERR]).freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
class ThriftFlumeEvent
|
29
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
30
|
+
TIMESTAMP = 1
|
31
|
+
PRIORITY = 2
|
32
|
+
BODY = 3
|
33
|
+
NANOS = 4
|
34
|
+
HOST = 5
|
35
|
+
FIELDSS = 6
|
36
|
+
|
37
|
+
FIELDS = {
|
38
|
+
TIMESTAMP => {:type => ::Thrift::Types::I64, :name => 'timestamp'},
|
39
|
+
PRIORITY => {:type => ::Thrift::Types::I32, :name => 'priority', :enum_class => ::Priority},
|
40
|
+
BODY => {:type => ::Thrift::Types::STRING, :name => 'body', :binary => true},
|
41
|
+
NANOS => {:type => ::Thrift::Types::I64, :name => 'nanos'},
|
42
|
+
HOST => {:type => ::Thrift::Types::STRING, :name => 'host'},
|
43
|
+
FIELDSS => {:type => ::Thrift::Types::MAP, :name => 'fieldss', :key => {:type => ::Thrift::Types::STRING}, :value => {:type => ::Thrift::Types::STRING, :binary => true}}
|
44
|
+
}
|
45
|
+
|
46
|
+
def struct_fields; FIELDS; end
|
47
|
+
|
48
|
+
def validate
|
49
|
+
unless @priority.nil? || ::Priority::VALID_VALUES.include?(@priority)
|
50
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field priority!')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
::Thrift::Struct.generate_accessors self
|
55
|
+
end
|
56
|
+
|
57
|
+
class RawEvent
|
58
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
59
|
+
RAW = 1
|
60
|
+
|
61
|
+
FIELDS = {
|
62
|
+
RAW => {:type => ::Thrift::Types::STRING, :name => 'raw', :binary => true}
|
63
|
+
}
|
64
|
+
|
65
|
+
def struct_fields; FIELDS; end
|
66
|
+
|
67
|
+
def validate
|
68
|
+
end
|
69
|
+
|
70
|
+
::Thrift::Struct.generate_accessors self
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,219 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.9.3)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'thrift'
|
8
|
+
require 'flume_types'
|
9
|
+
|
10
|
+
module ThriftFlumeEventServer
|
11
|
+
class Client
|
12
|
+
include ::Thrift::Client
|
13
|
+
|
14
|
+
def append(evt)
|
15
|
+
send_append(evt)
|
16
|
+
end
|
17
|
+
|
18
|
+
def send_append(evt)
|
19
|
+
send_oneway_message('append', Append_args, :evt => evt)
|
20
|
+
end
|
21
|
+
def rawAppend(evt)
|
22
|
+
send_rawAppend(evt)
|
23
|
+
end
|
24
|
+
|
25
|
+
def send_rawAppend(evt)
|
26
|
+
send_oneway_message('rawAppend', RawAppend_args, :evt => evt)
|
27
|
+
end
|
28
|
+
def ackedAppend(evt)
|
29
|
+
send_ackedAppend(evt)
|
30
|
+
return recv_ackedAppend()
|
31
|
+
end
|
32
|
+
|
33
|
+
def send_ackedAppend(evt)
|
34
|
+
send_message('ackedAppend', AckedAppend_args, :evt => evt)
|
35
|
+
end
|
36
|
+
|
37
|
+
def recv_ackedAppend()
|
38
|
+
result = receive_message(AckedAppend_result)
|
39
|
+
return result.success unless result.success.nil?
|
40
|
+
raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'ackedAppend failed: unknown result')
|
41
|
+
end
|
42
|
+
|
43
|
+
def close()
|
44
|
+
send_close()
|
45
|
+
recv_close()
|
46
|
+
end
|
47
|
+
|
48
|
+
def send_close()
|
49
|
+
send_message('close', Close_args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def recv_close()
|
53
|
+
result = receive_message(Close_result)
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class Processor
|
60
|
+
include ::Thrift::Processor
|
61
|
+
|
62
|
+
def process_append(seqid, iprot, oprot)
|
63
|
+
args = read_args(iprot, Append_args)
|
64
|
+
@handler.append(args.evt)
|
65
|
+
return
|
66
|
+
end
|
67
|
+
|
68
|
+
def process_rawAppend(seqid, iprot, oprot)
|
69
|
+
args = read_args(iprot, RawAppend_args)
|
70
|
+
@handler.rawAppend(args.evt)
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
74
|
+
def process_ackedAppend(seqid, iprot, oprot)
|
75
|
+
args = read_args(iprot, AckedAppend_args)
|
76
|
+
result = AckedAppend_result.new()
|
77
|
+
result.success = @handler.ackedAppend(args.evt)
|
78
|
+
write_result(result, oprot, 'ackedAppend', seqid)
|
79
|
+
end
|
80
|
+
|
81
|
+
def process_close(seqid, iprot, oprot)
|
82
|
+
args = read_args(iprot, Close_args)
|
83
|
+
result = Close_result.new()
|
84
|
+
@handler.close()
|
85
|
+
write_result(result, oprot, 'close', seqid)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# HELPER FUNCTIONS AND STRUCTURES
|
91
|
+
|
92
|
+
class Append_args
|
93
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
94
|
+
EVT = 1
|
95
|
+
|
96
|
+
FIELDS = {
|
97
|
+
EVT => {:type => ::Thrift::Types::STRUCT, :name => 'evt', :class => ::ThriftFlumeEvent}
|
98
|
+
}
|
99
|
+
|
100
|
+
def struct_fields; FIELDS; end
|
101
|
+
|
102
|
+
def validate
|
103
|
+
end
|
104
|
+
|
105
|
+
::Thrift::Struct.generate_accessors self
|
106
|
+
end
|
107
|
+
|
108
|
+
class Append_result
|
109
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
110
|
+
|
111
|
+
FIELDS = {
|
112
|
+
|
113
|
+
}
|
114
|
+
|
115
|
+
def struct_fields; FIELDS; end
|
116
|
+
|
117
|
+
def validate
|
118
|
+
end
|
119
|
+
|
120
|
+
::Thrift::Struct.generate_accessors self
|
121
|
+
end
|
122
|
+
|
123
|
+
class RawAppend_args
|
124
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
125
|
+
EVT = 1
|
126
|
+
|
127
|
+
FIELDS = {
|
128
|
+
EVT => {:type => ::Thrift::Types::STRUCT, :name => 'evt', :class => ::RawEvent}
|
129
|
+
}
|
130
|
+
|
131
|
+
def struct_fields; FIELDS; end
|
132
|
+
|
133
|
+
def validate
|
134
|
+
end
|
135
|
+
|
136
|
+
::Thrift::Struct.generate_accessors self
|
137
|
+
end
|
138
|
+
|
139
|
+
class RawAppend_result
|
140
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
141
|
+
|
142
|
+
FIELDS = {
|
143
|
+
|
144
|
+
}
|
145
|
+
|
146
|
+
def struct_fields; FIELDS; end
|
147
|
+
|
148
|
+
def validate
|
149
|
+
end
|
150
|
+
|
151
|
+
::Thrift::Struct.generate_accessors self
|
152
|
+
end
|
153
|
+
|
154
|
+
class AckedAppend_args
|
155
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
156
|
+
EVT = 1
|
157
|
+
|
158
|
+
FIELDS = {
|
159
|
+
EVT => {:type => ::Thrift::Types::STRUCT, :name => 'evt', :class => ::ThriftFlumeEvent}
|
160
|
+
}
|
161
|
+
|
162
|
+
def struct_fields; FIELDS; end
|
163
|
+
|
164
|
+
def validate
|
165
|
+
end
|
166
|
+
|
167
|
+
::Thrift::Struct.generate_accessors self
|
168
|
+
end
|
169
|
+
|
170
|
+
class AckedAppend_result
|
171
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
172
|
+
SUCCESS = 0
|
173
|
+
|
174
|
+
FIELDS = {
|
175
|
+
SUCCESS => {:type => ::Thrift::Types::I32, :name => 'success', :enum_class => ::EventStatus}
|
176
|
+
}
|
177
|
+
|
178
|
+
def struct_fields; FIELDS; end
|
179
|
+
|
180
|
+
def validate
|
181
|
+
unless @success.nil? || ::EventStatus::VALID_VALUES.include?(@success)
|
182
|
+
raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field success!')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
::Thrift::Struct.generate_accessors self
|
187
|
+
end
|
188
|
+
|
189
|
+
class Close_args
|
190
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
191
|
+
|
192
|
+
FIELDS = {
|
193
|
+
|
194
|
+
}
|
195
|
+
|
196
|
+
def struct_fields; FIELDS; end
|
197
|
+
|
198
|
+
def validate
|
199
|
+
end
|
200
|
+
|
201
|
+
::Thrift::Struct.generate_accessors self
|
202
|
+
end
|
203
|
+
|
204
|
+
class Close_result
|
205
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
206
|
+
|
207
|
+
FIELDS = {
|
208
|
+
|
209
|
+
}
|
210
|
+
|
211
|
+
def struct_fields; FIELDS; end
|
212
|
+
|
213
|
+
def validate
|
214
|
+
end
|
215
|
+
|
216
|
+
::Thrift::Struct.generate_accessors self
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
@@ -19,91 +19,90 @@
|
|
19
19
|
require 'fluent/output'
|
20
20
|
|
21
21
|
module Fluent
|
22
|
+
class FlumeOutput < BufferedOutput
|
23
|
+
Fluent::Plugin.register_output('flume', self)
|
24
|
+
|
25
|
+
config_param :host, :string, :default => 'localhost'
|
26
|
+
config_param :port, :integer, :default => 35863
|
27
|
+
config_param :timeout, :integer, :default => 30
|
28
|
+
config_param :remove_prefix, :string, :default => nil
|
29
|
+
config_param :default_category, :string, :default => 'unknown'
|
30
|
+
desc "The format of the thrift body. (default: json)"
|
31
|
+
config_param :format, :string, default: 'json'
|
32
|
+
config_param :trim_nl, :bool, default: true
|
33
|
+
|
34
|
+
unless method_defined?(:log)
|
35
|
+
define_method(:log) { $log }
|
36
|
+
end
|
22
37
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
desc "The format of the thrift body. (default: json)"
|
32
|
-
config_param :format, :string, default: 'json'
|
33
|
-
config_param :trim_nl, :bool, default: true
|
34
|
-
|
35
|
-
unless method_defined?(:log)
|
36
|
-
define_method(:log) { $log }
|
37
|
-
end
|
38
|
-
|
39
|
-
def initialize
|
40
|
-
require 'thrift'
|
41
|
-
$:.unshift File.join(File.dirname(__FILE__), 'thrift')
|
42
|
-
require 'flume_types'
|
43
|
-
require 'flume_constants'
|
44
|
-
require 'thrift_source_protocol'
|
45
|
-
super
|
46
|
-
end
|
38
|
+
def initialize
|
39
|
+
require 'thrift'
|
40
|
+
require 'fluent/plugin/thrift/flume_types'
|
41
|
+
$:.unshift File.join(File.dirname(__FILE__), 'thrift')
|
42
|
+
require 'flume_constants'
|
43
|
+
require 'thrift_source_protocol'
|
44
|
+
super
|
45
|
+
end
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
def configure(conf)
|
48
|
+
# override default buffer_chunk_limit
|
49
|
+
conf['buffer_chunk_limit'] ||= '1m'
|
51
50
|
|
52
|
-
|
51
|
+
super
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
@formatter = Plugin.new_formatter(@format)
|
54
|
+
@formatter.configure(conf)
|
55
|
+
end
|
57
56
|
|
58
|
-
|
59
|
-
|
57
|
+
def start
|
58
|
+
super
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
if @remove_prefix
|
61
|
+
@removed_prefix_string = @remove_prefix + '.'
|
62
|
+
@removed_length = @removed_prefix_string.length
|
63
|
+
end
|
64
64
|
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def shutdown
|
68
|
-
super
|
69
|
-
end
|
70
65
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
def emit(tag, es, chain)
|
67
|
+
if @remove_prefix and
|
68
|
+
((tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or tag == @remove_prefix)
|
69
|
+
tag = (tag[@removed_length..-1] || @default_category)
|
70
|
+
end
|
71
|
+
super(tag, es, chain, tag)
|
75
72
|
end
|
76
|
-
fr = @formatter.format(tag, time, record)
|
77
|
-
fr.chomp! if @trim_nl
|
78
|
-
[tag, time, fr].to_msgpack
|
79
|
-
end
|
80
73
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
client = ThriftSourceProtocol::Client.new protocol
|
74
|
+
def format(tag, time, record)
|
75
|
+
fr = @formatter.format(tag, time, record)
|
76
|
+
fr.chomp! if @trim_nl
|
77
|
+
[time, fr].to_msgpack
|
78
|
+
end
|
87
79
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
80
|
+
def write(chunk)
|
81
|
+
socket = Thrift::Socket.new @host, @port, @timeout
|
82
|
+
transport = Thrift::FramedTransport.new socket
|
83
|
+
#protocol = Thrift::BinaryProtocol.new transport, false, false
|
84
|
+
protocol = Thrift::CompactProtocol.new transport
|
85
|
+
client = ThriftSourceProtocol::Client.new protocol
|
86
|
+
|
87
|
+
tag = chunk.key
|
88
|
+
count = 0
|
89
|
+
header = {}
|
90
|
+
transport.open
|
91
|
+
log.debug "thrift client opened: #{client}"
|
92
|
+
begin
|
93
|
+
chunk.msgpack_each { |time, record|
|
94
|
+
header['timestamp'.freeze] = time.to_s
|
95
|
+
header['tag'.freeze] = tag
|
96
|
+
entry = ThriftFlumeEvent.new(:body => record.force_encoding('UTF-8'),
|
97
|
+
:headers => header)
|
98
|
+
client.append entry
|
99
|
+
count += 1
|
100
|
+
}
|
101
|
+
log.debug "Writing #{count} entries to flume"
|
102
|
+
ensure
|
103
|
+
log.debug "thrift client closing: #{client}"
|
104
|
+
transport.close
|
105
|
+
end
|
105
106
|
end
|
106
107
|
end
|
107
108
|
end
|
108
|
-
|
109
|
-
end
|
@@ -160,9 +160,9 @@ class FlumeInputTest < Test::Unit::TestCase
|
|
160
160
|
def test_message_format_json
|
161
161
|
d = create_driver(CONFIG + %[
|
162
162
|
tag_field category
|
163
|
-
|
163
|
+
msg_format json
|
164
164
|
])
|
165
|
-
assert_equal 'json', d.instance.
|
165
|
+
assert_equal 'json', d.instance.msg_format
|
166
166
|
|
167
167
|
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
168
168
|
Fluent::Engine.now = time
|
@@ -185,8 +185,6 @@ class FlumeInputTest < Test::Unit::TestCase
|
|
185
185
|
end
|
186
186
|
|
187
187
|
def setup
|
188
|
-
omit("Latest flume thrift protocol does not have event server.")
|
189
|
-
|
190
188
|
Fluent::FlumeInput.new
|
191
189
|
Fluent::Test.setup
|
192
190
|
end
|
@@ -41,9 +41,8 @@ class FlumeOutputTest < Test::Unit::TestCase
|
|
41
41
|
d = create_driver
|
42
42
|
d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
|
43
43
|
d.emit({"k21"=>"v21", "k22"=>"v22"}, time)
|
44
|
-
|
45
|
-
d.expect_format [
|
46
|
-
d.expect_format [d.tag, time, {"k21"=>"v21", "k22"=>"v22"}.to_json].to_msgpack
|
44
|
+
d.expect_format [time, {"k11"=>"v11", "k12"=>"v12"}.to_json].to_msgpack
|
45
|
+
d.expect_format [time, {"k21"=>"v21", "k22"=>"v22"}.to_json].to_msgpack
|
47
46
|
d.run
|
48
47
|
|
49
48
|
d = create_driver(CONFIG + %[
|
@@ -53,8 +52,8 @@ class FlumeOutputTest < Test::Unit::TestCase
|
|
53
52
|
|
54
53
|
d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
|
55
54
|
d.emit({"k21"=>"v21", "k22"=>"v22"}, time)
|
56
|
-
d.expect_format [
|
57
|
-
d.expect_format [
|
55
|
+
d.expect_format [time, {"k11"=>"v11", "k12"=>"v12"}.to_json].to_msgpack
|
56
|
+
d.expect_format [time, {"k21"=>"v21", "k22"=>"v22"}.to_json].to_msgpack
|
58
57
|
d.run
|
59
58
|
|
60
59
|
d = create_driver(CONFIG + %[
|
@@ -62,7 +61,7 @@ class FlumeOutputTest < Test::Unit::TestCase
|
|
62
61
|
], 'xxx.test.flumeplugin')
|
63
62
|
assert_equal 'xxx.test.flumeplugin', d.tag
|
64
63
|
d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
|
65
|
-
d.expect_format [
|
64
|
+
d.expect_format [time, {"k11"=>"v11", "k12"=>"v12"}.to_json].to_msgpack
|
66
65
|
d.run
|
67
66
|
|
68
67
|
d = create_driver(CONFIG + %[
|
@@ -70,7 +69,7 @@ class FlumeOutputTest < Test::Unit::TestCase
|
|
70
69
|
], 'test')
|
71
70
|
assert_equal 'test', d.tag
|
72
71
|
d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
|
73
|
-
d.expect_format [
|
72
|
+
d.expect_format [time, {"k11"=>"v11", "k12"=>"v12"}.to_json].to_msgpack
|
74
73
|
d.run
|
75
74
|
|
76
75
|
d = create_driver(CONFIG + %[
|
@@ -79,8 +78,8 @@ class FlumeOutputTest < Test::Unit::TestCase
|
|
79
78
|
assert_equal 'test.flumeplugin', d.tag
|
80
79
|
d.emit({"k11"=>"v11", "k12"=>"v12"}, time)
|
81
80
|
d.emit({"k21"=>"v21", "k22"=>"v22"}, time)
|
82
|
-
d.expect_format [
|
83
|
-
d.expect_format [
|
81
|
+
d.expect_format [time, {"k11"=>"v11", "k12"=>"v12"}.to_json].to_msgpack
|
82
|
+
d.expect_format [time, {"k21"=>"v21", "k22"=>"v22"}.to_json].to_msgpack
|
84
83
|
d.run
|
85
84
|
end
|
86
85
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-flume
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Muga Nishizawa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -86,6 +86,10 @@ files:
|
|
86
86
|
- example-out-flume.conf
|
87
87
|
- fluent-plugin-flume.gemspec
|
88
88
|
- lib/fluent/plugin/in_flume.rb
|
89
|
+
- lib/fluent/plugin/old_thrift/flume.thrift
|
90
|
+
- lib/fluent/plugin/old_thrift/flume_constants.rb
|
91
|
+
- lib/fluent/plugin/old_thrift/flume_types.rb
|
92
|
+
- lib/fluent/plugin/old_thrift/thrift_flume_event_server.rb
|
89
93
|
- lib/fluent/plugin/out_flume.rb
|
90
94
|
- lib/fluent/plugin/thrift/flume.thrift
|
91
95
|
- lib/fluent/plugin/thrift/flume.thrift.orig
|