fluent-plugin-flume 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/ChangeLog +1 -0
- data/README.rdoc +105 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/bin/fluent-flume-remote +28 -0
- data/fluent-plugin-flume.gemspec +56 -0
- data/lib/fluent/plugin/in_flume.rb +164 -0
- data/lib/fluent/plugin/out_flume.rb +96 -0
- data/lib/fluent/plugin/thrift/flume.thrift +72 -0
- data/lib/fluent/plugin/thrift/flume.thrift.orig +72 -0
- data/lib/fluent/plugin/thrift/flume_constants.rb +8 -0
- data/lib/fluent/plugin/thrift/flume_types.rb +71 -0
- data/lib/fluent/plugin/thrift/thrift_flume_event_server.rb +220 -0
- data/test/plugin/test_in_flume.rb +209 -0
- data/test/plugin/test_out_flume.rb +177 -0
- metadata +87 -0
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Muga Nishizawa <muga.nishizawa _at_ gmail.com>
|
data/ChangeLog
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Release 0.1.0 - 2012/05/02
|
data/README.rdoc
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
= Flume input/output plugin for Fluent
|
2
|
+
|
3
|
+
== Overview
|
4
|
+
|
5
|
+
This is a plugin for fluentd[https://github.com/fluentd] event collector. This plugin adds the Flume[https://github.com/apache/flume] compatible interface to fluentd.
|
6
|
+
|
7
|
+
== What's Flume?
|
8
|
+
|
9
|
+
Flume[https://github.com/apache/flume] is a distributed, reliable, and available service for efficiently collecting, aggregating, and moving large amounts of log data.
|
10
|
+
|
11
|
+
It uses Thrift[http://thrift.apache.org/], a cross-language RPC framework, to communicate between clients and servers.
|
12
|
+
|
13
|
+
== What's Flume plugin for fluent?
|
14
|
+
|
15
|
+
The Flume plugin for fluentd, which enables fluentd to talk the Flume protocol. Flume protocol is defined as follows, in Thrift-IDL format:
|
16
|
+
|
17
|
+
typedef i64 Timestamp
|
18
|
+
|
19
|
+
enum Priority {
|
20
|
+
FATAL = 0,
|
21
|
+
ERROR = 1,
|
22
|
+
WARN = 2,
|
23
|
+
INFO = 3,
|
24
|
+
DEBUG = 4,
|
25
|
+
TRACE = 5
|
26
|
+
}
|
27
|
+
|
28
|
+
enum EventStatus {
|
29
|
+
ACK = 0,
|
30
|
+
COMMITED = 1,
|
31
|
+
ERR = 2
|
32
|
+
}
|
33
|
+
|
34
|
+
struct ThriftFlumeEvent {
|
35
|
+
1: Timestamp timestamp,
|
36
|
+
2: Priority priority,
|
37
|
+
3: binary body,
|
38
|
+
4: i64 nanos,
|
39
|
+
5: string host,
|
40
|
+
6: map<string,binary> fields
|
41
|
+
}
|
42
|
+
|
43
|
+
# Instead of using thrift's serialization, we just assume the contents are serialized already.
|
44
|
+
struct RawEvent {
|
45
|
+
1: binary raw
|
46
|
+
}
|
47
|
+
|
48
|
+
service ThriftFlumeEventServer {
|
49
|
+
oneway void append( 1:ThriftFlumeEvent evt ),
|
50
|
+
oneway void rawAppend( 1:RawEvent evt),
|
51
|
+
EventStatus ackedAppend( 1: ThriftFlumeEvent evt ),
|
52
|
+
|
53
|
+
void close(),
|
54
|
+
}
|
55
|
+
|
56
|
+
A value that is stored in the ThriftFlumeEvent.fields map is used as fluentd 'tag'. A key of the value enables be specified by users as configuration parameter.
|
57
|
+
|
58
|
+
== How to use?
|
59
|
+
|
60
|
+
fluent-plugin-flume contains both input and output.
|
61
|
+
|
62
|
+
== Flume Input
|
63
|
+
|
64
|
+
Please add the following configurations to fluent.conf.
|
65
|
+
|
66
|
+
# Flume input
|
67
|
+
<source>
|
68
|
+
type flume
|
69
|
+
port 56789
|
70
|
+
</source>
|
71
|
+
|
72
|
+
These options are supported.
|
73
|
+
|
74
|
+
* port: port number (default: 56789)
|
75
|
+
* bind: bind address (default: 0.0.0.0)
|
76
|
+
* server_type: server architecture either in 'simple', 'threaded', 'thread_pool', (default: simple)
|
77
|
+
* is_framed: use framed protocol or not (default: false)
|
78
|
+
* tag_field: key name of fluentd 'tag' that is stored in ThriftFlumeEvent.fields (default: nil)
|
79
|
+
* default_tag: default fluentd 'tag' (default: 'category')
|
80
|
+
* add_prefix: prefix string, added to the tag (default: nil)
|
81
|
+
|
82
|
+
== Flume Output
|
83
|
+
|
84
|
+
Please add the following configurations to fluent.conf. This allows fluentd to output its logs into another Flume server. Note that fluentd conveys semi-structured data while Flume conveys unstructured data. Thus the plugin translates semi-structured data into JSON data and conveys it to Flume.
|
85
|
+
|
86
|
+
# Flume output
|
87
|
+
<match *>
|
88
|
+
type flume
|
89
|
+
host flume-host.local
|
90
|
+
port 56789
|
91
|
+
</match>
|
92
|
+
|
93
|
+
These options are supported.
|
94
|
+
|
95
|
+
* host: host name or address (default: localhost)
|
96
|
+
* port: port number (default: 35863)
|
97
|
+
* timeout: thrift protocol timeout (default: 30)
|
98
|
+
* remove_prefix: prefix string, removed from the tag (default: nil)
|
99
|
+
|
100
|
+
== Contributors
|
101
|
+
|
102
|
+
== Copyright
|
103
|
+
|
104
|
+
Copyright:: Copyright (c) 2012 Treasure Data, Inc.
|
105
|
+
License:: Apache License, Version 2.0
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/clean'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gemspec|
|
8
|
+
gemspec.name = "fluent-plugin-flume"
|
9
|
+
gemspec.summary = "Flume Input/Output plugin for Fluentd event collector"
|
10
|
+
gemspec.author = "Muga Nishizawa"
|
11
|
+
gemspec.email = "muga.nishizawa@gmail.com"
|
12
|
+
gemspec.homepage = "https://github.com/muga/fluent-plugin-flume"
|
13
|
+
gemspec.has_rdoc = false
|
14
|
+
gemspec.require_paths = ["lib"]
|
15
|
+
gemspec.add_dependency "fluentd", "~> 0.10.16"
|
16
|
+
gemspec.add_dependency "thrift", "~> 0.6.0"
|
17
|
+
gemspec.test_files = Dir["test/**/*.rb"]
|
18
|
+
gemspec.files = Dir["bin/**/*", "lib/**/*", "test/**/*.rb"] +
|
19
|
+
%w[example.conf VERSION AUTHORS Rakefile fluent-plugin-flume.gemspec]
|
20
|
+
gemspec.executables = ['fluent-flume-remote']
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
task "thrift_gen" do
|
28
|
+
system "mkdir -p tmp"
|
29
|
+
system "thrift --gen rb -o tmp lib/fluent/plugin/thrift/flume.thrift"
|
30
|
+
system "mv tmp/gen-rb/* lib/fluent/plugin/thrift/"
|
31
|
+
system "rm -fR tmp"
|
32
|
+
end
|
33
|
+
|
34
|
+
Rake::TestTask.new(:test) do |t|
|
35
|
+
t.test_files = Dir['test/plugin/*.rb']
|
36
|
+
t.ruby_opts = ['-rubygems'] if defined? Gem
|
37
|
+
t.ruby_opts << '-I.'
|
38
|
+
end
|
39
|
+
|
40
|
+
#VERSION_FILE = "lib/fluent/version.rb"
|
41
|
+
#
|
42
|
+
#file VERSION_FILE => ["VERSION"] do |t|
|
43
|
+
# version = File.read("VERSION").strip
|
44
|
+
# File.open(VERSION_FILE, "w") {|f|
|
45
|
+
# f.write <<EOF
|
46
|
+
#module Fluent
|
47
|
+
#
|
48
|
+
#VERSION = '#{version}'
|
49
|
+
#
|
50
|
+
#end
|
51
|
+
#EOF
|
52
|
+
# }
|
53
|
+
#end
|
54
|
+
#
|
55
|
+
#task :default => [VERSION_FILE, :build]
|
56
|
+
|
57
|
+
task :default => [:build]
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thrift'
|
3
|
+
require 'json'
|
4
|
+
$:.unshift File.join(File.dirname(__FILE__), '../lib/fluent/plugin/thrift')
|
5
|
+
require 'flume_types'
|
6
|
+
require 'flume_constants'
|
7
|
+
require 'thrift_flume_event_server'
|
8
|
+
|
9
|
+
host = 'localhost'
|
10
|
+
port = 3586
|
11
|
+
|
12
|
+
socket = Thrift::Socket.new host, port.to_i
|
13
|
+
transport = Thrift::BufferedTransport.new socket
|
14
|
+
protocol = Thrift::BinaryProtocol.new transport
|
15
|
+
client = ThriftFlumeEventServer::Client.new protocol
|
16
|
+
transport.open
|
17
|
+
|
18
|
+
# 2011/09/02 Kazuki Ohta <kazuki.ohta@gmail.com>
|
19
|
+
# explicitly specify TCP_NODELAY for low-latency communication.
|
20
|
+
raw_sock = socket.to_io
|
21
|
+
raw_sock.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
|
22
|
+
|
23
|
+
entry = ThriftFlumeEvent.new(:body=>{'a'=>'b'}.to_json,
|
24
|
+
:priority=>Priority::INFO,
|
25
|
+
:timestamp=>(Time.now.to_i * 1000))
|
26
|
+
client.append entry
|
27
|
+
|
28
|
+
transport.close
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "fluent-plugin-flume"
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Muga Nishizawa"]
|
12
|
+
s.date = "2012-04-07"
|
13
|
+
s.email = "muga.nishizawa@gmail.com"
|
14
|
+
s.executables = ["fluent-flume-remote"]
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"ChangeLog",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"AUTHORS",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"bin/fluent-flume-remote",
|
24
|
+
"example.conf",
|
25
|
+
"fluent-plugin-flume.gemspec",
|
26
|
+
"lib/fluent/plugin/in_flume.rb",
|
27
|
+
"lib/fluent/plugin/out_flume.rb",
|
28
|
+
"lib/fluent/plugin/thrift/flume.thrift",
|
29
|
+
"lib/fluent/plugin/thrift/flume.thrift.orig",
|
30
|
+
"lib/fluent/plugin/thrift/flume_constants.rb",
|
31
|
+
"lib/fluent/plugin/thrift/flume_types.rb",
|
32
|
+
"lib/fluent/plugin/thrift/thrift_flume_event_server.rb",
|
33
|
+
"test/plugin/out_flume.rb"
|
34
|
+
]
|
35
|
+
s.homepage = "https://github.com/muga/fluent-plugin-flume"
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = "1.8.15"
|
38
|
+
s.summary = "Flume Input/Output plugin for Fluentd event collector"
|
39
|
+
s.test_files = ["test/plugin/out_flume.rb"]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_runtime_dependency(%q<fluentd>, ["~> 0.10.16"])
|
46
|
+
s.add_runtime_dependency(%q<thrift>, ["~> 0.6.0"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<fluentd>, ["~> 0.10.16"])
|
49
|
+
s.add_dependency(%q<thrift>, ["~> 0.6.0"])
|
50
|
+
end
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<fluentd>, ["~> 0.10.16"])
|
53
|
+
s.add_dependency(%q<thrift>, ["~> 0.6.0"])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012 Muga Nishizawa
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# 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
|
+
module Fluent
|
19
|
+
|
20
|
+
class FlumeInput < Input
|
21
|
+
Plugin.register_input('flume', self)
|
22
|
+
|
23
|
+
config_param :port, :integer, :default => 56789
|
24
|
+
config_param :bind, :string, :default => '0.0.0.0'
|
25
|
+
config_param :server_type, :string, :default => 'simple'
|
26
|
+
config_param :is_framed, :bool, :default => false
|
27
|
+
config_param :body_size_limit, :size, :default => 32*1024*1024 # TODO default
|
28
|
+
config_param :tag_field, :string, :default => nil
|
29
|
+
config_param :default_tag, :string, :default => 'category'
|
30
|
+
config_param :add_prefix, :string, :default => nil
|
31
|
+
config_param :message_format, :string, :default => 'text'
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
require 'thrift'
|
35
|
+
$:.unshift File.join(File.dirname(__FILE__), 'thrift')
|
36
|
+
require 'flume_types'
|
37
|
+
require 'flume_constants'
|
38
|
+
require 'thrift_flume_event_server'
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def configure(conf)
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
def start
|
48
|
+
$log.debug "listening flume on #{@bind}:#{@port}"
|
49
|
+
|
50
|
+
handler = FluentFlumeHandler.new
|
51
|
+
handler.tag_field = @tag_field
|
52
|
+
handler.default_tag = @default_tag
|
53
|
+
handler.add_prefix = @add_prefix
|
54
|
+
handler.message_format = @message_format
|
55
|
+
processor = ThriftFlumeEventServer::Processor.new handler
|
56
|
+
|
57
|
+
@transport = Thrift::ServerSocket.new @bind, @port
|
58
|
+
unless @is_framed
|
59
|
+
transport_factory = Thrift::BufferedTransportFactory.new
|
60
|
+
else
|
61
|
+
raise ConfigError, "in_flume: unsupported is_framed '#{@is_framed}'"
|
62
|
+
end
|
63
|
+
|
64
|
+
unless ['text', 'json'].include? @message_format
|
65
|
+
raise 'Unknown format: message_format=#{@message_format}'
|
66
|
+
end
|
67
|
+
|
68
|
+
# 2011/09/29 Kazuki Ohta <kazuki.ohta@gmail.com>
|
69
|
+
# This section is a workaround to set strict_read and strict_write option.
|
70
|
+
# Ruby-Thrift 0.7 set them both 'true' in default, but Flume protocol set
|
71
|
+
# them both 'false'.
|
72
|
+
protocol_factory = Thrift::BinaryProtocolFactory.new
|
73
|
+
protocol_factory.instance_eval {|obj|
|
74
|
+
def get_protocol(trans) # override
|
75
|
+
return Thrift::BinaryProtocol.new(trans,
|
76
|
+
strict_read=false,
|
77
|
+
strict_write=false)
|
78
|
+
end
|
79
|
+
}
|
80
|
+
|
81
|
+
case @server_type
|
82
|
+
when 'simple'
|
83
|
+
@server = Thrift::SimpleServer.new processor, @transport, transport_factory, protocol_factory
|
84
|
+
when 'threaded'
|
85
|
+
@server = Thrift::ThreadedServer.new processor, @transport, transport_factory, protocol_factory
|
86
|
+
when 'thread_pool'
|
87
|
+
@server = Thrift::ThreadPoolServer.new processor, @transport, transport_factory, protocol_factory
|
88
|
+
else
|
89
|
+
raise ConfigError, "in_flume: unsupported server_type '#{@server_type}'"
|
90
|
+
end
|
91
|
+
@thread = Thread.new(&method(:run))
|
92
|
+
end
|
93
|
+
|
94
|
+
def shutdown
|
95
|
+
@transport.close unless @transport.closed? # TODO
|
96
|
+
#@thread.join # TODO
|
97
|
+
end
|
98
|
+
|
99
|
+
def run
|
100
|
+
$log.debug "starting server: #{@server}"
|
101
|
+
@server.serve
|
102
|
+
rescue
|
103
|
+
$log.error "unexpected error", :error=>$!.to_s
|
104
|
+
$log.error_backtrace
|
105
|
+
end
|
106
|
+
|
107
|
+
class FluentFlumeHandler
|
108
|
+
attr_accessor :tag_field
|
109
|
+
attr_accessor :default_tag
|
110
|
+
attr_accessor :add_prefix
|
111
|
+
attr_accessor :message_format
|
112
|
+
|
113
|
+
def append(evt)
|
114
|
+
begin
|
115
|
+
record = create_record(evt)
|
116
|
+
if @tag_field
|
117
|
+
tag = evt.fieldss[@tag_field] || @default_tag
|
118
|
+
unless tag
|
119
|
+
return # ignore
|
120
|
+
end
|
121
|
+
else
|
122
|
+
tag = @default_tag
|
123
|
+
end
|
124
|
+
timestamp = evt.timestamp.to_i
|
125
|
+
if @add_prefix
|
126
|
+
Engine.emit(@add_prefix + '.' + tag, timestamp, record)
|
127
|
+
else
|
128
|
+
Engine.emit(tag, timestamp, record)
|
129
|
+
end
|
130
|
+
rescue => e
|
131
|
+
$log.error "unexpected error", :error=>$!.to_s
|
132
|
+
$log.error_backtrace
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def rawAppend(evt)
|
137
|
+
$log.error "rawAppend is not implemented yet: #{evt}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def ackedAppend(evt)
|
141
|
+
$log.error "ackedAppend is not implemented yet: #{evt}"
|
142
|
+
EventStatus::OK
|
143
|
+
end
|
144
|
+
|
145
|
+
def close()
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
def create_record(evt)
|
150
|
+
case @message_format
|
151
|
+
when 'text'
|
152
|
+
return {'message'=>evt.body.force_encoding('UTF-8')}
|
153
|
+
when 'json'
|
154
|
+
js = JSON.parse(evt.body.force_encoding('UTF-8'))
|
155
|
+
raise 'body must be a Hash, if json_body=true' unless js.is_a?(Hash)
|
156
|
+
return js
|
157
|
+
else
|
158
|
+
raise 'Invalid format: #{@message_format}'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
# Fluent
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012 Muga Nishizawa
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# 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
|
+
module Fluent
|
19
|
+
|
20
|
+
class FlumeOutput < BufferedOutput
|
21
|
+
Fluent::Plugin.register_output('flume', self)
|
22
|
+
|
23
|
+
config_param :host, :string, :default => 'localhost'
|
24
|
+
config_param :port, :integer, :default => 35863
|
25
|
+
config_param :timeout, :integer, :default => 30
|
26
|
+
config_param :remove_prefix, :string, :default => nil
|
27
|
+
config_param :default_category, :string, :default => 'unknown'
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
require 'thrift'
|
31
|
+
$:.unshift File.join(File.dirname(__FILE__), 'thrift')
|
32
|
+
require 'flume_types'
|
33
|
+
require 'flume_constants'
|
34
|
+
require 'thrift_flume_event_server'
|
35
|
+
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def configure(conf)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def start
|
44
|
+
super
|
45
|
+
|
46
|
+
if @remove_prefix
|
47
|
+
@removed_prefix_string = @remove_prefix + '.'
|
48
|
+
@removed_length = @removed_prefix_string.length
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def shutdown
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
def format(tag, time, record)
|
57
|
+
if @remove_prefix and
|
58
|
+
( (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or
|
59
|
+
tag == @remove_prefix)
|
60
|
+
[(tag[@removed_length..-1] || @default_category), time, record].to_msgpack
|
61
|
+
else
|
62
|
+
[tag, time, record].to_msgpack
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def write(chunk)
|
67
|
+
records = []
|
68
|
+
chunk.msgpack_each { |arr|
|
69
|
+
records << arr
|
70
|
+
}
|
71
|
+
|
72
|
+
transport = Thrift::Socket.new @host, @port, @timeout
|
73
|
+
#transport = Thrift::FramedTransport.new socket
|
74
|
+
#protocol = Thrift::BinaryProtocol.new transport, false, false
|
75
|
+
protocol = Thrift::BinaryProtocol.new transport
|
76
|
+
client = ThriftFlumeEventServer::Client.new protocol
|
77
|
+
|
78
|
+
transport.open
|
79
|
+
$log.debug "thrift client opend: #{client}"
|
80
|
+
begin
|
81
|
+
records.each { |r|
|
82
|
+
tag, time, record = r
|
83
|
+
entry = ThriftFlumeEvent.new(:body=>record.to_json.to_s.force_encoding('UTF-8'),
|
84
|
+
:priority=>Priority::INFO,
|
85
|
+
:timestamp=>time,
|
86
|
+
:fieldss=>{'category'=>tag})
|
87
|
+
client.append entry
|
88
|
+
}
|
89
|
+
ensure
|
90
|
+
$log.debug "thrift client closing: #{client}"
|
91
|
+
transport.close
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|