fluent-logger 0.3.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.
@@ -0,0 +1,17 @@
1
+
2
+ Release 0.3.0 - 2011/08/21
3
+
4
+ * Added 'tag' for event logs
5
+
6
+
7
+ Release 0.2.0 - 2011/08/05
8
+
9
+ * Redesigned Event class
10
+ * Added TestLogger (Fluent.open(:test))
11
+ * Added test programs
12
+
13
+
14
+ Release 0.1.0 - 2011/08/04
15
+
16
+ * First release
17
+
@@ -0,0 +1,117 @@
1
+ = Fluent logger
2
+
3
+ A structured event loger
4
+
5
+ == Examples
6
+
7
+ === Simple
8
+
9
+ require 'fluent-logger'
10
+
11
+ EventLogger = Fluent::Logger::ConsoleLogger.new(STDOUT)
12
+
13
+ module Event
14
+ AccessEvent = EventLogger.create_event('access', :agent, :action=>'access')
15
+ end
16
+
17
+ #=> access: action="access" agent="foo"
18
+ Event::AccessEvent.agent('foo').post!
19
+
20
+
21
+ === Singleton
22
+
23
+ require 'fluent-logger'
24
+
25
+ Fluent::Logger::ConsoleLogger.open(STDOUT)
26
+
27
+ module Event
28
+ AccessEvent = Fluent::Logger.create_event('access', :agent, :action=>'access')
29
+ end
30
+
31
+ #=> access: action="access" agent="foo"
32
+ Event::AccessEvent.agent('foo').post!
33
+
34
+
35
+ === Combine events
36
+
37
+ require 'fluent-logger'
38
+
39
+ EventLogger = Fluent::Logger::ConsoleLogger.new(STDOUT)
40
+
41
+ module Event
42
+ User = EventLogger.create_event('user', :name, :age)
43
+ LoginEvent = EventLogger.create_event('login', :action=>'login')
44
+ BuyEvent = EventLogger.create_event('buy', :item, :action=>'login')
45
+ end
46
+
47
+ e_user = Event::User.name('me').age(24)
48
+
49
+ #=> login: action="login" name="me" age=24
50
+ Event::LoginEvent.with(e_user).post!
51
+
52
+ #=> buy: action="login" name="me" age=24 item="item01"
53
+ Event::BuyEvent.with(e_user).item("item01").post!
54
+
55
+ === Update created events
56
+
57
+ require 'fluent-logger'
58
+
59
+ EventLogger = Fluent::Logger::ConsoleLogger.new(STDOUT)
60
+
61
+ module Event
62
+ User = EventLogger.create_event('user', :name, :age)
63
+ AgeChangeEvent = EventLogger.create_event('age_change', :changed_age, :action=>'age_change')
64
+ BuyEvent = EventLogger.create_event('buy', :item, :action=>'buy')
65
+ end
66
+
67
+ e_user = User.name('me').age(24)
68
+
69
+ #=> age_change: action="age_change" name="me" age=24 changed_age=25
70
+ Event::AgeChangeEvent.with(e_user).changed_age(25).post!
71
+ e_user.age!(25)
72
+
73
+ #=> buy: action="buy" name="me" age=25 item="item01"
74
+ Event::BuyEvent.with(e_user).item("item01").post!
75
+
76
+ === Update created events by combining
77
+
78
+ require 'fluent-logger'
79
+
80
+ EventLogger = Fluent::Logger::ConsoleLogger.new(STDOUT)
81
+
82
+ module Event
83
+ User = EventLogger.create_event('user', :name, :age)
84
+ Browser = EventLogger.create_event('browser', :host, :agent)
85
+ LoginEvent = EventLogger.create_event('login', :action=>'login')
86
+ end
87
+
88
+ e_user = Event::User.name('me').age(24)
89
+ e_browser = Event::Browser.host('remoteip').agent('firefox')
90
+ e_user.with!(e_browser)
91
+
92
+ #=> login: action="login" name="me" age=24 host="remoteip" agent="firefox"
93
+ Event::LoginEvent.with(e_user).post!
94
+
95
+
96
+ == Loggers
97
+
98
+ === Console
99
+
100
+ Fluent::Logger::ConsoleLogger.open(io)
101
+
102
+ === Syslog
103
+
104
+ Fluent::Logger::SyslogLogger.open(ident=$0, level=:info)
105
+
106
+ === Fluent
107
+
108
+ Fluent::Logger::FluentLogger.open('tag_prefix', 'host', port=24224)
109
+
110
+
111
+ Web site:: http://fluent.github.com/
112
+ Documents:: http://fluent.github.com/doc/
113
+ Source repository:: http://github.com/fluent
114
+ Author:: Sadayuki Furuhashi
115
+ Copyright:: (c) 2011 FURUHASHI Sadayuki
116
+ License:: Apache License, Version 2.0
117
+
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'fluent', 'logger')
@@ -0,0 +1,92 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+
21
+ module Logger
22
+ require 'fluent/logger/event'
23
+ require 'fluent/logger/base'
24
+
25
+ class DefaultLogger < LoggerBase
26
+ INSTANCE = self.new
27
+
28
+ def self.instance
29
+ INSTANCE
30
+ end
31
+
32
+ def self.new
33
+ INSTANCE
34
+ end
35
+
36
+ def post(tag, map)
37
+ Fluent::Logger.default.post(tag, map)
38
+ end
39
+
40
+ def close
41
+ Fluent::Logger.default.close
42
+ end
43
+ end
44
+
45
+ @@default_logger = nil
46
+
47
+ def self.new(*args)
48
+ if args.first.is_a?(Class) && args.first.ancestors.include?(LoggerBase)
49
+ type = args.shift
50
+ else
51
+ type = FluentLogger
52
+ end
53
+ type.new(*args)
54
+ end
55
+
56
+ def self.open(*args)
57
+ close
58
+ @@default_logger = new(*args)
59
+ end
60
+
61
+ def self.close
62
+ if @@default_logger
63
+ @@default_logger.close
64
+ @@default_logger = nil
65
+ end
66
+ end
67
+
68
+ def self.create_event(*args)
69
+ DefaultLogger.instance.create_event(*args)
70
+ end
71
+
72
+ def self.post(tag, map)
73
+ DefaultLogger.instance.post(tag, map)
74
+ end
75
+
76
+ def self.default
77
+ @@default_logger ||= ConsoleLogger.new(STDOUT)
78
+ end
79
+
80
+ def self.default=(logger)
81
+ @@default_logger = logger
82
+ end
83
+
84
+ autoload :FluentLogger, 'fluent/logger/fluent'
85
+ autoload :ConsoleLogger, 'fluent/logger/console'
86
+ autoload :SyslogLogger, 'fluent/logger/syslog'
87
+ autoload :TestLogger, 'fluent/logger/test'
88
+ end
89
+
90
+
91
+ end
92
+
@@ -0,0 +1,89 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+ module Logger
20
+
21
+
22
+ class LoggerBase
23
+ def self.open(*args, &block)
24
+ Fluent::Logger.open(self, *args, &block)
25
+ end
26
+
27
+ def create_event(tag, *args)
28
+ map = {}
29
+ keys = []
30
+ args.each {|a|
31
+ case a
32
+ when Hash
33
+ a.each_pair {|k,v|
34
+ keys << k.to_sym
35
+ map[k.to_sym] = v
36
+ }
37
+ else
38
+ keys << a.to_sym
39
+ end
40
+ }
41
+
42
+ m = Module.new
43
+ m.module_eval do
44
+ keys.each {|key|
45
+ define_method(key) do |v|
46
+ with(key=>v)
47
+ end
48
+ define_method(:"#{key}!") do |v|
49
+ with!(key=>v)
50
+ end
51
+ }
52
+ define_method(:MODULE) { m }
53
+ end
54
+
55
+ e = TerminalEvent.new(self, tag, map)
56
+ e.extend(m)
57
+ e
58
+ end
59
+
60
+ #def post(tag, map)
61
+ #end
62
+
63
+ #def close(map)
64
+ #end
65
+ end
66
+
67
+
68
+ class TextLogger < LoggerBase
69
+ def initialize
70
+ require 'json'
71
+ @time_format = "%b %e %H:%M:%S"
72
+ end
73
+
74
+ def post(tag, map)
75
+ a = [Time.now.strftime(@time_format), " ", tag, ":"]
76
+ map.each_pair {|k,v|
77
+ a << " #{k}="
78
+ a << v.to_json
79
+ }
80
+ post_text a.join
81
+ end
82
+
83
+ #def post_text(text)
84
+ #end
85
+ end
86
+
87
+
88
+ end
89
+ end
@@ -0,0 +1,56 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+ module Logger
20
+
21
+
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 "Invlaid 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
52
+ end
53
+
54
+
55
+ end
56
+ end
@@ -0,0 +1,118 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+ module Logger
20
+
21
+
22
+ class Event
23
+ def initialize(link, map)
24
+ @link = link
25
+ @map = map
26
+ end
27
+
28
+ def to_hash(o={})
29
+ @link.to_hash(o)
30
+ o.merge!(@map)
31
+ o
32
+ end
33
+
34
+ def tag
35
+ @link.tag
36
+ end
37
+
38
+ def logger
39
+ @link.logger
40
+ end
41
+
42
+ def logger=(logger)
43
+ @link.logger = logger
44
+ end
45
+
46
+ def post!(with_tag=tag)
47
+ logger.post(with_tag, to_hash)
48
+ self
49
+ end
50
+
51
+ alias post post!
52
+
53
+ def with(a)
54
+ if a.is_a?(Event)
55
+ ma = MODULE()
56
+ mb = a.MODULE()
57
+ m = Module.new
58
+ m.module_eval do
59
+ include ma
60
+ include mb
61
+ define_method(:MODULE) { m }
62
+ end
63
+ map = a.to_hash(to_hash)
64
+ e = TerminalEvent.new(LOGGER(), tag, map)
65
+ e.extend(m)
66
+ else
67
+ map = a.to_hash
68
+ e = Event.new(self, map)
69
+ e.extend(MODULE())
70
+ end
71
+ e
72
+ end
73
+
74
+ alias + with
75
+
76
+ def with!(a)
77
+ if a.is_a?(Event)
78
+ self.extend a.MODULE()
79
+ a.to_hash(@map)
80
+ else
81
+ @map.merge!(a.to_hash)
82
+ end
83
+ self
84
+ end
85
+
86
+ def create_event(*args)
87
+ self.with(LOGGER().create_event(*args))
88
+ end
89
+
90
+ def LOGGER
91
+ @link.LOGGER()
92
+ end
93
+ end
94
+
95
+
96
+ class TerminalEvent < Event
97
+ def initialize(logger, tag, map)
98
+ @logger = logger
99
+ @tag = tag
100
+ @map = map
101
+ end
102
+
103
+ def to_hash(o={})
104
+ o.merge!(@map)
105
+ o
106
+ end
107
+
108
+ attr_accessor :tag
109
+ attr_accessor :logger
110
+
111
+ def LOGGER
112
+ @logger
113
+ end
114
+ end
115
+
116
+
117
+ end
118
+ end
@@ -0,0 +1,115 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+ module Logger
20
+
21
+
22
+ class FluentLogger < LoggerBase
23
+ BUFFER_LIMIT = 8*1024*1024
24
+
25
+ def initialize(tag, host, port=24224)
26
+ super()
27
+ require 'msgpack'
28
+ require 'socket'
29
+ require 'monitor'
30
+ require 'logger'
31
+ @mon = Monitor.new
32
+
33
+ @tag = tag
34
+
35
+ @pending = nil
36
+ @host = host
37
+ @port = port
38
+ connect!
39
+
40
+ @limit = BUFFER_LIMIT
41
+ @logger = ::Logger.new(STDERR)
42
+
43
+ FluentLogger.close_on_exit(self)
44
+ end
45
+
46
+ attr_accessor :limit, :logger
47
+
48
+ def post(tag, map)
49
+ time = Time.now.to_i
50
+ write ["#{@tag}.#{tag}", time, map]
51
+ end
52
+
53
+ def close
54
+ if @pending
55
+ @logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}")
56
+ end
57
+ @con.close if @con
58
+ @con = nil
59
+ @pending = nil
60
+ self
61
+ end
62
+
63
+ private
64
+ def write(msg)
65
+ data = msg.to_msgpack
66
+ @mon.synchronize {
67
+ if @pending
68
+ @pending << data
69
+ data = @pending
70
+ end
71
+ begin
72
+ unless @con
73
+ connect!
74
+ end
75
+ while true
76
+ n = @con.syswrite(data)
77
+ if n >= data.bytesize
78
+ break
79
+ end
80
+ data = data[n..-1]
81
+ end
82
+ @pending = nil
83
+ rescue
84
+ if @pending
85
+ if @pending.bytesize > @limit
86
+ @logger.error("FluentLogger: Can't send logs to #{@host}:#{@port}")
87
+ @pending = nil
88
+ end
89
+ else
90
+ @pending = data
91
+ end
92
+ @con.close if @con
93
+ @con = nil
94
+ end
95
+ }
96
+ end
97
+
98
+ def connect!
99
+ @con = TCPSocket.new(@host, @port)
100
+ end
101
+
102
+ def self.close_on_exit(logger)
103
+ ObjectSpace.define_finalizer(logger, self.finalizer(logger))
104
+ end
105
+
106
+ def self.finalizer(logger)
107
+ proc {
108
+ logger.close
109
+ }
110
+ end
111
+ end
112
+
113
+
114
+ end
115
+ end
@@ -0,0 +1,127 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+ module Logger
20
+
21
+
22
+ class SyslogLogger < TextLogger
23
+ def initialize(ident=$0, level=:info)
24
+ super()
25
+ require 'syslog'
26
+
27
+ @ident = ident
28
+ self.level = level
29
+ #self.facility = facility
30
+ Syslog.open(@ident)
31
+ end
32
+
33
+ attr_reader :level
34
+
35
+ def level=(level)
36
+ level = level.to_sym if level.is_a?(String)
37
+ @level = case level
38
+ when :emerg, Syslog::LOG_EMERG
39
+ Syslog::LOG_EMERG
40
+ when :alert, Syslog::LOG_ALERT
41
+ Syslog::LOG_ALERT
42
+ when :crit, Syslog::LOG_CRIT
43
+ Syslog::LOG_CRIT
44
+ when :err, :error, Syslog::LOG_ERR
45
+ Syslog::LOG_ERR
46
+ when :warning, :warn, Syslog::LOG_WARNING
47
+ Syslog::LOG_WARNING
48
+ when :notice, Syslog::LOG_NOTICE
49
+ Syslog::LOG_NOTICE
50
+ when :info, Syslog::LOG_INFO
51
+ Syslog::LOG_INFO
52
+ when :debug, Syslog::LOG_DEBUG
53
+ Syslog::LOG_DEBUG
54
+ else
55
+ raise "Unknown level description #{level.inspect}"
56
+ end
57
+ end
58
+
59
+ #def facility=(facility)
60
+ # facility = facility.to_sym if facility.is_a?(String)
61
+ # @facility = case facility
62
+ # when :auth, Syslog::LOG_AUTH
63
+ # Syslog::LOG_AUTH
64
+ # when :authpriv, Syslog::LOG_AUTHPRIV
65
+ # Syslog::LOG_AUTHPRIV
66
+ # when :console, Syslog::LOG_CONSOLE
67
+ # Syslog::LOG_CONSOLE
68
+ # when :cron, Syslog::LOG_CRON
69
+ # Syslog::LOG_CRON
70
+ # when :daemon, Syslog::LOG_DAEMON
71
+ # Syslog::LOG_DAEMON
72
+ # when :ftp, Syslog::LOG_FTP
73
+ # Syslog::LOG_FTP
74
+ # when :kern, Syslog::LOG_KERN
75
+ # Syslog::LOG_KERN
76
+ # when :lpr, Syslog::LOG_LPR
77
+ # Syslog::LOG_LPR
78
+ # when :mail, Syslog::LOG_MAIL
79
+ # Syslog::LOG_MAIL
80
+ # when :news, Syslog::LOG_NEWS
81
+ # Syslog::LOG_NEWS
82
+ # when :ntp, Syslog::LOG_NTP
83
+ # Syslog::LOG_NTP
84
+ # when :security, Syslog::LOG_SECURITY
85
+ # Syslog::LOG_SECURITY
86
+ # when :syslog, Syslog::LOG_SYSLOG
87
+ # Syslog::LOG_SYSLOG
88
+ # when :user, Syslog::LOG_USER
89
+ # Syslog::LOG_USER
90
+ # when :uucp, Syslog::LOG_UUCP
91
+ # Syslog::LOG_UUCP
92
+ # when :local0, Syslog::LOG_LOCAL0
93
+ # Syslog::LOG_LOCAL0
94
+ # when :local1, Syslog::LOG_LOCAL1
95
+ # Syslog::LOG_LOCAL1
96
+ # when :local2, Syslog::LOG_LOCAL2
97
+ # Syslog::LOG_LOCAL2
98
+ # when :local3, Syslog::LOG_LOCAL3
99
+ # Syslog::LOG_LOCAL3
100
+ # when :local4, Syslog::LOG_LOCAL4
101
+ # Syslog::LOG_LOCAL4
102
+ # when :local5, Syslog::LOG_LOCAL5
103
+ # Syslog::LOG_LOCAL5
104
+ # when :local6, Syslog::LOG_LOCAL6
105
+ # Syslog::LOG_LOCAL6
106
+ # when :local7, Syslog::LOG_LOCAL7
107
+ # Syslog::LOG_LOCAL7
108
+ # else
109
+ # raise "Unknown facility description #{facility.inspect}"
110
+ # end
111
+ # Syslog.reopen(@ident, Syslog::LOG_PID|Syslog::LOG_CONS, @facility)
112
+ # facility
113
+ #end
114
+
115
+ def post_text(text)
116
+ Syslog.log(@level, "%s", text)
117
+ end
118
+
119
+ def close
120
+ Syslog.close
121
+ self
122
+ end
123
+ end
124
+
125
+
126
+ end
127
+ end
@@ -0,0 +1,55 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
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
+ module Logger
20
+
21
+
22
+ class TestLogger < LoggerBase
23
+ def initialize(queue=[])
24
+ @queue = queue
25
+ @max = 1024
26
+ @close_called = 0
27
+ end
28
+
29
+ attr_accessor :max
30
+ attr_reader :queue
31
+ attr_reader :close_called
32
+
33
+ def post(tag, map)
34
+ while @queue.size > @max
35
+ @queue.shift
36
+ end
37
+ (class<<map;self;end).module_eval do
38
+ define_method(:tag) { tag }
39
+ end
40
+ @queue << map
41
+ end
42
+
43
+ def close
44
+ @close_called += 1
45
+ end
46
+
47
+ def closed?
48
+ @close_called > 0
49
+ end
50
+ end
51
+
52
+
53
+ end
54
+ end
55
+
@@ -0,0 +1,7 @@
1
+ module Fluent
2
+ module Logger
3
+
4
+ VERSION = '0.3.0'
5
+
6
+ end
7
+ end
@@ -0,0 +1,183 @@
1
+ require File.dirname(__FILE__)+'/test_helper'
2
+
3
+ class EventTest < Test::Unit::TestCase
4
+ it 'keys' do
5
+ g = Fluent::Logger::TestLogger.new
6
+
7
+ assert_nothing_raised do
8
+ e1 = g.create_event('e1', :k1)
9
+ e1.k1('v1')
10
+ end
11
+
12
+ assert_raise(NoMethodError) do
13
+ e2 = g.create_event('e2')
14
+ e2.k1('v1')
15
+ end
16
+
17
+ assert_raise(NoMethodError) do
18
+ e3 = g.create_event('e3', :k1)
19
+ e3.k2('v2')
20
+ end
21
+ end
22
+
23
+ it 'set_value' do
24
+ g = Fluent::Logger::TestLogger.new
25
+
26
+ e1 = g.create_event('e1', :k1)
27
+ e1.k1('v1').post!
28
+ assert_equal g.queue.last, {:k1=>'v1'}
29
+
30
+ e2 = g.create_event('e2', :k1, :k2)
31
+ e2.k1('v1').k2('v2').post!
32
+ assert_equal g.queue.last, {:k1=>'v1', :k2=>'v2'}
33
+
34
+ e3 = g.create_event('e3', :k1, :k2)
35
+ e3.k1('v1').post!
36
+ assert_equal g.queue.last, {:k1=>'v1'}
37
+ end
38
+
39
+ it 'default_value' do
40
+ g = Fluent::Logger::TestLogger.new
41
+
42
+ e1 = g.create_event('e1', :k1)
43
+ e1.post!
44
+ assert_equal g.queue.last, {}
45
+
46
+ e2 = g.create_event('e2', :k1=>'v1')
47
+ e2.post!
48
+ assert_equal g.queue.last, {:k1=>'v1'}
49
+
50
+ e3 = g.create_event('e3', :k1=>'v1', :k2=>'v2')
51
+ e3.post!
52
+ assert_equal g.queue.last, {:k1=>'v1', :k2=>'v2'}
53
+
54
+ e4 = g.create_event('e4', :k1=>'v1', :k2=>'v2')
55
+ e4.k2('v3').post!
56
+ assert_equal g.queue.last, {:k1=>'v1', :k2=>'v3'}
57
+ end
58
+
59
+ it 'modify' do
60
+ g = Fluent::Logger::TestLogger.new
61
+
62
+ e1 = g.create_event('e1', :k1)
63
+ e1.k1!('v1')
64
+ e1.post!
65
+ assert_equal g.queue.last, {:k1=>'v1'}
66
+
67
+ e1.k1!('v2')
68
+ e1.post!
69
+ assert_equal g.queue.last, {:k1=>'v2'}
70
+
71
+ e2 = g.create_event('e2', :k1=>'v1')
72
+ e2.k1!('v2')
73
+ e2.post!
74
+ assert_equal g.queue.last, {:k1=>'v2'}
75
+ end
76
+
77
+ it 'no_modify' do
78
+ g = Fluent::Logger::TestLogger.new
79
+
80
+ e1 = g.create_event('e1', :k1)
81
+ e1.k1('v1')
82
+ e1.post!
83
+ assert_equal g.queue.last, {}
84
+
85
+ e1.k1('v2')
86
+ e1.post!
87
+ assert_equal g.queue.last, {}
88
+
89
+ e2 = g.create_event('e1', :k1=>'v1')
90
+ e2.k1('v2')
91
+ e2.post!
92
+ assert_equal g.queue.last, {:k1=>'v1'}
93
+ end
94
+
95
+ it 'with_map' do
96
+ g = Fluent::Logger::TestLogger.new
97
+
98
+ e1 = g.create_event('e1')
99
+ e1.with(:k1=>'v1').post!
100
+ assert_equal g.queue.last, {:k1=>'v1'}
101
+
102
+ e2 = g.create_event('e2', :k1=>'v1')
103
+ e2.with(:k1=>'v2').post!
104
+ assert_equal g.queue.last, {:k1=>'v2'}
105
+
106
+ e3 = g.create_event('e3', :k1=>'v1')
107
+ e3.with(:k1=>'v2', :k2=>'v3').post!
108
+ assert_equal g.queue.last, {:k1=>'v2', :k2=>'v3'}
109
+ end
110
+
111
+ it 'with_map_modify' do
112
+ g = Fluent::Logger::TestLogger.new
113
+
114
+ e1 = g.create_event('e2', :k1)
115
+ e1.with!(:k1=>'v1')
116
+ e1.post!
117
+ assert_equal g.queue.last, {:k1=>'v1'}
118
+
119
+ e1.with!(:k1=>'v2')
120
+ e1.post!
121
+ assert_equal g.queue.last, {:k1=>'v2'}
122
+
123
+ e2 = g.create_event('e2')
124
+ e2.with!(:k1=>'v1', :k2=>'v2')
125
+ e2.post!
126
+ assert_equal g.queue.last, {:k1=>'v1', :k2=>'v2'}
127
+
128
+ e2.with!(:k1=>'v3')
129
+ e2.post!
130
+ assert_equal g.queue.last, {:k1=>'v3', :k2=>'v2'}
131
+ end
132
+
133
+ it 'with_event_keys' do
134
+ g = Fluent::Logger::TestLogger.new
135
+
136
+ assert_nothing_raised do
137
+ e1 = g.create_event('e1', :k1)
138
+ e2 = g.create_event('e2', :k2)
139
+ e3 = e1.with(e2)
140
+ e3.k1('v1').k2('v2')
141
+ end
142
+
143
+ assert_nothing_raised do
144
+ e1 = g.create_event('e1', :k1)
145
+ e2 = g.create_event('e2', :k1, :k2)
146
+ e3 = e1.with(e2)
147
+ e3.k1('v1').k2('v2')
148
+ end
149
+
150
+ assert_nothing_raised do
151
+ e1 = g.create_event('e1', :k1)
152
+ e2 = g.create_event('e2', :k2)
153
+ e1.with!(e2)
154
+ e1.k1('v1').k2('v2')
155
+ end
156
+
157
+ assert_raise(NoMethodError) do
158
+ e1 = g.create_event('e1', :k1)
159
+ e2 = g.create_event('e2', :k2)
160
+ e3 = e1.with(e2)
161
+ e1.k2('v1')
162
+ end
163
+
164
+ assert_raise(NoMethodError) do
165
+ e1 = g.create_event('e1', :k1)
166
+ e2 = g.create_event('e2', :k2)
167
+ e1.with!(e2)
168
+ e2.k1('v1')
169
+ end
170
+ end
171
+
172
+ it 'tag' do
173
+ g = Fluent::Logger::TestLogger.new
174
+
175
+ e1 = g.create_event('e1')
176
+ e1.post!
177
+ assert_equal g.queue.last.tag, 'e1'
178
+
179
+ e1.post!('e2')
180
+ assert_equal g.queue.last.tag, 'e2'
181
+ end
182
+ end
183
+
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__)+'/test_helper'
2
+
3
+ class InstanceTest < Test::Unit::TestCase
4
+ it 'default' do
5
+ g1 = Fluent::Logger::TestLogger.open
6
+ assert_equal g1.object_id, Fluent::Logger.default.object_id
7
+
8
+ assert_equal false, g1.closed?
9
+
10
+ g2 = Fluent::Logger::TestLogger.open
11
+ assert_equal g2.object_id, Fluent::Logger.default.object_id
12
+
13
+ assert_equal true, g1.closed?
14
+
15
+ g3 = Fluent::Logger::TestLogger.new
16
+ assert_equal g2.object_id, Fluent::Logger.default.object_id
17
+
18
+ assert_equal false, g2.closed?
19
+ Fluent::Logger.close
20
+ assert_equal true, g2.closed?
21
+ end
22
+
23
+ it 'post' do
24
+ g1 = Fluent::Logger::TestLogger.new
25
+
26
+ g1.post :k1=>'v1'
27
+ assert_equal g1.queue.last, {:k1=>'v1'}
28
+
29
+ g2 = Fluent::Logger::TestLogger.open
30
+
31
+ Fluent::Logger.post :k2=>'v2'
32
+ assert_equal g2.queue.last, {:k2=>'v2'}
33
+ end
34
+ end
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__)+'/test_helper'
2
+
3
+ class SimpleTest < Test::Unit::TestCase
4
+ it 'singleton' do
5
+ Fluent::Logger::ConsoleLogger.open(STDOUT)
6
+
7
+ AccessEvent = Fluent::Logger.create_event('e1', :agent, :action=>'access')
8
+ LoginEvent = Fluent::Logger.create_event('e2', :user, :action=>'login')
9
+
10
+ #=> action="access" agent="foo"
11
+ AccessEvent.agent('foo').post!
12
+
13
+ #=> action="login" user="bar"
14
+ LoginEvent.user('bar').post!
15
+ end
16
+
17
+ it 'local' do
18
+ E2_LOG = Fluent::Logger::ConsoleLogger.new(STDOUT)
19
+
20
+ E2_AccessEvent = E2_LOG.create_event('e1', :agent, :action=>'access')
21
+ E2_LoginEvent = E2_LOG.create_event('e2', :user, :action=>'login')
22
+
23
+ #=> action="access" agent="foo"
24
+ E2_AccessEvent.agent('foo').post!
25
+
26
+ #=> action="login" user="bar"
27
+ E2_LoginEvent.user('bar').post!
28
+ end
29
+
30
+ it 'combine' do
31
+ E3_LOG = Fluent::Logger::ConsoleLogger.new(STDOUT)
32
+
33
+ E3_User = E3_LOG.create_event('e1', :name, :age)
34
+ E3_LoginEvent = E3_LOG.create_event('e2', :action=>'login')
35
+ E3_BuyEvent = E3_LOG.create_event('e3', :item, :action=>'login')
36
+
37
+ e_user = E3_User.name('me').age(24)
38
+
39
+ #=> action="login" name="me" age=24
40
+ E3_LoginEvent.with(e_user).post!
41
+
42
+ #=> action="login" name="me" age=24 item="item01"
43
+ E3_BuyEvent.with(e_user).item("item01").post!
44
+ end
45
+
46
+ it 'update' do
47
+ E4_LOG = Fluent::Logger::ConsoleLogger.new(STDOUT)
48
+
49
+ E4_User = E4_LOG.create_event('e1', :name, :age)
50
+ E4_AgeChangeEvent = E4_LOG.create_event('e2', :changed_age, :action=>'age_change')
51
+ E4_BuyEvent = E4_LOG.create_event('e3', :item, :action=>'buy')
52
+
53
+ e_user = E4_User.name('me').age(24)
54
+
55
+ #=> action="age_change" name="me" age=24 changed_age=25
56
+ E4_AgeChangeEvent.with(e_user).changed_age(25).post!
57
+ e_user.age!(25)
58
+
59
+ #=> action="buy" name="me" age=25 item="item01"
60
+ E4_BuyEvent.with(e_user).item("item01").post!
61
+ end
62
+
63
+ it 'combine_update' do
64
+ E5_LOG = Fluent::Logger::ConsoleLogger.new(STDOUT)
65
+
66
+ E5_User = E5_LOG.create_event('e1', :name, :age)
67
+ E5_Browser = E5_LOG.create_event('e2', :host, :agent)
68
+ E5_LoginEvent = E5_LOG.create_event('e3', :action=>'login')
69
+
70
+ e_user = E5_User.name('me').age(24)
71
+ e_browser = E5_Browser.host('remoteip').agent('firefox')
72
+ e_user.with!(e_browser)
73
+
74
+ #=> action="login" name="me" age=24 host="remoteip" agent="firefox"
75
+ E5_LoginEvent.with(e_user).post!
76
+ end
77
+ end
78
+
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ $LOAD_PATH << File.dirname(__FILE__)+"/../lib"
3
+ require 'fluent/logger'
4
+ require 'fileutils'
5
+
6
+ class Test::Unit::TestCase
7
+ #class << self
8
+ # alias_method :it, :test
9
+ #end
10
+ def self.it(name, &block)
11
+ define_method("test_#{name}", &block)
12
+ end
13
+ end
14
+
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-logger
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
+ platform: ruby
12
+ authors:
13
+ - Sadayuki Furuhashi
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-21 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: msgpack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 0
32
+ - 4
33
+ - 4
34
+ version: 0.4.4
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 1
46
+ segments:
47
+ - 1
48
+ - 4
49
+ - 3
50
+ version: 1.4.3
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ description:
54
+ email: frsyuki@gmail.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files:
60
+ - ChangeLog
61
+ - README.rdoc
62
+ files:
63
+ - lib/fluent-logger.rb
64
+ - lib/fluent/logger.rb
65
+ - lib/fluent/logger/base.rb
66
+ - lib/fluent/logger/console.rb
67
+ - lib/fluent/logger/event.rb
68
+ - lib/fluent/logger/fluent.rb
69
+ - lib/fluent/logger/syslog.rb
70
+ - lib/fluent/logger/test.rb
71
+ - lib/fluent/logger/version.rb
72
+ - test/event_test.rb
73
+ - test/instance_test.rb
74
+ - test/simple_test.rb
75
+ - test/test_helper.rb
76
+ - ChangeLog
77
+ - README.rdoc
78
+ has_rdoc: true
79
+ homepage: http://fluent.github.com/
80
+ licenses: []
81
+
82
+ post_install_message:
83
+ rdoc_options:
84
+ - --charset=UTF-8
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ requirements: []
106
+
107
+ rubyforge_project:
108
+ rubygems_version: 1.3.7
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: Structured event logger
112
+ test_files:
113
+ - test/event_test.rb
114
+ - test/instance_test.rb
115
+ - test/simple_test.rb
116
+ - test/test_helper.rb