franz 1.6.9 → 2.0.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/Readme.md +34 -6
- data/VERSION +1 -1
- data/bin/franz +29 -8
- data/franz.gemspec +2 -0
- data/lib/franz/output/kafka.rb +135 -0
- data/lib/franz/output/rabbitmq.rb +101 -0
- data/lib/franz/output/stdout.rb +70 -0
- data/lib/franz/output.rb +3 -120
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3daab71d5207b3f6b7e32c4799ada5d1c1597f64
|
4
|
+
data.tar.gz: f5440a6bff60093e02925e6e0e81804a97ff730c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8e79de017d808a8ea074a313d7fa80de03946174dcb9533afee6d2480a595f882abd829f5c75b100a5ee0f725c36d9dfd438407f7377ad051035fc18e045fd2
|
7
|
+
data.tar.gz: 5911d098549d5afa4061bb6e7327355bdabc094d096b3c9b1bc9fa7d839b95e20b07bf857ec04f8b645e05a08b384cc89dd705917e0cb51d1298396391a97ca8
|
data/Readme.md
CHANGED
@@ -9,9 +9,9 @@ doing the bulk of the log processing. Using this setup, RabbitMQ and logstash
|
|
9
9
|
may be scaled and restarted independently, so new configurations may be applied
|
10
10
|
without interrupting those precious log hosts.
|
11
11
|
|
12
|
-
Even so, Franz was designed to be interruped. Before exiting, Franz
|
13
|
-
|
14
|
-
|
12
|
+
Even so, Franz was designed to be interruped. Before exiting, Franz keeps a log
|
13
|
+
of checkpoints, which are used to restore application state in the event of a
|
14
|
+
crash.
|
15
15
|
|
16
16
|
He's also got a couple of improvements over logstash. Let's discuss!
|
17
17
|
|
@@ -19,7 +19,7 @@ He's also got a couple of improvements over logstash. Let's discuss!
|
|
19
19
|
## Improvements
|
20
20
|
|
21
21
|
First let me say logstash is an awesome hunk of software thanks to the hard
|
22
|
-
work of Jordan Sissel and the entire logstash community.
|
22
|
+
work of Jordan Sissel and the entire logstash community.
|
23
23
|
|
24
24
|
### Multiline Flush
|
25
25
|
|
@@ -141,8 +141,12 @@ It's kinda like a JSON version of the Logstash config language:
|
|
141
141
|
"play_catchup?": true // Pick up where we left off
|
142
142
|
},
|
143
143
|
|
144
|
-
|
144
|
+
|
145
|
+
// If you provide both RabbitMQ and Kafka configurations, Franz will
|
146
|
+
// prefer RabbitMQ. If you provide neither, events are printed to STDOUT
|
145
147
|
"output": {
|
148
|
+
|
149
|
+
// RabbitMQ
|
146
150
|
"rabbitmq": {
|
147
151
|
|
148
152
|
// Must be a consistently-hashed exchange!
|
@@ -170,6 +174,20 @@ It's kinda like a JSON version of the Logstash config language:
|
|
170
174
|
}
|
171
175
|
},
|
172
176
|
|
177
|
+
// Kafka (experimental)
|
178
|
+
"kafka": {
|
179
|
+
"client_id": "hostname",
|
180
|
+
"cluster": [ "localhost:9092" ],
|
181
|
+
"type": "sync",
|
182
|
+
"compression_codec": "snappy"
|
183
|
+
"metadata_refresh_interval_ms": 600000,
|
184
|
+
"max_send_retries": 3,
|
185
|
+
"retry_backoff_ms": 100,
|
186
|
+
"required_acks": 0,
|
187
|
+
"ack_timeout_ms": 1500,
|
188
|
+
"socket_timeout_ms": 10000
|
189
|
+
}
|
190
|
+
|
173
191
|
// Advanced configuration (optional)
|
174
192
|
"stats_interval": 60, // Emit statistics periodically
|
175
193
|
"bound": 25000, // Limit output queue size
|
@@ -193,4 +211,14 @@ At Blue Jeans, we deploy Franz with Upstart. Here's a minimal config:
|
|
193
211
|
exec franz
|
194
212
|
|
195
213
|
We actually use the [`bjn_franz` cookbook](https://github.com/sczizzo/bjn-franz-cookbook)
|
196
|
-
for Chef.
|
214
|
+
for Chef.
|
215
|
+
|
216
|
+
### Changelog
|
217
|
+
|
218
|
+
#### v2.0.0
|
219
|
+
|
220
|
+
- Added new outputs: `StdOut`, `Kafka` (experimental)
|
221
|
+
|
222
|
+
#### v1
|
223
|
+
|
224
|
+
Intial implementation of the file-to-RabbitMQ pipeline
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/bin/franz
CHANGED
@@ -69,14 +69,33 @@ statz = Franz::Stats.new \
|
|
69
69
|
interval: (config[:output][:stats_interval] || 300),
|
70
70
|
logger: logger
|
71
71
|
|
72
|
-
|
73
|
-
#
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
72
|
+
|
73
|
+
# Now we'll connect to our output. This creates a new thread in the background,
|
74
|
+
# which will consume the events generated by our input on io
|
75
|
+
if config[:output][:rabbitmq]
|
76
|
+
Franz::Output::RabbitMQ.new \
|
77
|
+
input: io,
|
78
|
+
output: config[:output][:rabbitmq],
|
79
|
+
logger: logger,
|
80
|
+
tags: config[:output][:tags],
|
81
|
+
statz: statz
|
82
|
+
|
83
|
+
elsif config[:output][:kafka]
|
84
|
+
Franz::Output::Kafka.new \
|
85
|
+
input: io,
|
86
|
+
output: config[:output][:kafka],
|
87
|
+
logger: logger,
|
88
|
+
tags: config[:output][:tags],
|
89
|
+
statz: statz
|
90
|
+
|
91
|
+
else
|
92
|
+
Franz::Output::StdOut.new \
|
93
|
+
input: io,
|
94
|
+
logger: logger,
|
95
|
+
tags: config[:output][:tags],
|
96
|
+
statz: statz
|
97
|
+
end
|
98
|
+
|
80
99
|
|
81
100
|
# Franz has only one kind of input, plain text files.
|
82
101
|
Franz::Input.new \
|
@@ -87,6 +106,8 @@ Franz::Input.new \
|
|
87
106
|
checkpoint_interval: config[:checkpoint_interval],
|
88
107
|
statz: statz
|
89
108
|
|
109
|
+
|
110
|
+
|
90
111
|
# Ensure memory doesn't grow too large (> 1GB by default)
|
91
112
|
def mem_kb ; `ps -o rss= -p #{$$}`.strip.to_i ; end
|
92
113
|
|
data/franz.gemspec
CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_runtime_dependency 'colorize', '~> 0.7.0'
|
20
20
|
s.add_runtime_dependency 'deep_merge', '~> 1.0.0'
|
21
21
|
s.add_runtime_dependency 'eventmachine', '= 1.0.5'
|
22
|
+
s.add_runtime_dependency 'poseidon', '~> 0.0.5'
|
23
|
+
s.add_runtime_dependency 'snappy', '~> 0.0.11'
|
22
24
|
|
23
25
|
s.files = `git ls-files`.split("\n")
|
24
26
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'poseidon'
|
5
|
+
require 'deep_merge'
|
6
|
+
|
7
|
+
|
8
|
+
module Franz
|
9
|
+
module Output
|
10
|
+
|
11
|
+
# Kafka output for Franz.
|
12
|
+
class Kafka
|
13
|
+
@@host = Socket.gethostname # We'll apply the hostname to all events
|
14
|
+
|
15
|
+
|
16
|
+
# Start a new output in the background. We'll consume from the input queue
|
17
|
+
# and ship events to STDOUT.
|
18
|
+
#
|
19
|
+
# @param [Hash] opts options for the output
|
20
|
+
# @option opts [Queue] :input ([]) "input" queue
|
21
|
+
# @option opts [Queue] :output ([]) "output" configuration
|
22
|
+
def initialize opts={}
|
23
|
+
opts = {
|
24
|
+
logger: Logger.new(STDOUT),
|
25
|
+
tags: [],
|
26
|
+
input: [],
|
27
|
+
output: {
|
28
|
+
flush_interval: 10,
|
29
|
+
flush_size: 500,
|
30
|
+
client_id: @@host,
|
31
|
+
cluster: %w[ localhost:9092 ],
|
32
|
+
type: 'sync',
|
33
|
+
compression_codec: 'snappy',
|
34
|
+
metadata_refresh_interval_ms: 600000,
|
35
|
+
max_send_retries: 3,
|
36
|
+
retry_backoff_ms: 100,
|
37
|
+
required_acks: 0,
|
38
|
+
ack_timeout_ms: 1500,
|
39
|
+
socket_timeout_ms: 10000
|
40
|
+
}
|
41
|
+
}.deep_merge!(opts)
|
42
|
+
|
43
|
+
@statz = opts[:statz] || Franz::Stats.new
|
44
|
+
@statz.create :num_output, 0
|
45
|
+
|
46
|
+
@logger = opts[:logger]
|
47
|
+
|
48
|
+
@stop = false
|
49
|
+
@foreground = opts[:foreground]
|
50
|
+
|
51
|
+
@flush_size = opts[:output].delete :flush_size
|
52
|
+
@flush_interval = opts[:output].delete :flush_interval
|
53
|
+
|
54
|
+
kafka_cluster = opts[:output].delete :cluster
|
55
|
+
kafka_client_id = opts[:output].delete :client_id
|
56
|
+
kafka_config = opts[:output].map { |k,v| v.is_a?(String) ? v.to_sym : v }
|
57
|
+
|
58
|
+
@kafka = Poseidon::Producer.new \
|
59
|
+
kafka_cluster,
|
60
|
+
kafka_client_id,
|
61
|
+
Hash[kafka_config]
|
62
|
+
|
63
|
+
@lock = Mutex.new
|
64
|
+
@messages = []
|
65
|
+
|
66
|
+
|
67
|
+
@thread = Thread.new do
|
68
|
+
loop do
|
69
|
+
ready_messages = []
|
70
|
+
@lock.synchronize do
|
71
|
+
ready_messages = @messages
|
72
|
+
@messages = []
|
73
|
+
end
|
74
|
+
@kafka.send_messages ready_messages unless ready_messages.empty?
|
75
|
+
log.debug \
|
76
|
+
event: 'periodic flush',
|
77
|
+
num_messages: ready_messages.size
|
78
|
+
sleep @flush_interval
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
@thread = Thread.new do
|
84
|
+
until @stop
|
85
|
+
event = opts[:input].shift
|
86
|
+
|
87
|
+
log.trace \
|
88
|
+
event: 'publish',
|
89
|
+
raw: event
|
90
|
+
|
91
|
+
payload = JSON::generate(event)
|
92
|
+
@messages << Poseidon::MessageToSend.new(event[:type].to_s, payload)
|
93
|
+
|
94
|
+
@statz.inc :num_output
|
95
|
+
|
96
|
+
if @statz.get(:num_output) % @flush_size == 0
|
97
|
+
@kafka.send_messages @messages unless @messages.empty?
|
98
|
+
log.debug \
|
99
|
+
event: 'flush',
|
100
|
+
num_messages: @messages.size
|
101
|
+
@messages = []
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
log.info event: 'output started'
|
108
|
+
|
109
|
+
@thread.join if @foreground
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# Join the Output thread. Effectively only once.
|
114
|
+
def join
|
115
|
+
return if @foreground
|
116
|
+
@foreground = true
|
117
|
+
@thread.join
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
# Stop the Output thread. Effectively only once.
|
122
|
+
def stop
|
123
|
+
return if @foreground
|
124
|
+
@foreground = true
|
125
|
+
@thread.kill
|
126
|
+
log.info event: 'output stopped'
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
private
|
131
|
+
def log ; @logger end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'bunny'
|
4
|
+
require 'deep_merge'
|
5
|
+
|
6
|
+
|
7
|
+
module Franz
|
8
|
+
module Output
|
9
|
+
|
10
|
+
# RabbitMQ output for Franz. You must declare an x-consistent-hash type
|
11
|
+
# exchange, as we generate random Integers for routing keys.
|
12
|
+
class RabbitMQ
|
13
|
+
|
14
|
+
# Start a new output in the background. We'll consume from the input queue
|
15
|
+
# and ship events to the configured RabbitMQ cluster.
|
16
|
+
#
|
17
|
+
# @param [Hash] opts options for the output
|
18
|
+
# @option opts [Queue] :input ([]) "input" queue
|
19
|
+
# @option opts [Hash] :output ({}) "output" configuration
|
20
|
+
def initialize opts={}
|
21
|
+
opts = {
|
22
|
+
logger: Logger.new(STDOUT),
|
23
|
+
tags: [],
|
24
|
+
input: [],
|
25
|
+
output: {
|
26
|
+
exchange: {
|
27
|
+
name: 'test',
|
28
|
+
durable: true
|
29
|
+
},
|
30
|
+
connection: {
|
31
|
+
host: 'localhost',
|
32
|
+
port: 5672
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}.deep_merge!(opts)
|
36
|
+
|
37
|
+
@statz = opts[:statz] || Franz::Stats.new
|
38
|
+
@statz.create :num_output, 0
|
39
|
+
|
40
|
+
@logger = opts[:logger]
|
41
|
+
|
42
|
+
rabbit = Bunny.new opts[:output][:connection].merge({
|
43
|
+
network_recovery_interval: 10.0,
|
44
|
+
continuation_timeout: 10_000,
|
45
|
+
threaded: false,
|
46
|
+
logger: @logger
|
47
|
+
})
|
48
|
+
|
49
|
+
rabbit.start
|
50
|
+
|
51
|
+
channel = rabbit.create_channel
|
52
|
+
exchange = opts[:output][:exchange].delete(:name)
|
53
|
+
exchange = channel.exchange exchange, \
|
54
|
+
{ type: 'x-consistent-hash' }.merge(opts[:output][:exchange])
|
55
|
+
|
56
|
+
@stop = false
|
57
|
+
@foreground = opts[:foreground]
|
58
|
+
|
59
|
+
@thread = Thread.new do
|
60
|
+
rand = Random.new
|
61
|
+
until @stop
|
62
|
+
event = opts[:input].shift
|
63
|
+
|
64
|
+
log.trace \
|
65
|
+
event: 'publish',
|
66
|
+
raw: event
|
67
|
+
|
68
|
+
exchange.publish \
|
69
|
+
JSON::generate(event),
|
70
|
+
routing_key: rand.rand(10_000),
|
71
|
+
persistent: false
|
72
|
+
|
73
|
+
@statz.inc :num_output
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
log.info event: 'output started'
|
78
|
+
|
79
|
+
@thread.join if @foreground
|
80
|
+
end
|
81
|
+
|
82
|
+
# Join the Output thread. Effectively only once.
|
83
|
+
def join
|
84
|
+
return if @foreground
|
85
|
+
@foreground = true
|
86
|
+
@thread.join
|
87
|
+
end
|
88
|
+
|
89
|
+
# Stop the Output thread. Effectively only once.
|
90
|
+
def stop
|
91
|
+
return if @foreground
|
92
|
+
@foreground = true
|
93
|
+
@thread.kill
|
94
|
+
log.info event: 'output stopped'
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def log ; @logger end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'deep_merge'
|
4
|
+
|
5
|
+
|
6
|
+
module Franz
|
7
|
+
module Output
|
8
|
+
|
9
|
+
# STDOUT output for Franz.
|
10
|
+
class StdOut
|
11
|
+
|
12
|
+
# Start a new output in the background. We'll consume from the input queue
|
13
|
+
# and ship events to STDOUT.
|
14
|
+
#
|
15
|
+
# @param [Hash] opts options for the output
|
16
|
+
# @option opts [Queue] :input ([]) "input" queue
|
17
|
+
def initialize opts={}
|
18
|
+
opts = {
|
19
|
+
logger: Logger.new(STDOUT),
|
20
|
+
tags: [],
|
21
|
+
input: []
|
22
|
+
}.deep_merge!(opts)
|
23
|
+
|
24
|
+
@statz = opts[:statz] || Franz::Stats.new
|
25
|
+
@statz.create :num_output, 0
|
26
|
+
|
27
|
+
@logger = opts[:logger]
|
28
|
+
|
29
|
+
@stop = false
|
30
|
+
@foreground = opts[:foreground]
|
31
|
+
|
32
|
+
@thread = Thread.new do
|
33
|
+
until @stop
|
34
|
+
event = opts[:input].shift
|
35
|
+
|
36
|
+
log.trace \
|
37
|
+
event: 'publish',
|
38
|
+
raw: event
|
39
|
+
|
40
|
+
puts JSON::generate(event)
|
41
|
+
|
42
|
+
@statz.inc :num_output
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
log.info event: 'output started'
|
47
|
+
|
48
|
+
@thread.join if @foreground
|
49
|
+
end
|
50
|
+
|
51
|
+
# Join the Output thread. Effectively only once.
|
52
|
+
def join
|
53
|
+
return if @foreground
|
54
|
+
@foreground = true
|
55
|
+
@thread.join
|
56
|
+
end
|
57
|
+
|
58
|
+
# Stop the Output thread. Effectively only once.
|
59
|
+
def stop
|
60
|
+
return if @foreground
|
61
|
+
@foreground = true
|
62
|
+
@thread.kill
|
63
|
+
log.info event: 'output stopped'
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def log ; @logger end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/franz/output.rb
CHANGED
@@ -1,121 +1,4 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
require 'bunny'
|
4
|
-
require 'deep_merge'
|
5
|
-
|
6
1
|
require_relative 'stats'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# RabbitMQ output for Franz. You must declare an x-consistent-hash type
|
12
|
-
# exchange, as we generate random Integers for routing keys.
|
13
|
-
class Output
|
14
|
-
|
15
|
-
# Start a new output in the background. We'll consume from the input queue
|
16
|
-
# and ship events to the configured RabbitMQ cluster.
|
17
|
-
#
|
18
|
-
# @param [Hash] opts options for the output
|
19
|
-
# @option opts [Queue] :input ([]) "input" queue
|
20
|
-
# @option opts [Hash] :output ({}) "output" configuration
|
21
|
-
def initialize opts={}
|
22
|
-
opts = {
|
23
|
-
logger: Logger.new(STDOUT),
|
24
|
-
tags: [],
|
25
|
-
input: [],
|
26
|
-
output: {
|
27
|
-
exchange: {
|
28
|
-
name: 'test',
|
29
|
-
durable: true
|
30
|
-
},
|
31
|
-
connection: {
|
32
|
-
host: 'localhost',
|
33
|
-
port: 5672
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}.deep_merge!(opts)
|
37
|
-
|
38
|
-
@statz = opts[:statz] || Franz::Stats.new
|
39
|
-
@statz.create :num_output, 0
|
40
|
-
|
41
|
-
@logger = opts[:logger]
|
42
|
-
|
43
|
-
rabbit = Bunny.new opts[:output][:connection].merge({
|
44
|
-
network_recovery_interval: 10.0,
|
45
|
-
continuation_timeout: 10_000,
|
46
|
-
threaded: false,
|
47
|
-
logger: @logger
|
48
|
-
})
|
49
|
-
|
50
|
-
rabbit.start
|
51
|
-
|
52
|
-
channel = rabbit.create_channel
|
53
|
-
exchange = opts[:output][:exchange].delete(:name)
|
54
|
-
exchange = channel.exchange exchange, \
|
55
|
-
{ type: 'x-consistent-hash' }.merge(opts[:output][:exchange])
|
56
|
-
|
57
|
-
@stop = false
|
58
|
-
@foreground = opts[:foreground]
|
59
|
-
|
60
|
-
@thread = Thread.new do
|
61
|
-
rand = Random.new
|
62
|
-
until @stop
|
63
|
-
event = opts[:input].shift
|
64
|
-
|
65
|
-
if event[:path]
|
66
|
-
# Can't use sub!, because :path is frozen
|
67
|
-
event[:path] = event[:path].sub '/home/denimuser/seam-builds/rel', ''
|
68
|
-
event[:path] = event[:path].sub '/home/denimuser/seam-builds/live', ''
|
69
|
-
event[:path] = event[:path].sub '/home/denimuser/seam-builds/beta', ''
|
70
|
-
event[:path] = event[:path].sub '/home/denimuser/builds/rel', ''
|
71
|
-
event[:path] = event[:path].sub '/home/denimuser/builds/live', ''
|
72
|
-
event[:path] = event[:path].sub '/home/denimuser/builds/beta', ''
|
73
|
-
event[:path] = event[:path].sub '/home/denimuser/cobalt-builds/rel', ''
|
74
|
-
event[:path] = event[:path].sub '/home/denimuser/cobalt-builds/live', ''
|
75
|
-
event[:path] = event[:path].sub '/home/denimuser/cobalt-builds/beta', ''
|
76
|
-
event[:path] = event[:path].sub '/home/denimuser/rivet-builds', ''
|
77
|
-
event[:path] = event[:path].sub '/home/denimuser/denim/logs', ''
|
78
|
-
event[:path] = event[:path].sub '/home/denimuser/seam/logs', ''
|
79
|
-
event[:path] = event[:path].sub '/home/denimuser/rivet/bjn/logs', ''
|
80
|
-
event[:path] = event[:path].sub '/home/denimuser', ''
|
81
|
-
event[:path] = event[:path].sub '/var/log/franz', ''
|
82
|
-
event[:path] = event[:path].sub '/var/log', ''
|
83
|
-
end
|
84
|
-
|
85
|
-
log.trace \
|
86
|
-
event: 'publish',
|
87
|
-
raw: event
|
88
|
-
|
89
|
-
exchange.publish \
|
90
|
-
JSON::generate(event),
|
91
|
-
routing_key: rand.rand(10_000),
|
92
|
-
persistent: false
|
93
|
-
|
94
|
-
@statz.inc :num_output
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
log.info event: 'output started'
|
99
|
-
|
100
|
-
@thread.join if @foreground
|
101
|
-
end
|
102
|
-
|
103
|
-
# Join the Output thread. Effectively only once.
|
104
|
-
def join
|
105
|
-
return if @foreground
|
106
|
-
@foreground = true
|
107
|
-
@thread.join
|
108
|
-
end
|
109
|
-
|
110
|
-
# Stop the Output thread. Effectively only once.
|
111
|
-
def stop
|
112
|
-
return if @foreground
|
113
|
-
@foreground = true
|
114
|
-
@thread.kill
|
115
|
-
log.info event: 'output stopped'
|
116
|
-
end
|
117
|
-
|
118
|
-
private
|
119
|
-
def log ; @logger end
|
120
|
-
end
|
121
|
-
end
|
2
|
+
require_relative 'output/kafka'
|
3
|
+
require_relative 'output/stdout'
|
4
|
+
require_relative 'output/rabbitmq'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: franz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Clemmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slog
|
@@ -94,6 +94,34 @@ dependencies:
|
|
94
94
|
- - '='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 1.0.5
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: poseidon
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.0.5
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.0.5
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: snappy
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.0.11
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.0.11
|
97
125
|
description: Aggregate log file events and send them elsewhere.
|
98
126
|
email: sclemmer@bluejeans.com
|
99
127
|
executables:
|
@@ -118,6 +146,9 @@ files:
|
|
118
146
|
- lib/franz/input_config.rb
|
119
147
|
- lib/franz/metadata.rb
|
120
148
|
- lib/franz/output.rb
|
149
|
+
- lib/franz/output/kafka.rb
|
150
|
+
- lib/franz/output/rabbitmq.rb
|
151
|
+
- lib/franz/output/stdout.rb
|
121
152
|
- lib/franz/sash.rb
|
122
153
|
- lib/franz/stats.rb
|
123
154
|
- lib/franz/tail.rb
|