fluent-logger 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d93795042f622581efc248bfb4458418a56487c6
4
- data.tar.gz: 96e4b0d775212bb6094dea72de1625a9fc80e38e
3
+ metadata.gz: a3cc43a68a8c73c0232044f58faae75f84eb2fc3
4
+ data.tar.gz: 43ed7af93c1e1e0976a813b89daedba55f88ff66
5
5
  SHA512:
6
- metadata.gz: 54f9d02fd16d99b4bc2f2be8ad73b66b43386c1f01022b1f1c4c671ef22df9a8ca0cf53c1fa06cd5a13423952d19e5a65dc8688718a98fd60fbfce68ec0eca65
7
- data.tar.gz: e7172605473f80a5ea13f910a1de12c663070d123c9e242f896715c59ec5180e5b137b6d1a172ddaf5c2860957a83e1eb7b69a01880facf01282d1b1396dad79
6
+ metadata.gz: 607a3d6c81390b225efba3a1fff812f233d53ff6e7521aa1b95fbf0cfdc052f55961c908455b477b2511dda86c9830bdbabb372c0952589fd37390949414127e
7
+ data.tar.gz: a7f32f72c5411e264463a451f830228f7a15d943445ec0b5058ab1c3aee811252dc879822c3f7f7adba94a790c74be6970235ff05503d3bb9b931f3e090477ac
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ .bundle
1
2
  Gemfile.lock
2
3
  pkg/*
3
4
  coverage/*
@@ -1,18 +1,12 @@
1
1
  rvm:
2
- - 1.8.7
3
- - 1.9.2
4
2
  - 1.9.3
5
3
  - 2.0.0
6
4
  - 2.1
7
5
  - 2.2
8
- - ree
9
6
  - rbx
10
7
 
11
8
  script: bundle exec rake spec
12
9
 
13
10
  matrix:
14
11
  allow_failures:
15
- - rvm: 1.8.7
16
- - rvm: 1.9.2
17
- - rvm: ree
18
12
  - rvm: rbx
data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ Release 0.5.1 - 2015/11/24
2
+
3
+ * Allow injection of buffer overflow handler
4
+ * tag_prefix now default to nil
5
+ * LoggerBase.open follows README
6
+
1
7
  Release 0.5.0 - 2015/01/25
2
8
 
3
9
  * Use json instead of yajl. If you pass an invalid string to post, you may get 'invalid byte sequence' error.
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
1
  # Fluent logger
2
+
3
+ [![Build Status](https://travis-ci.org/fluent/fluent-logger-ruby.svg?branch=master)](https://travis-ci.org/fluent/fluent-logger-ruby)
4
+
2
5
  A structured event logger
3
6
 
4
7
  ## Examples
@@ -53,6 +56,32 @@ Fluent::Logger::ConsoleLogger.open(io)
53
56
  Fluent::Logger::NullLogger.open
54
57
  ```
55
58
 
59
+ ## Buffer overflow
60
+
61
+ You can inject your own custom proc to handle buffer overflow in the event of connection failure. This will mitigate the loss of data instead of simply throwing data away.
62
+
63
+ Your proc must accept a single argument, which will be the internal buffer of messages from the logger. A typical use-case for this would be writing to disk or possibly writing to Redis.
64
+
65
+ ##### Example
66
+ ```
67
+ class BufferOverflowHandler
68
+ attr_accessor :buffer
69
+
70
+ def flush(messages)
71
+ @buffer ||= []
72
+ MessagePack::Unpacker.new.feed_each(messages) do |msg|
73
+ @buffer << msg
74
+ end
75
+ end
76
+ end
77
+
78
+ handler = Proc.new { |messages| BufferOverflowHandler.new.flush(messages) }
79
+
80
+ Fluent::Logger::FluentLogger.new(nil,
81
+ :host => 'localhost', :port => 24224,
82
+ :buffer_overflow_handler => handler)
83
+ ```
84
+
56
85
  |name|description|
57
86
  |---|---|
58
87
  |Web site|http://fluentd.org/|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.5.1
@@ -34,7 +34,7 @@ module Fluent
34
34
  r / RECONNECT_WAIT_INCR_RATE
35
35
  }
36
36
 
37
- def initialize(tag_prefix = '', *args)
37
+ def initialize(tag_prefix = nil, *args)
38
38
  super()
39
39
 
40
40
  options = {
@@ -62,6 +62,8 @@ module Fluent
62
62
  @limit = options[:buffer_limit] || BUFFER_LIMIT
63
63
  @log_reconnect_error_threshold = options[:log_reconnect_error_threshold] || RECONNECT_WAIT_MAX_COUNT
64
64
 
65
+ @buffer_overflow_handler = options[:buffer_overflow_handler]
66
+
65
67
  if logger = options[:logger]
66
68
  @logger = logger
67
69
  else
@@ -107,6 +109,7 @@ module Fluent
107
109
  rescue => e
108
110
  set_last_error(e)
109
111
  @logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}: #{$!}")
112
+ call_buffer_overflow_handler(@pending)
110
113
  end
111
114
  end
112
115
  @con.close if connect?
@@ -168,6 +171,7 @@ module Fluent
168
171
  set_last_error(e)
169
172
  if @pending.bytesize > @limit
170
173
  @logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}: #{$!}")
174
+ call_buffer_overflow_handler(@pending)
171
175
  @pending = nil
172
176
  end
173
177
  @con.close if connect?
@@ -217,6 +221,14 @@ module Fluent
217
221
  raise e
218
222
  end
219
223
 
224
+ def call_buffer_overflow_handler(pending)
225
+ if @buffer_overflow_handler
226
+ @buffer_overflow_handler.call(pending)
227
+ end
228
+ rescue Exception => e
229
+ @logger.error("FluentLogger: Can't call buffer overflow handler: #{$!}")
230
+ end
231
+
220
232
  def log_reconnect_error
221
233
  @logger.error("FluentLogger: Can't connect to #{@host}:#{@port}(#{@connect_error_history.size} retried): #{$!}")
222
234
  end
@@ -19,7 +19,7 @@ module Fluent
19
19
  module Logger
20
20
  class LoggerBase
21
21
  def self.open(*args, &block)
22
- Fluent::Logger.open(*args, &block)
22
+ Fluent::Logger.open(self, *args, &block)
23
23
  end
24
24
 
25
25
  def post(tag, map)
@@ -1,7 +1,7 @@
1
1
  module Fluent
2
2
  module Logger
3
3
 
4
- VERSION = '0.5.0'
4
+ VERSION = '0.5.1'
5
5
 
6
6
  end
7
7
  end
@@ -10,7 +10,7 @@ require 'stringio'
10
10
  require 'fluent/logger/fluent_logger/cui'
11
11
  require 'plugin/out_test'
12
12
 
13
- $log = Fluent::Log.new(StringIO.new) # XXX should remove $log from fluentd
13
+ $log = Fluent::Log.new(StringIO.new) # XXX should remove $log from fluentd
14
14
 
15
15
  describe Fluent::Logger::FluentLogger do
16
16
  WAIT = ENV['WAIT'] ? ENV['WAIT'].to_f : 0.1
@@ -32,19 +32,26 @@ describe Fluent::Logger::FluentLogger do
32
32
  @logger_io = StringIO.new
33
33
  logger = ::Logger.new(@logger_io)
34
34
  Fluent::Logger::FluentLogger.new('logger-test', {
35
- :host => 'localhost',
35
+ :host => 'localhost',
36
36
  :port => fluentd_port,
37
37
  :logger => logger,
38
+ :buffer_overflow_handler => buffer_overflow_handler
38
39
  })
39
40
  }
40
41
 
42
+ let(:buffer_overflow_handler) { nil }
43
+
41
44
  let(:logger_io) {
42
45
  @logger_io
43
46
  }
44
47
 
45
48
  let(:output) {
46
49
  sleep 0.0001 # next tick
47
- Fluent::Engine.match('logger-test').output
50
+ if Fluent::Engine.respond_to?(:match)
51
+ Fluent::Engine.match('logger-test').output
52
+ else
53
+ Fluent::Engine.root_agent.event_router.match('logger-test')
54
+ end
48
55
  }
49
56
 
50
57
  let(:queue) {
@@ -95,33 +102,33 @@ EOF
95
102
  args = %W(-h localhost -p #{fluentd_port} -t logger-test.tag -v a=b -v foo=bar)
96
103
  Fluent::Logger::FluentLogger::CUI.post(args)
97
104
  wait_transfer
98
- queue.last.should == ['logger-test.tag', {'a' => 'b', 'foo' => 'bar'}]
105
+ expect(queue.last).to eq ['logger-test.tag', {'a' => 'b', 'foo' => 'bar'}]
99
106
  }
100
107
  end
101
108
 
102
109
  context('post') do
103
- it ('success') {
110
+ it ('success') {
104
111
  expect(logger.post('tag', {'a' => 'b'})).to be true
105
112
  wait_transfer
106
- queue.last.should == ['logger-test.tag', {'a' => 'b'}]
113
+ expect(queue.last).to eq ['logger-test.tag', {'a' => 'b'}]
107
114
  }
108
115
 
109
116
  it ('close after post') {
110
- logger.should be_connect
117
+ expect(logger).to be_connect
111
118
  logger.close
112
- logger.should_not be_connect
119
+ expect(logger).not_to be_connect
113
120
 
114
121
  logger.post('tag', {'b' => 'c'})
115
- logger.should be_connect
122
+ expect(logger).to be_connect
116
123
  wait_transfer
117
- queue.last.should == ['logger-test.tag', {'b' => 'c'}]
124
+ expect(queue.last).to eq ['logger-test.tag', {'b' => 'c'}]
118
125
  }
119
126
 
120
127
  it ('large data') {
121
128
  data = {'a' => ('b' * 1000000)}
122
129
  logger.post('tag', data)
123
130
  wait_transfer
124
- queue.last.should == ['logger-test.tag', data]
131
+ expect(queue.last).to eq ['logger-test.tag', data]
125
132
  }
126
133
 
127
134
  it ('msgpack unsupport data') {
@@ -133,9 +140,9 @@ EOF
133
140
  logger.post('tag', data)
134
141
  wait_transfer
135
142
  logger_data = queue.last.last
136
- logger_data['time'].should == '2008-09-01 10:05:00 UTC'
137
- logger_data['proc'].should be
138
- logger_data['object'].should be
143
+ expect(logger_data['time']).to eq '2008-09-01 10:05:00 UTC'
144
+ expect(logger_data['proc']).to be_truthy
145
+ expect(logger_data['object']).to be_truthy
139
146
  }
140
147
 
141
148
  it ('msgpack and JSON unsupport data') {
@@ -147,7 +154,7 @@ EOF
147
154
  }
148
155
  logger.post('tag', data)
149
156
  wait_transfer
150
- queue.last.should be_nil
157
+ expect(queue.last).to be_nil
151
158
  logger_io.rewind
152
159
  logger_io.read =~ /FluentLogger: Can't convert to msgpack:/
153
160
  }
@@ -167,66 +174,105 @@ EOF
167
174
 
168
175
  context "initializer" do
169
176
  it "backward compatible" do
170
- port = fluentd_port
171
- fluent_logger = Fluent::Logger::FluentLogger.new('logger-test', 'localhost', port)
172
- fluent_logger.instance_eval {
173
- @host.should == 'localhost'
174
- @port.should == port
175
- }
177
+ fluent_logger = Fluent::Logger::FluentLogger.new('logger-test', 'localhost', fluentd_port)
178
+ host, port = fluent_logger.instance_eval { [@host, @port] }
179
+ expect(host).to eq 'localhost'
180
+ expect(port).to eq fluentd_port
176
181
  end
177
182
 
178
183
  it "hash argument" do
179
- port = fluentd_port
180
184
  fluent_logger = Fluent::Logger::FluentLogger.new('logger-test', {
181
185
  :host => 'localhost',
182
- :port => port
186
+ :port => fluentd_port
183
187
  })
184
- fluent_logger.instance_eval {
185
- @host.should == 'localhost'
186
- @port.should == port
187
- }
188
+
189
+ host, port = fluent_logger.instance_eval { [@host, @port] }
190
+ expect(host).to eq 'localhost'
191
+ expect(port).to eq fluentd_port
188
192
  end
189
193
  end
190
194
  end
191
-
195
+
192
196
  context "not running fluentd" do
193
197
  context('fluent logger interface') do
194
198
  it ('post & close') {
195
199
  expect(logger.post('tag', {'a' => 'b'})).to be false
196
200
  wait_transfer # even if wait
197
- queue.last.should be_nil
201
+ expect(queue.last).to be_nil
198
202
  logger.close
199
203
  logger_io.rewind
200
204
  log = logger_io.read
201
- log.should =~ /Failed to connect/
202
- log.should =~ /Can't send logs to/
205
+ expect(log).to match /Failed to connect/
206
+ expect(log).to match /Can't send logs to/
203
207
  }
204
208
 
205
209
  it ('post limit over') do
206
210
  logger.limit = 100
207
211
  logger.post('tag', {'a' => 'b'})
208
212
  wait_transfer # even if wait
209
- queue.last.should be_nil
213
+ expect(queue.last).to be_nil
210
214
 
211
215
  logger_io.rewind
212
- logger_io.read.should_not =~ /Can't send logs to/
216
+ expect(logger_io.read).not_to match /Can't send logs to/
213
217
 
214
218
  logger.post('tag', {'a' => ('c' * 1000)})
215
219
  logger_io.rewind
216
- logger_io.read.should =~ /Can't send logs to/
220
+ expect(logger_io.read).to match /Can't send logs to/
217
221
  end
218
222
 
219
223
  it ('log connect error once') do
220
- Fluent::Logger::FluentLogger.any_instance.stub(:suppress_sec).and_return(-1)
224
+ allow_any_instance_of(Fluent::Logger::FluentLogger).to receive(:suppress_sec).and_return(-1)
221
225
  logger.log_reconnect_error_threshold = 1
222
- Fluent::Logger::FluentLogger.any_instance.should_receive(:log_reconnect_error).once.and_call_original
226
+ expect_any_instance_of(Fluent::Logger::FluentLogger).to receive(:log_reconnect_error).once.and_call_original
223
227
 
224
228
  logger.post('tag', {'a' => 'b'})
225
229
  wait_transfer # even if wait
226
230
  logger.post('tag', {'a' => 'b'})
227
231
  wait_transfer # even if wait
228
232
  logger_io.rewind
229
- logger_io.read.should =~ /Failed to connect/
233
+ expect(logger_io.read).to match /Failed to connect/
234
+ end
235
+ end
236
+
237
+ context "when a buffer overflow handler is provided" do
238
+ class BufferOverflowHandler
239
+ attr_accessor :buffer
240
+
241
+ def flush(messages)
242
+ @buffer ||= []
243
+ MessagePack::Unpacker.new.feed_each(messages) do |msg|
244
+ @buffer << msg
245
+ end
246
+ end
247
+ end
248
+
249
+ let(:handler) { BufferOverflowHandler.new }
250
+ let(:buffer_overflow_handler) { Proc.new { |messages| handler.flush(messages) } }
251
+
252
+ it ('post limit over') do
253
+ logger.limit = 100
254
+ event_1 = {'a' => 'b'}
255
+ logger.post('tag', event_1)
256
+ wait_transfer # even if wait
257
+ queue.last.should be_nil
258
+
259
+ logger_io.rewind
260
+ logger_io.read.should_not =~ /Can't send logs to/
261
+
262
+ event_2 = {'a' => ('c' * 1000)}
263
+ logger.post('tag', event_2)
264
+ logger_io.rewind
265
+ logger_io.read.should =~ /Can't send logs to/
266
+
267
+ buffer = handler.buffer
268
+
269
+ buffer[0][0].should == 'logger-test.tag'
270
+ buffer[0][1].should.to_s =~ /\d{10}/
271
+ buffer[0][2].should == event_1
272
+
273
+ buffer[1][0].should == 'logger-test.tag'
274
+ buffer[1][1].should.to_s =~ /\d{10}/
275
+ buffer[1][2].should == event_2
230
276
  end
231
277
  end
232
278
  end
@@ -3,9 +3,21 @@ require 'spec_helper'
3
3
 
4
4
  describe Fluent::Logger::LoggerBase do
5
5
  context "subclass" do
6
- subject { Class.new(Fluent::Logger::LoggerBase) }
7
- its(:open) {
8
- should be_kind_of(Fluent::Logger::LoggerBase)
9
- }
6
+ let(:subclass) { Class.new(Fluent::Logger::LoggerBase) }
7
+ let(:other_subclass) { Class.new(Fluent::Logger::LoggerBase) }
8
+
9
+ describe ".open" do
10
+ subject(:open) { subclass.open }
11
+
12
+ it { should be_kind_of(Fluent::Logger::LoggerBase) }
13
+
14
+ it "changes Fluent::Logger.default" do
15
+ subclass.open
16
+ expect(Fluent::Logger.default).to be_kind_of(subclass)
17
+
18
+ other_subclass.open
19
+ expect(Fluent::Logger.default).to be_kind_of(other_subclass)
20
+ end
21
+ end
10
22
  end
11
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-25 00:00:00.000000000 Z
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
181
  version: '0'
182
182
  requirements: []
183
183
  rubyforge_project:
184
- rubygems_version: 2.4.5
184
+ rubygems_version: 2.4.5.1
185
185
  signing_key:
186
186
  specification_version: 4
187
187
  summary: fluent logger for ruby