logstash-logger 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -5
- data/CHANGELOG.md +5 -0
- data/README.md +36 -0
- data/lib/logstash-logger/device.rb +2 -0
- data/lib/logstash-logger/device/kafka.rb +81 -0
- data/lib/logstash-logger/version.rb +1 -1
- data/logstash-logger.gemspec +2 -1
- data/spec/device/kafka_spec.rb +32 -0
- data/spec/device_spec.rb +5 -0
- data/spec/spec_helper.rb +3 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03eb27ccbc6770bb3348ffcedd6fdc46ba789731
|
4
|
+
data.tar.gz: 3d4d59a4c5a2b5ede515b44595c97fe73949d89d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 454217b66be5ceeaa97f904b0218d1c24651cb865c7cafb1bc69702025b90d8fe8ca3a5337b77296aea8dda1c2e78bce669348708f950195e30706436f8a7c0e
|
7
|
+
data.tar.gz: 3aa6228a59fbd9b540e5dc745caebebb2bfc11d65d16ad7265afd50a10710305e2cfc46ce1802118bbaf3fd8af25286b79c220efc93c7439c06924bb9a514735
|
data/.travis.yml
CHANGED
@@ -2,11 +2,8 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- 1.9.3
|
4
4
|
- 2.0.0
|
5
|
-
- 2.1
|
6
|
-
- 2.
|
7
|
-
- 2.1.2
|
8
|
-
- 2.1.3
|
9
|
-
- 2.2.0
|
5
|
+
- 2.1
|
6
|
+
- 2.2
|
10
7
|
- jruby-19mode
|
11
8
|
- rbx-2
|
12
9
|
gemfile:
|
@@ -14,3 +11,6 @@ gemfile:
|
|
14
11
|
- gemfiles/rails_4.0.gemfile
|
15
12
|
- gemfiles/rails_4.1.gemfile
|
16
13
|
- gemfiles/rails_4.2.gemfile
|
14
|
+
matrix:
|
15
|
+
allow_failures:
|
16
|
+
- rbx-2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.10.0
|
2
|
+
- Support for logging to Kafka.
|
3
|
+
Fixes [#37](https://github.com/dwbutler/logstash-logger/issues/37).
|
4
|
+
Thanks [Felix Bechstein](https://github.com/felixb)!
|
5
|
+
|
1
6
|
## 0.9.0
|
2
7
|
- Support for customizing the fields on all logged messages via configuration.
|
3
8
|
Fixes [#32](https://github.com/dwbutler/logstash-logger/pull/32).
|
data/README.md
CHANGED
@@ -44,6 +44,7 @@ tcp_logger = LogStashLogger.new(type: :tcp, host: 'localhost', port: 5229)
|
|
44
44
|
file_logger = LogStashLogger.new(type: :file, path: 'log/development.log', sync: true)
|
45
45
|
unix_logger = LogStashLogger.new(type: :unix, path: '/tmp/sock')
|
46
46
|
redis_logger = LogStashLogger.new(type: :redis)
|
47
|
+
kafka_logger = LogStashLogger.new(type: :kafka)
|
47
48
|
stdout_logger = LogStashLogger.new(type: :stdout)
|
48
49
|
stderr_logger = LogStashLogger.new(type: :stderr)
|
49
50
|
io_logger = LogStashLogger.new(type: :io, io: io)
|
@@ -81,6 +82,7 @@ tcp://localhost:5229
|
|
81
82
|
unix:///tmp/socket
|
82
83
|
file:///path/to/file
|
83
84
|
redis://localhost:6379
|
85
|
+
kafka://localhost:9092
|
84
86
|
stdout:/
|
85
87
|
stderr:/
|
86
88
|
```
|
@@ -253,6 +255,10 @@ config.logstash.path = '/tmp/sock'
|
|
253
255
|
|
254
256
|
#### Redis
|
255
257
|
|
258
|
+
Add the redis gem to your Gemfile:
|
259
|
+
|
260
|
+
gem 'redis'
|
261
|
+
|
256
262
|
```ruby
|
257
263
|
# Required
|
258
264
|
config.logstash.type = :redis
|
@@ -271,6 +277,30 @@ config.logstash.host = 'localhost'
|
|
271
277
|
config.logstash.port = 6379
|
272
278
|
```
|
273
279
|
|
280
|
+
#### Kafka
|
281
|
+
|
282
|
+
Add the poseidon gem to your Gemfile:
|
283
|
+
|
284
|
+
gem 'poseidon'
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
# Required
|
288
|
+
config.logstash.type = :kafka
|
289
|
+
|
290
|
+
# Optional, will default to the 'logstash' topic
|
291
|
+
config.logstash.path = 'logstash'
|
292
|
+
|
293
|
+
# Optional, will default to the 'logstash-logger' producer
|
294
|
+
config.logstash.producer = 'logstash-logger'
|
295
|
+
|
296
|
+
# Optional, will default to localhost:9092 host/port
|
297
|
+
config.logstash.hosts = ['localhost:9092']
|
298
|
+
|
299
|
+
# Optional, will default to 1s backoff
|
300
|
+
config.logstash.backoff = 1
|
301
|
+
|
302
|
+
```
|
303
|
+
|
274
304
|
#### File
|
275
305
|
|
276
306
|
```ruby
|
@@ -347,6 +377,11 @@ Heroku recommends installing the [rails_12factor](https://github.com/heroku/rail
|
|
347
377
|
Unfortunately, this overrides LogStashLogger, preventing logs from being sent to their configured destination. The solution
|
348
378
|
is to remove `rails_12factor` from your Gemfile.
|
349
379
|
|
380
|
+
### Logging eventually stops in production
|
381
|
+
This is most likely not a problem with LogStashLogger, but rather a different gem changing the log level of `Rails.logger`.
|
382
|
+
This is especially likely if you're using a threaded server such as Puma, since gems often change the log level of
|
383
|
+
`Rails.logger` in a non thread-safe way. See [#17](https://github.com/dwbutler/logstash-logger/issues/17) for more information.
|
384
|
+
|
350
385
|
## Breaking changes
|
351
386
|
|
352
387
|
### Version 0.5+
|
@@ -379,6 +414,7 @@ logger = LogStashLogger.new('localhost', 5228, :tcp)
|
|
379
414
|
* [Jan Schulte](https://github.com/schultyy)
|
380
415
|
* [Kurt Preston](https://github.com/KurtPreston)
|
381
416
|
* [Chris Blatchley](https://github.com/chrisblatchley)
|
417
|
+
* [Felix Bechstein](https://github.com/felixb)
|
382
418
|
|
383
419
|
## Contributing
|
384
420
|
|
@@ -11,6 +11,7 @@ module LogStashLogger
|
|
11
11
|
autoload :TCP, 'logstash-logger/device/tcp'
|
12
12
|
autoload :Unix, 'logstash-logger/device/unix'
|
13
13
|
autoload :Redis, 'logstash-logger/device/redis'
|
14
|
+
autoload :Kafka, 'logstash-logger/device/kafka'
|
14
15
|
autoload :File, 'logstash-logger/device/file'
|
15
16
|
autoload :IO, 'logstash-logger/device/io'
|
16
17
|
autoload :Stdout, 'logstash-logger/device/stdout'
|
@@ -56,6 +57,7 @@ module LogStashLogger
|
|
56
57
|
when :unix then Unix
|
57
58
|
when :file then File
|
58
59
|
when :redis then Redis
|
60
|
+
when :kafka then Kafka
|
59
61
|
when :io then IO
|
60
62
|
when :stdout then Stdout
|
61
63
|
when :stderr then Stderr
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'poseidon'
|
2
|
+
require 'stud/buffer'
|
3
|
+
|
4
|
+
module LogStashLogger
|
5
|
+
module Device
|
6
|
+
class Kafka < Connectable
|
7
|
+
include Stud::Buffer
|
8
|
+
|
9
|
+
DEFAULT_HOST = 'localhost'
|
10
|
+
DEFAULT_PORT = 9092
|
11
|
+
DEFAULT_TOPIC = 'logstash'
|
12
|
+
DEFAULT_PRODUCER = 'logstash-logger'
|
13
|
+
DEFAULT_BACKOFF = 1
|
14
|
+
|
15
|
+
attr_accessor :hosts, :topic, :producer, :backoff
|
16
|
+
|
17
|
+
def initialize(opts)
|
18
|
+
super
|
19
|
+
host = opts[:host] || DEFAULT_HOST
|
20
|
+
port = opts[:port] || DEFAULT_PORT
|
21
|
+
@hosts = opts[:hosts] || host.split(',').map { |h| "#{h}:#{port}" }
|
22
|
+
@topic = opts[:path] || DEFAULT_TOPIC
|
23
|
+
@producer = opts[:producer] || DEFAULT_PRODUCER
|
24
|
+
@backoff = opts[:backoff] || DEFAULT_BACKOFF
|
25
|
+
|
26
|
+
@batch_events = opts.fetch(:batch_events, 50)
|
27
|
+
@batch_timeout = opts.fetch(:batch_timeout, 5)
|
28
|
+
|
29
|
+
buffer_initialize max_items: @batch_events, max_interval: @batch_timeout
|
30
|
+
end
|
31
|
+
|
32
|
+
def connect
|
33
|
+
@io = ::Poseidon::Producer.new(@hosts, @producer)
|
34
|
+
end
|
35
|
+
|
36
|
+
def reconnect
|
37
|
+
@io.close
|
38
|
+
connect
|
39
|
+
end
|
40
|
+
|
41
|
+
def with_connection
|
42
|
+
connect unless @io
|
43
|
+
yield
|
44
|
+
rescue ::Poseidon::Errors::ChecksumError, Poseidon::Errors::UnableToFetchMetadata => e
|
45
|
+
warn "#{self.class} - #{e.class} -> reconnect/retry"
|
46
|
+
sleep backoff if backoff
|
47
|
+
reconnect
|
48
|
+
retry
|
49
|
+
rescue => e
|
50
|
+
warn "#{self.class} - #{e.class} - #{e.message} -> giving up"
|
51
|
+
@io = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def write(message)
|
55
|
+
buffer_receive Poseidon::MessageToSend.new(@topic, message)
|
56
|
+
buffer_flush(force: true) if @sync
|
57
|
+
end
|
58
|
+
|
59
|
+
def close
|
60
|
+
buffer_flush(final: true)
|
61
|
+
@io && @io.close
|
62
|
+
rescue => e
|
63
|
+
warn "#{self.class} - #{e.class} - #{e.message}"
|
64
|
+
ensure
|
65
|
+
@io = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def flush(*args)
|
69
|
+
if args.empty?
|
70
|
+
buffer_flush
|
71
|
+
else
|
72
|
+
messages = *args.first
|
73
|
+
with_connection do
|
74
|
+
@io.send_messages messages
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/logstash-logger.gemspec
CHANGED
@@ -17,12 +17,13 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
|
-
|
20
|
+
|
21
21
|
gem.add_runtime_dependency 'logstash-event', '~> 1.2'
|
22
22
|
gem.add_runtime_dependency 'stud'
|
23
23
|
|
24
24
|
gem.add_development_dependency 'rails'
|
25
25
|
gem.add_development_dependency 'redis'
|
26
|
+
gem.add_development_dependency 'poseidon'
|
26
27
|
gem.add_development_dependency 'rspec', '>= 3'
|
27
28
|
gem.add_development_dependency 'rake'
|
28
29
|
gem.add_development_dependency 'pry'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'logstash-logger'
|
2
|
+
|
3
|
+
describe LogStashLogger::Device::Kafka do
|
4
|
+
include_context 'device'
|
5
|
+
|
6
|
+
let(:producer) { double("Poseidon::Producer") }
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
allow(Poseidon::Producer).to receive(:new) { producer }
|
10
|
+
end
|
11
|
+
|
12
|
+
it "writes to a Kafka topic" do
|
13
|
+
expect(producer).to receive(:send_messages)
|
14
|
+
kafka_device.write "foo"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "defaults the Kafka hosts to ['localhost:9092']" do
|
18
|
+
expect(kafka_device.hosts).to eq(['localhost:9092'])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "defaults the Kafka topic to 'logstash'" do
|
22
|
+
expect(kafka_device.topic).to eq('logstash')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "defaults the Kafka producer to 'logstash-logger'" do
|
26
|
+
expect(kafka_device.producer).to eq('logstash-logger')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "defaults the Kafka backoff to 1" do
|
30
|
+
expect(kafka_device.backoff).to eq(1)
|
31
|
+
end
|
32
|
+
end
|
data/spec/device_spec.rb
CHANGED
@@ -72,6 +72,11 @@ describe LogStashLogger::Device do
|
|
72
72
|
it { is_expected.to be_a LogStashLogger::Device::Redis }
|
73
73
|
end
|
74
74
|
|
75
|
+
context "when URI config is kafka" do
|
76
|
+
let(:uri_config) { kafka_uri_config }
|
77
|
+
it { is_expected.to be_a LogStashLogger::Device::Kafka }
|
78
|
+
end
|
79
|
+
|
75
80
|
context "when URI config is stdout" do
|
76
81
|
let(:uri_config) { stdout_uri_config }
|
77
82
|
it { is_expected.to be_a LogStashLogger::Device::Stdout }
|
data/spec/spec_helper.rb
CHANGED
@@ -52,6 +52,7 @@ RSpec.shared_context 'device' do
|
|
52
52
|
let(:io_device) { LogStashLogger::Device.new(type: :io, io: io)}
|
53
53
|
|
54
54
|
let(:redis_device) { LogStashLogger::Device.new(type: :redis, sync: true) }
|
55
|
+
let(:kafka_device) { LogStashLogger::Device.new(type: :kafka, sync: true) }
|
55
56
|
let(:multi_delegator_device) { LogStashLogger::Device.new([{type: :stdout}, {type: :io, io: io}]) }
|
56
57
|
|
57
58
|
let(:udp_uri) { "udp://localhost:5228" }
|
@@ -59,6 +60,7 @@ RSpec.shared_context 'device' do
|
|
59
60
|
let(:unix_uri) { "unix:///some/path/to/socket" }
|
60
61
|
let(:file_uri) { "file://#{file.path}" }
|
61
62
|
let(:redis_uri) { "redis://localhost:6379" }
|
63
|
+
let(:kafka_uri) { "kafka://localhost:9092" }
|
62
64
|
let(:stdout_uri) { "stdout://localhost" }
|
63
65
|
let(:stderr_uri) { "stderr://localhost" }
|
64
66
|
|
@@ -68,6 +70,7 @@ RSpec.shared_context 'device' do
|
|
68
70
|
let(:unix_uri_config) { {uri: unix_uri} }
|
69
71
|
let(:file_uri_config) { {uri: file_uri} }
|
70
72
|
let(:redis_uri_config) { {uri: redis_uri} }
|
73
|
+
let(:kafka_uri_config) { {uri: kafka_uri} }
|
71
74
|
let(:stdout_uri_config) { {uri: stdout_uri} }
|
72
75
|
let(:stderr_uri_config) { {uri: stderr_uri} }
|
73
76
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Butler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-event
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: poseidon
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -163,6 +177,7 @@ files:
|
|
163
177
|
- lib/logstash-logger/device/connectable.rb
|
164
178
|
- lib/logstash-logger/device/file.rb
|
165
179
|
- lib/logstash-logger/device/io.rb
|
180
|
+
- lib/logstash-logger/device/kafka.rb
|
166
181
|
- lib/logstash-logger/device/multi_delegator.rb
|
167
182
|
- lib/logstash-logger/device/redis.rb
|
168
183
|
- lib/logstash-logger/device/socket.rb
|
@@ -188,6 +203,7 @@ files:
|
|
188
203
|
- spec/configuration_spec.rb
|
189
204
|
- spec/device/file_spec.rb
|
190
205
|
- spec/device/io_spec.rb
|
206
|
+
- spec/device/kafka_spec.rb
|
191
207
|
- spec/device/multi_delegator_spec.rb
|
192
208
|
- spec/device/redis_spec.rb
|
193
209
|
- spec/device/socket_spec.rb
|
@@ -229,6 +245,7 @@ test_files:
|
|
229
245
|
- spec/configuration_spec.rb
|
230
246
|
- spec/device/file_spec.rb
|
231
247
|
- spec/device/io_spec.rb
|
248
|
+
- spec/device/kafka_spec.rb
|
232
249
|
- spec/device/multi_delegator_spec.rb
|
233
250
|
- spec/device/redis_spec.rb
|
234
251
|
- spec/device/socket_spec.rb
|