fluent-logger 0.4.10 → 0.5.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 +2 -2
- data/ChangeLog +5 -0
- data/Gemfile +2 -2
- data/VERSION +1 -1
- data/fluent-logger.gemspec +0 -6
- data/lib/fluent/logger.rb +37 -39
- data/lib/fluent/logger/console_logger.rb +31 -34
- data/lib/fluent/logger/fluent_logger.rb +173 -177
- data/lib/fluent/logger/fluent_logger/cui.rb +34 -37
- data/lib/fluent/logger/logger_base.rb +14 -16
- data/lib/fluent/logger/null_logger.rb +6 -8
- data/lib/fluent/logger/test_logger.rb +25 -27
- data/lib/fluent/logger/text_logger.rb +16 -18
- data/lib/fluent/logger/version.rb +1 -1
- data/spec/fluent_logger_spec.rb +5 -18
- data/spec/plugin/out_test.rb +73 -0
- metadata +5 -18
- data/.gitmodules +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d93795042f622581efc248bfb4458418a56487c6
|
4
|
+
data.tar.gz: 96e4b0d775212bb6094dea72de1625a9fc80e38e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54f9d02fd16d99b4bc2f2be8ad73b66b43386c1f01022b1f1c4c671ef22df9a8ca0cf53c1fa06cd5a13423952d19e5a65dc8688718a98fd60fbfce68ec0eca65
|
7
|
+
data.tar.gz: e7172605473f80a5ea13f910a1de12c663070d123c9e242f896715c59ec5180e5b137b6d1a172ddaf5c2860957a83e1eb7b69a01880facf01282d1b1396dad79
|
data/.travis.yml
CHANGED
data/ChangeLog
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
Release 0.5.0 - 2015/01/25
|
2
|
+
|
3
|
+
* Use json instead of yajl. If you pass an invalid string to post, you may get 'invalid byte sequence' error.
|
4
|
+
* Support JRuby environment
|
5
|
+
|
1
6
|
Release 0.4.10 - 2015/01/10
|
2
7
|
|
3
8
|
* Call closed? in connect? method to check connection is closed or not
|
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/fluent-logger.gemspec
CHANGED
@@ -16,11 +16,6 @@ end
|
|
16
16
|
EOF
|
17
17
|
}
|
18
18
|
|
19
|
-
unless File.exist?("vendor/fluentd/Gemfile")
|
20
|
-
puts "git submodule update -i"
|
21
|
-
system("git submodule update -i")
|
22
|
-
end
|
23
|
-
|
24
19
|
gem.name = %q{fluent-logger}
|
25
20
|
gem.version = version
|
26
21
|
# gem.platform = Gem::Platform::RUBY
|
@@ -35,7 +30,6 @@ EOF
|
|
35
30
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
36
31
|
gem.require_paths = ['lib']
|
37
32
|
|
38
|
-
gem.add_dependency 'yajl-ruby', '~> 1.0'
|
39
33
|
gem.add_dependency "msgpack", [">= 0.4.4", "!= 0.5.0", "!= 0.5.1", "!= 0.5.2", "!= 0.5.3", "< 0.6.0"]
|
40
34
|
gem.add_development_dependency 'rake', '>= 0.9.2'
|
41
35
|
gem.add_development_dependency 'rspec', '>= 3.0.0'
|
data/lib/fluent/logger.rb
CHANGED
@@ -16,54 +16,52 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
+
module Logger
|
20
|
+
autoload :ConsoleLogger , 'fluent/logger/console_logger'
|
21
|
+
autoload :FluentLogger , 'fluent/logger/fluent_logger'
|
22
|
+
autoload :LoggerBase , 'fluent/logger/logger_base'
|
23
|
+
autoload :TestLogger , 'fluent/logger/test_logger'
|
24
|
+
autoload :TextLogger , 'fluent/logger/text_logger'
|
25
|
+
autoload :NullLogger , 'fluent/logger/null_logger'
|
26
|
+
autoload :VERSION , 'fluent/logger/version'
|
19
27
|
|
20
|
-
|
21
|
-
autoload :ConsoleLogger , 'fluent/logger/console_logger'
|
22
|
-
autoload :FluentLogger , 'fluent/logger/fluent_logger'
|
23
|
-
autoload :LoggerBase , 'fluent/logger/logger_base'
|
24
|
-
autoload :TestLogger , 'fluent/logger/test_logger'
|
25
|
-
autoload :TextLogger , 'fluent/logger/text_logger'
|
26
|
-
autoload :NullLogger , 'fluent/logger/null_logger'
|
27
|
-
autoload :VERSION , 'fluent/logger/version'
|
28
|
+
@@default_logger = nil
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
type
|
30
|
+
def self.new(*args)
|
31
|
+
if args.first.is_a?(Class) && args.first.ancestors.include?(LoggerBase)
|
32
|
+
type = args.shift
|
33
|
+
else
|
34
|
+
type = FluentLogger
|
35
|
+
end
|
36
|
+
type.new(*args)
|
36
37
|
end
|
37
|
-
type.new(*args)
|
38
|
-
end
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
def self.open(*args)
|
40
|
+
close
|
41
|
+
@@default_logger = new(*args)
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
def self.close
|
45
|
+
if @@default_logger
|
46
|
+
@@default_logger.close
|
47
|
+
@@default_logger = nil
|
48
|
+
end
|
49
49
|
end
|
50
|
-
end
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
def self.post(tag, map)
|
52
|
+
@@default_logger.post(tag, map)
|
53
|
+
end
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
def self.post_with_time(tag, map, time)
|
56
|
+
@@default_logger.post_with_time(tag, map, time)
|
57
|
+
end
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
def self.default
|
60
|
+
@@default_logger ||= ConsoleLogger.new(STDOUT)
|
61
|
+
end
|
63
62
|
|
64
|
-
|
65
|
-
|
63
|
+
def self.default=(logger)
|
64
|
+
@@default_logger = logger
|
65
|
+
end
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
69
|
-
end
|
@@ -18,40 +18,37 @@
|
|
18
18
|
require 'fluent/logger/text_logger'
|
19
19
|
|
20
20
|
module Fluent
|
21
|
-
module Logger
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
module Logger
|
22
|
+
class ConsoleLogger < TextLogger
|
23
|
+
def initialize(out)
|
24
|
+
super()
|
25
|
+
require 'time'
|
26
|
+
|
27
|
+
if out.is_a?(String)
|
28
|
+
@io = File.open(out, "a")
|
29
|
+
@on_reopen = Proc.new { @io.reopen(out, "a") }
|
30
|
+
elsif out.respond_to?(:write)
|
31
|
+
@io = out
|
32
|
+
@on_reopen = Proc.new { }
|
33
|
+
else
|
34
|
+
raise "Invalid output: #{out.inspect}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :time_format
|
39
|
+
|
40
|
+
def reopen!
|
41
|
+
@on_reopen.call
|
42
|
+
end
|
43
|
+
|
44
|
+
def post_text(text)
|
45
|
+
@io.puts text
|
46
|
+
end
|
47
|
+
|
48
|
+
def close
|
49
|
+
@io.close
|
50
|
+
self
|
51
|
+
end
|
36
52
|
end
|
37
53
|
end
|
38
|
-
|
39
|
-
attr_accessor :time_format
|
40
|
-
|
41
|
-
def reopen!
|
42
|
-
@on_reopen.call
|
43
|
-
end
|
44
|
-
|
45
|
-
def post_text(text)
|
46
|
-
@io.puts text
|
47
|
-
end
|
48
|
-
|
49
|
-
def close
|
50
|
-
@io.close
|
51
|
-
self
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
54
|
end
|
@@ -19,216 +19,212 @@ require 'msgpack'
|
|
19
19
|
require 'socket'
|
20
20
|
require 'monitor'
|
21
21
|
require 'logger'
|
22
|
-
require '
|
22
|
+
require 'json'
|
23
23
|
|
24
24
|
module Fluent
|
25
|
-
module Logger
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
RECONNECT_WAIT_MAX_COUNT =
|
34
|
-
(1..100).inject(RECONNECT_WAIT_MAX / RECONNECT_WAIT) {|r,i|
|
25
|
+
module Logger
|
26
|
+
class FluentLogger < LoggerBase
|
27
|
+
BUFFER_LIMIT = 8*1024*1024
|
28
|
+
RECONNECT_WAIT = 0.5
|
29
|
+
RECONNECT_WAIT_INCR_RATE = 1.5
|
30
|
+
RECONNECT_WAIT_MAX = 60
|
31
|
+
RECONNECT_WAIT_MAX_COUNT =
|
32
|
+
(1..100).inject(RECONNECT_WAIT_MAX / RECONNECT_WAIT) {|r,i|
|
35
33
|
break i + 1 if r < RECONNECT_WAIT_INCR_RATE
|
36
34
|
r / RECONNECT_WAIT_INCR_RATE
|
37
35
|
}
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@tag_prefix = tag_prefix
|
57
|
-
@host = options[:host]
|
58
|
-
@port = options[:port]
|
59
|
-
|
60
|
-
@mon = Monitor.new
|
61
|
-
@pending = nil
|
62
|
-
@connect_error_history = []
|
63
|
-
|
64
|
-
@limit = options[:buffer_limit] || BUFFER_LIMIT
|
65
|
-
@log_reconnect_error_threshold = options[:log_reconnect_error_threshold] || RECONNECT_WAIT_MAX_COUNT
|
66
|
-
|
67
|
-
if logger = options[:logger]
|
68
|
-
@logger = logger
|
69
|
-
else
|
70
|
-
@logger = ::Logger.new(STDERR)
|
71
|
-
if options[:debug]
|
72
|
-
@logger.level = ::Logger::DEBUG
|
73
|
-
else
|
74
|
-
@logger.level = ::Logger::INFO
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
@last_error = {}
|
79
|
-
|
80
|
-
begin
|
81
|
-
connect!
|
82
|
-
rescue => e
|
83
|
-
set_last_error(e)
|
84
|
-
@logger.error "Failed to connect fluentd: #{$!}"
|
85
|
-
@logger.error "Connection will be retried."
|
86
|
-
end
|
87
|
-
|
88
|
-
at_exit { close }
|
89
|
-
end
|
37
|
+
def initialize(tag_prefix = '', *args)
|
38
|
+
super()
|
39
|
+
|
40
|
+
options = {
|
41
|
+
:host => 'localhost',
|
42
|
+
:port => 24224
|
43
|
+
}
|
44
|
+
|
45
|
+
case args.first
|
46
|
+
when String, Symbol
|
47
|
+
# backward compatible
|
48
|
+
options[:host] = args[0]
|
49
|
+
options[:port] = args[1] if args[1]
|
50
|
+
when Hash
|
51
|
+
options.update args.first
|
52
|
+
end
|
90
53
|
|
91
|
-
|
92
|
-
|
54
|
+
@tag_prefix = tag_prefix
|
55
|
+
@host = options[:host]
|
56
|
+
@port = options[:port]
|
93
57
|
|
94
|
-
|
95
|
-
|
96
|
-
|
58
|
+
@mon = Monitor.new
|
59
|
+
@pending = nil
|
60
|
+
@connect_error_history = []
|
61
|
+
|
62
|
+
@limit = options[:buffer_limit] || BUFFER_LIMIT
|
63
|
+
@log_reconnect_error_threshold = options[:log_reconnect_error_threshold] || RECONNECT_WAIT_MAX_COUNT
|
64
|
+
|
65
|
+
if logger = options[:logger]
|
66
|
+
@logger = logger
|
67
|
+
else
|
68
|
+
@logger = ::Logger.new(STDERR)
|
69
|
+
if options[:debug]
|
70
|
+
@logger.level = ::Logger::DEBUG
|
71
|
+
else
|
72
|
+
@logger.level = ::Logger::INFO
|
73
|
+
end
|
74
|
+
end
|
97
75
|
|
98
|
-
|
99
|
-
@logger.debug { "event: #{tag} #{map.to_json}" rescue nil } if @logger.debug?
|
100
|
-
tag = "#{@tag_prefix}.#{tag}" if @tag_prefix
|
101
|
-
write [tag, time.to_i, map]
|
102
|
-
end
|
76
|
+
@last_error = {}
|
103
77
|
|
104
|
-
def close
|
105
|
-
@mon.synchronize {
|
106
|
-
if @pending
|
107
78
|
begin
|
108
|
-
|
79
|
+
connect!
|
109
80
|
rescue => e
|
110
81
|
set_last_error(e)
|
111
|
-
@logger.error
|
82
|
+
@logger.error "Failed to connect fluentd: #{$!}"
|
83
|
+
@logger.error "Connection will be retried."
|
112
84
|
end
|
85
|
+
|
86
|
+
at_exit { close }
|
113
87
|
end
|
114
|
-
@con.close if connect?
|
115
|
-
@con = nil
|
116
|
-
@pending = nil
|
117
|
-
}
|
118
|
-
self
|
119
|
-
end
|
120
88
|
|
121
|
-
|
122
|
-
|
123
|
-
end
|
89
|
+
attr_accessor :limit, :logger, :log_reconnect_error_threshold
|
90
|
+
attr_reader :last_error
|
124
91
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
msg.to_msgpack
|
129
|
-
rescue NoMethodError
|
130
|
-
Yajl::Parser.parse( Yajl::Encoder.encode(msg) ).to_msgpack
|
131
|
-
end
|
132
|
-
end
|
92
|
+
def last_error
|
93
|
+
@last_error[Thread.current.object_id]
|
94
|
+
end
|
133
95
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
140
|
-
end
|
96
|
+
def post_with_time(tag, map, time)
|
97
|
+
@logger.debug { "event: #{tag} #{map.to_json}" rescue nil } if @logger.debug?
|
98
|
+
tag = "#{@tag_prefix}.#{tag}" if @tag_prefix
|
99
|
+
write [tag, time.to_i, map]
|
100
|
+
end
|
141
101
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
102
|
+
def close
|
103
|
+
@mon.synchronize {
|
104
|
+
if @pending
|
105
|
+
begin
|
106
|
+
send_data(@pending)
|
107
|
+
rescue => e
|
108
|
+
set_last_error(e)
|
109
|
+
@logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}: #{$!}")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
@con.close if connect?
|
113
|
+
@con = nil
|
114
|
+
@pending = nil
|
115
|
+
}
|
116
|
+
self
|
117
|
+
end
|
150
118
|
|
151
|
-
|
152
|
-
|
153
|
-
@pending << data
|
154
|
-
else
|
155
|
-
@pending = data
|
119
|
+
def connect?
|
120
|
+
@con && !@con.closed?
|
156
121
|
end
|
157
122
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
123
|
+
private
|
124
|
+
def to_msgpack(msg)
|
125
|
+
begin
|
126
|
+
msg.to_msgpack
|
127
|
+
rescue NoMethodError
|
128
|
+
JSON.parse(JSON.generate(msg)).to_msgpack
|
162
129
|
end
|
163
130
|
end
|
164
131
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
set_last_error(e)
|
171
|
-
if @pending.bytesize > @limit
|
172
|
-
@logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}: #{$!}")
|
173
|
-
@pending = nil
|
132
|
+
def suppress_sec
|
133
|
+
if (sz = @connect_error_history.size) < RECONNECT_WAIT_MAX_COUNT
|
134
|
+
RECONNECT_WAIT * (RECONNECT_WAIT_INCR_RATE ** (sz - 1))
|
135
|
+
else
|
136
|
+
RECONNECT_WAIT_MAX
|
174
137
|
end
|
175
|
-
@con.close if connect?
|
176
|
-
@con = nil
|
177
|
-
false
|
178
138
|
end
|
179
|
-
}
|
180
|
-
end
|
181
139
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
# n = @con.syswrite(data[0..32*1024])
|
191
|
-
# else
|
192
|
-
# n = @con.syswrite(data)
|
193
|
-
# end
|
194
|
-
# puts "sent #{n}"
|
195
|
-
# if n >= data.bytesize
|
196
|
-
# break
|
197
|
-
# end
|
198
|
-
# data = data[n..-1]
|
199
|
-
#end
|
200
|
-
true
|
201
|
-
end
|
140
|
+
def write(msg)
|
141
|
+
begin
|
142
|
+
data = to_msgpack(msg)
|
143
|
+
rescue => e
|
144
|
+
set_last_error(e)
|
145
|
+
@logger.error("FluentLogger: Can't convert to msgpack: #{msg.inspect}: #{$!}")
|
146
|
+
return false
|
147
|
+
end
|
202
148
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
149
|
+
@mon.synchronize {
|
150
|
+
if @pending
|
151
|
+
@pending << data
|
152
|
+
else
|
153
|
+
@pending = data
|
154
|
+
end
|
155
|
+
|
156
|
+
# suppress reconnection burst
|
157
|
+
if !@connect_error_history.empty? && @pending.bytesize <= @limit
|
158
|
+
if Time.now.to_i - @connect_error_history.last < suppress_sec
|
159
|
+
return false
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
begin
|
164
|
+
send_data(@pending)
|
165
|
+
@pending = nil
|
166
|
+
true
|
167
|
+
rescue => e
|
168
|
+
set_last_error(e)
|
169
|
+
if @pending.bytesize > @limit
|
170
|
+
@logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}: #{$!}")
|
171
|
+
@pending = nil
|
172
|
+
end
|
173
|
+
@con.close if connect?
|
174
|
+
@con = nil
|
175
|
+
false
|
176
|
+
end
|
177
|
+
}
|
178
|
+
end
|
213
179
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
180
|
+
def send_data(data)
|
181
|
+
unless connect?
|
182
|
+
connect!
|
183
|
+
end
|
184
|
+
@con.write data
|
185
|
+
#while true
|
186
|
+
# puts "sending #{data.length} bytes"
|
187
|
+
# if data.length > 32*1024
|
188
|
+
# n = @con.syswrite(data[0..32*1024])
|
189
|
+
# else
|
190
|
+
# n = @con.syswrite(data)
|
191
|
+
# end
|
192
|
+
# puts "sent #{n}"
|
193
|
+
# if n >= data.bytesize
|
194
|
+
# break
|
195
|
+
# end
|
196
|
+
# data = data[n..-1]
|
197
|
+
#end
|
198
|
+
true
|
199
|
+
end
|
218
200
|
|
219
|
-
|
220
|
-
|
201
|
+
def connect!
|
202
|
+
@con = TCPSocket.new(@host, @port)
|
203
|
+
@con.sync = true
|
204
|
+
@connect_error_history.clear
|
205
|
+
@logged_reconnect_error = false
|
206
|
+
rescue => e
|
207
|
+
@connect_error_history << Time.now.to_i
|
208
|
+
if @connect_error_history.size > RECONNECT_WAIT_MAX_COUNT
|
209
|
+
@connect_error_history.shift
|
210
|
+
end
|
221
211
|
|
222
|
-
|
223
|
-
|
224
|
-
|
212
|
+
if @connect_error_history.size >= @log_reconnect_error_threshold && !@logged_reconnect_error
|
213
|
+
log_reconnect_error
|
214
|
+
@logged_reconnect_error = true
|
215
|
+
end
|
225
216
|
|
226
|
-
|
227
|
-
|
228
|
-
@last_error[Thread.current.object_id] = e
|
229
|
-
end
|
230
|
-
end
|
217
|
+
raise e
|
218
|
+
end
|
231
219
|
|
220
|
+
def log_reconnect_error
|
221
|
+
@logger.error("FluentLogger: Can't connect to #{@host}:#{@port}(#{@connect_error_history.size} retried): #{$!}")
|
222
|
+
end
|
232
223
|
|
233
|
-
|
224
|
+
def set_last_error(e)
|
225
|
+
# TODO: Check non GVL env
|
226
|
+
@last_error[Thread.current.object_id] = e
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
234
230
|
end
|
@@ -1,46 +1,43 @@
|
|
1
|
-
|
2
1
|
require 'fluent/logger'
|
3
2
|
require 'optparse'
|
4
3
|
|
5
4
|
module Fluent
|
6
|
-
module Logger
|
7
|
-
class FluentLogger
|
5
|
+
module Logger
|
6
|
+
class FluentLogger
|
7
|
+
module CUI
|
8
|
+
def post(args)
|
9
|
+
options = {
|
10
|
+
:port => '24224',
|
11
|
+
:host => 'localhost'
|
12
|
+
}
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
o = OptionParser.new
|
15
|
+
o.version = Fluent::Logger::VERSION
|
16
|
+
o.on('-t [tag (default nil)]') {|v| options[:tag] = v }
|
17
|
+
o.on('-p [port (default 24224)]') {|v| options[:port] = v }
|
18
|
+
o.on('-h [host (default localhost)]') {|v| options[:host] = v }
|
19
|
+
o.on('-v [key=value]') {|v|
|
20
|
+
key, value = v.split('=')
|
21
|
+
(options[:data] ||= {})[key] = value
|
22
|
+
}
|
23
|
+
o.banner = 'Usage: fluent-post -t tag.foo.bar -v key1=value1 -v key2=value2'
|
24
|
+
args = args.to_a
|
25
|
+
args << '--help' if args.empty?
|
26
|
+
o.parse(args)
|
27
|
+
|
28
|
+
f = Fluent::Logger::FluentLogger.new(nil, {
|
29
|
+
:host => options[:host],
|
30
|
+
:port => options[:port]
|
31
|
+
})
|
15
32
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
o.on('-v [key=value]') {|v|
|
22
|
-
key, value = v.split('=')
|
23
|
-
(options[:data] ||= {})[key] = value
|
24
|
-
}
|
25
|
-
o.banner = 'Usage: fluent-post -t tag.foo.bar -v key1=value1 -v key2=value2'
|
26
|
-
args = args.to_a
|
27
|
-
args << '--help' if args.empty?
|
28
|
-
o.parse(args)
|
29
|
-
|
30
|
-
f = Fluent::Logger::FluentLogger.new(nil, {
|
31
|
-
:host => options[:host],
|
32
|
-
:port => options[:port]
|
33
|
-
})
|
33
|
+
{
|
34
|
+
:success => f.post(options[:tag], options[:data]),
|
35
|
+
:data => options[:data]
|
36
|
+
}
|
37
|
+
end
|
34
38
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
}
|
39
|
+
extend self
|
40
|
+
end
|
41
|
+
end
|
39
42
|
end
|
40
|
-
|
41
|
-
extend self
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
43
|
end
|
@@ -16,24 +16,22 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
-
module Logger
|
19
|
+
module Logger
|
20
|
+
class LoggerBase
|
21
|
+
def self.open(*args, &block)
|
22
|
+
Fluent::Logger.open(*args, &block)
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def post(tag, map)
|
27
|
-
raise ArgumentError.new("Second argument should kind of Hash (tag: #{map})") unless map.kind_of? Hash
|
28
|
-
post_with_time(tag, map, Time.now)
|
29
|
-
end
|
25
|
+
def post(tag, map)
|
26
|
+
raise ArgumentError.new("Second argument should kind of Hash (tag: #{map})") unless map.kind_of? Hash
|
27
|
+
post_with_time(tag, map, Time.now)
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
#def post_with_time(tag, map)
|
31
|
+
#end
|
33
32
|
|
34
|
-
|
33
|
+
def close
|
34
|
+
end
|
35
|
+
end
|
35
36
|
end
|
36
37
|
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
@@ -16,13 +16,11 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
-
module Logger
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
module Logger
|
20
|
+
class NullLogger < LoggerBase
|
21
|
+
def post_with_time(tag, map, time)
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
24
25
|
end
|
25
26
|
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
@@ -16,36 +16,34 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
-
module Logger
|
19
|
+
module Logger
|
20
|
+
class TestLogger < LoggerBase
|
21
|
+
def initialize(queue=[])
|
22
|
+
@queue = queue
|
23
|
+
@max = 1024
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
@queue = queue
|
24
|
-
@max = 1024
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_accessor :max
|
28
|
-
attr_reader :queue
|
26
|
+
attr_accessor :max
|
27
|
+
attr_reader :queue
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
29
|
+
def post_with_time(tag, map, time)
|
30
|
+
while @queue.size > @max-1
|
31
|
+
@queue.shift
|
32
|
+
end
|
33
|
+
(class<<map;self;end).module_eval do
|
34
|
+
define_method(:tag) { tag }
|
35
|
+
define_method(:time) { time }
|
36
|
+
end
|
37
|
+
@queue << map
|
38
|
+
true
|
39
|
+
end
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
def tag_queue(tag)
|
42
|
+
@queue.find_all {|map| map.tag == tag }
|
43
|
+
end
|
45
44
|
|
46
|
-
|
45
|
+
def close
|
46
|
+
end
|
47
|
+
end
|
47
48
|
end
|
48
49
|
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
@@ -16,24 +16,22 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
module Fluent
|
19
|
-
module Logger
|
19
|
+
module Logger
|
20
|
+
class TextLogger < LoggerBase
|
21
|
+
def initialize
|
22
|
+
require 'json'
|
23
|
+
@time_format = "%b %e %H:%M:%S"
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
def post_with_time(tag, map, time)
|
27
|
+
a = [time.strftime(@time_format), " ", tag, ":"]
|
28
|
+
map.each_pair { |k,v|
|
29
|
+
a << " #{k}="
|
30
|
+
a << JSON.dump(v)
|
31
|
+
}
|
32
|
+
post_text a.join
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
25
36
|
end
|
26
|
-
|
27
|
-
def post_with_time(tag, map, time)
|
28
|
-
a = [time.strftime(@time_format), " ", tag, ":"]
|
29
|
-
map.each_pair {|k,v|
|
30
|
-
a << " #{k}="
|
31
|
-
a << Yajl::Encoder.encode(v)
|
32
|
-
}
|
33
|
-
post_text a.join
|
34
|
-
true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
37
|
end
|
data/spec/fluent_logger_spec.rb
CHANGED
@@ -1,19 +1,14 @@
|
|
1
1
|
|
2
2
|
require 'spec_helper'
|
3
|
-
if RUBY_VERSION < "1.9.2"
|
4
|
-
|
5
|
-
describe Fluent::Logger::FluentLogger do
|
6
|
-
pending "fluentd don't work RUBY < 1.9.2"
|
7
|
-
end
|
8
|
-
|
9
|
-
else
|
10
3
|
|
11
4
|
require 'fluent/load'
|
5
|
+
require 'fluent/test'
|
12
6
|
require 'tempfile'
|
13
7
|
require 'logger'
|
14
8
|
require 'socket'
|
15
9
|
require 'stringio'
|
16
10
|
require 'fluent/logger/fluent_logger/cui'
|
11
|
+
require 'plugin/out_test'
|
17
12
|
|
18
13
|
$log = Fluent::Log.new(StringIO.new) # XXX should remove $log from fluentd
|
19
14
|
|
@@ -70,22 +65,17 @@ describe Fluent::Logger::FluentLogger do
|
|
70
65
|
|
71
66
|
context "running fluentd" do
|
72
67
|
before(:each) do
|
73
|
-
|
74
|
-
tmp.close(false)
|
75
|
-
|
76
|
-
File.open(tmp.path, 'w') {|f|
|
77
|
-
f.puts <<EOF
|
68
|
+
@config = Fluent::Config.parse(<<EOF, '(logger-spec)', '(logger-spec-dir)', true)
|
78
69
|
<source>
|
79
|
-
type
|
70
|
+
type forward
|
80
71
|
port #{fluentd_port}
|
81
72
|
</source>
|
82
73
|
<match logger-test.**>
|
83
74
|
type test
|
84
75
|
</match>
|
85
76
|
EOF
|
86
|
-
}
|
87
77
|
Fluent::Test.setup
|
88
|
-
Fluent::Engine.
|
78
|
+
Fluent::Engine.run_configure(@config)
|
89
79
|
@coolio_default_loop = nil
|
90
80
|
@thread = Thread.new {
|
91
81
|
@coolio_default_loop = Coolio::Loop.default
|
@@ -240,7 +230,4 @@ EOF
|
|
240
230
|
end
|
241
231
|
end
|
242
232
|
end
|
243
|
-
|
244
|
-
end
|
245
|
-
|
246
233
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
module Fluent
|
18
|
+
class TestOutput < Output
|
19
|
+
Plugin.register_output('test', self)
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@emit_streams = []
|
23
|
+
@name = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :emit_streams, :name
|
27
|
+
|
28
|
+
def emits
|
29
|
+
all = []
|
30
|
+
@emit_streams.each {|tag,events|
|
31
|
+
events.each {|time,record|
|
32
|
+
all << [tag, time, record]
|
33
|
+
}
|
34
|
+
}
|
35
|
+
all
|
36
|
+
end
|
37
|
+
|
38
|
+
def events
|
39
|
+
all = []
|
40
|
+
@emit_streams.each {|tag,events|
|
41
|
+
all.concat events
|
42
|
+
}
|
43
|
+
all
|
44
|
+
end
|
45
|
+
|
46
|
+
def records
|
47
|
+
all = []
|
48
|
+
@emit_streams.each {|tag,events|
|
49
|
+
events.each {|time,record|
|
50
|
+
all << record
|
51
|
+
}
|
52
|
+
}
|
53
|
+
all
|
54
|
+
end
|
55
|
+
|
56
|
+
def configure(conf)
|
57
|
+
if name = conf['name']
|
58
|
+
@name = name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def start
|
63
|
+
end
|
64
|
+
|
65
|
+
def shutdown
|
66
|
+
end
|
67
|
+
|
68
|
+
def emit(tag, es, chain)
|
69
|
+
chain.next
|
70
|
+
@emit_streams << [tag, es.to_a]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
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-
|
11
|
+
date: 2015-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: yajl-ruby
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: msgpack
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,7 +132,6 @@ extensions: []
|
|
146
132
|
extra_rdoc_files: []
|
147
133
|
files:
|
148
134
|
- ".gitignore"
|
149
|
-
- ".gitmodules"
|
150
135
|
- ".rspec"
|
151
136
|
- ".travis.yml"
|
152
137
|
- AUTHORS
|
@@ -173,6 +158,7 @@ files:
|
|
173
158
|
- spec/logger_base_spec.rb
|
174
159
|
- spec/logger_spec.rb
|
175
160
|
- spec/null_logger_spec.rb
|
161
|
+
- spec/plugin/out_test.rb
|
176
162
|
- spec/spec_helper.rb
|
177
163
|
- spec/support/timecop.rb
|
178
164
|
- spec/test_logger_spec.rb
|
@@ -195,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
181
|
version: '0'
|
196
182
|
requirements: []
|
197
183
|
rubyforge_project:
|
198
|
-
rubygems_version: 2.
|
184
|
+
rubygems_version: 2.4.5
|
199
185
|
signing_key:
|
200
186
|
specification_version: 4
|
201
187
|
summary: fluent logger for ruby
|
@@ -205,6 +191,7 @@ test_files:
|
|
205
191
|
- spec/logger_base_spec.rb
|
206
192
|
- spec/logger_spec.rb
|
207
193
|
- spec/null_logger_spec.rb
|
194
|
+
- spec/plugin/out_test.rb
|
208
195
|
- spec/spec_helper.rb
|
209
196
|
- spec/support/timecop.rb
|
210
197
|
- spec/test_logger_spec.rb
|
data/.gitmodules
DELETED