right_support 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +38 -14
- data/lib/right_support.rb +1 -1
- data/lib/right_support/crypto/signed_hash.rb +11 -2
- data/lib/right_support/db.rb +1 -3
- data/lib/right_support/db/cassandra_model.rb +299 -18
- data/lib/right_support/log.rb +4 -0
- data/lib/right_support/log/exception_logger.rb +86 -0
- data/lib/right_support/log/filter_logger.rb +75 -0
- data/lib/right_support/log/mixin.rb +104 -0
- data/lib/right_support/log/multiplexer.rb +93 -0
- data/lib/right_support/log/null_logger.rb +76 -0
- data/lib/right_support/net.rb +5 -3
- data/lib/right_support/net/balancing/health_check.rb +40 -23
- data/lib/right_support/net/request_balancer.rb +19 -32
- data/lib/right_support/rack.rb +2 -3
- data/lib/right_support/rack/custom_logger.rb +29 -8
- data/lib/right_support/rack/request_logger.rb +113 -0
- data/lib/right_support/ruby.rb +4 -3
- data/lib/right_support/ruby/easy_singleton.rb +24 -0
- data/lib/right_support/ruby/object_extensions.rb +18 -2
- data/lib/right_support/ruby/string_extensions.rb +120 -0
- data/lib/right_support/stats.rb +34 -0
- data/lib/right_support/stats/activity.rb +206 -0
- data/lib/right_support/stats/exceptions.rb +96 -0
- data/lib/right_support/stats/helpers.rb +438 -0
- data/lib/right_support/validation.rb +2 -4
- data/right_support.gemspec +3 -5
- metadata +18 -20
data/lib/right_support/log.rb
CHANGED
@@ -32,3 +32,7 @@ end
|
|
32
32
|
require 'right_support/log/system_logger'
|
33
33
|
require 'right_support/log/filter_logger'
|
34
34
|
require 'right_support/log/tag_logger'
|
35
|
+
require 'right_support/log/null_logger'
|
36
|
+
require 'right_support/log/multiplexer'
|
37
|
+
require 'right_support/log/exception_logger'
|
38
|
+
require 'right_support/log/mixin'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightSupport::Log
|
24
|
+
# A logger that prepends a tag to every message that is emitted. Can be used to
|
25
|
+
# correlate logs with a Web session ID, transaction ID or other context.
|
26
|
+
#
|
27
|
+
# The user of this logger is responsible for calling #tag= to set the tag as
|
28
|
+
# appropriate, e.g. in a Web request around-filter.
|
29
|
+
#
|
30
|
+
# This logger uses thread-local storage (TLS) to provide tagging on a per-thread
|
31
|
+
# basis; however, it does not account for EventMachine, neverblock, the use of
|
32
|
+
# Ruby fibers, or any other phenomenon that can "hijack" a thread's call stack.
|
33
|
+
#
|
34
|
+
class ExceptionLogger < FilterLogger
|
35
|
+
# Format exception information
|
36
|
+
#
|
37
|
+
# === Parameters
|
38
|
+
# description(String):: Error description
|
39
|
+
# exception(Exception|String):: Associated exception or other parenthetical error information
|
40
|
+
# backtrace(Symbol):: Exception backtrace extent: :no_trace, :caller, or :trace,
|
41
|
+
# defaults to :caller
|
42
|
+
#
|
43
|
+
# === Return
|
44
|
+
# (String):: Information about the exception in a format suitable for logging
|
45
|
+
def self.format_exception(description, exception = nil, backtrace = :caller)
|
46
|
+
if exception
|
47
|
+
if exception.respond_to?(:message)
|
48
|
+
description += " (#{exception.class}: #{exception.message}"
|
49
|
+
else
|
50
|
+
description += " (#{exception}"
|
51
|
+
end
|
52
|
+
|
53
|
+
unless exception.respond_to?(:backtrace) && exception.backtrace
|
54
|
+
backtrace = :no_trace
|
55
|
+
end
|
56
|
+
|
57
|
+
case backtrace
|
58
|
+
when :no_trace
|
59
|
+
description += ")"
|
60
|
+
when :caller
|
61
|
+
description += " IN " + exception.backtrace[0] + ")"
|
62
|
+
when :trace
|
63
|
+
description += " IN\n " + exception.backtrace.join("\n ") + ")"
|
64
|
+
else
|
65
|
+
raise ArgumentError, "Unknown backtrace value #{backtrace.inspect}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
description
|
70
|
+
end
|
71
|
+
|
72
|
+
# Log information about an exception with ERROR severity.
|
73
|
+
#
|
74
|
+
# === Parameters
|
75
|
+
# description(String):: Error description
|
76
|
+
# exception(Exception|String):: Associated exception or other parenthetical error information
|
77
|
+
# backtrace(Symbol):: Exception backtrace extent: :no_trace, :caller, or :trace,
|
78
|
+
# defaults to :caller
|
79
|
+
#
|
80
|
+
# === Return
|
81
|
+
# Forwards the return value of its underlying logger's #error method
|
82
|
+
def exception(description, exception = nil, backtrace = :caller)
|
83
|
+
error(self.class.format_exception(description, exception, backtrace))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -27,7 +27,19 @@ module RightSupport::Log
|
|
27
27
|
# before they are passed to the underlying Logger. Can be used to for various log-
|
28
28
|
# processing tasks such as filtering sensitive data or tagging log lines with a
|
29
29
|
# context marker.
|
30
|
+
#
|
31
|
+
# FilterLogger implements method_missing and respond_to? and proxies unknown
|
32
|
+
# method calls to its underlying logger; this allows it to be used as a
|
33
|
+
# decorator.
|
30
34
|
class FilterLogger < Logger
|
35
|
+
SEVERITY_TO_METHOD = {
|
36
|
+
DEBUG => :debug,
|
37
|
+
INFO => :info,
|
38
|
+
WARN => :warn,
|
39
|
+
ERROR => :error,
|
40
|
+
FATAL => :fatal,
|
41
|
+
}
|
42
|
+
|
31
43
|
# Initialize a new instance of this class.
|
32
44
|
#
|
33
45
|
# === Parameters
|
@@ -35,7 +47,70 @@ module RightSupport::Log
|
|
35
47
|
#
|
36
48
|
def initialize(actual_logger)
|
37
49
|
@actual_logger = actual_logger
|
50
|
+
end
|
51
|
+
|
52
|
+
def method_missing(meth, *args)
|
53
|
+
return @actual_logger.__send__(meth, *args) if @actual_logger.respond_to?(meth)
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
def respond_to?(meth)
|
58
|
+
super(meth) || @actual_logger.respond_to?(meth)
|
59
|
+
end
|
38
60
|
|
61
|
+
# Log a message, filtering the severity and/or message and dispatching
|
62
|
+
# to the corresponding severity-method of the underlying logger.
|
63
|
+
#
|
64
|
+
# See #info for more information.
|
65
|
+
def debug(message = nil, &block)
|
66
|
+
severity, message = filter(DEBUG, message)
|
67
|
+
meth = SEVERITY_TO_METHOD[severity]
|
68
|
+
raise ArgumentError, "Filter emitted unknown severity #{severity.inspect}" unless meth
|
69
|
+
@actual_logger.__send__(meth, message, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Log a message, filtering the severity and/or message and dispatching
|
73
|
+
# to the corresponding severity-method of the underlying logger.
|
74
|
+
#
|
75
|
+
# See #info for more information.
|
76
|
+
def info(message = nil, &block)
|
77
|
+
severity, message = filter(INFO, message)
|
78
|
+
meth = SEVERITY_TO_METHOD[severity]
|
79
|
+
raise ArgumentError, "Filter emitted unknown severity #{severity.inspect}" unless meth
|
80
|
+
@actual_logger.__send__(meth, message, &block)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Log a message, filtering the severity and/or message and dispatching
|
84
|
+
# to the corresponding severity-method of the underlying logger.
|
85
|
+
#
|
86
|
+
# See #info for more information.
|
87
|
+
def warn(message = nil, &block)
|
88
|
+
severity, message = filter(WARN, message)
|
89
|
+
meth = SEVERITY_TO_METHOD[severity]
|
90
|
+
raise ArgumentError, "Filter emitted unknown severity #{severity.inspect}" unless meth
|
91
|
+
@actual_logger.__send__(meth, message, &block)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Log a message, filtering the severity and/or message and dispatching
|
95
|
+
# to the corresponding severity-method of the underlying logger.
|
96
|
+
#
|
97
|
+
# See #info for more information.
|
98
|
+
def error(message = nil, &block)
|
99
|
+
severity, message = filter(ERROR, message)
|
100
|
+
meth = SEVERITY_TO_METHOD[severity]
|
101
|
+
raise ArgumentError, "Filter emitted unknown severity #{severity.inspect}" unless meth
|
102
|
+
@actual_logger.__send__(meth, message, &block)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Log a message, filtering the severity and/or message and dispatching
|
106
|
+
# to the corresponding severity-method of the underlying logger.
|
107
|
+
#
|
108
|
+
# See #info for more information.
|
109
|
+
def fatal(message = nil, &block)
|
110
|
+
severity, message = filter(FATAL, message)
|
111
|
+
meth = SEVERITY_TO_METHOD[severity]
|
112
|
+
raise ArgumentError, "Filter emitted unknown severity #{severity.inspect}" unless meth
|
113
|
+
@actual_logger.__send__(meth, message, &block)
|
39
114
|
end
|
40
115
|
|
41
116
|
# Add a log line, filtering the severity and message before calling through
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightSupport::Log
|
24
|
+
# A mixin that facilitates access to a logger for classes that want logging functionality.
|
25
|
+
#
|
26
|
+
# === Basic Usage
|
27
|
+
# Your class must opt into logging by including the mixin:
|
28
|
+
# class AwesomenessProcessor
|
29
|
+
# include RightSupport::Log::Mixin
|
30
|
+
#
|
31
|
+
# Having opted in, your class now has a #logger instance method, as well as a .logger
|
32
|
+
# class method, which allows logging from either instance or class methods:
|
33
|
+
#
|
34
|
+
# def self.prepare_awesomeness_for_processing(input)
|
35
|
+
# logger.info "Preparing a #{input.class.name} for additional awesomeness"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# def process_awesomeness(input)
|
39
|
+
# input = self.class.prepare_awesomeness(input)
|
40
|
+
# logger.info "Processing #{input.size} units of awesomeness"
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# === Controlling Where Log Messages Go
|
44
|
+
# By default, your class shares a Logger object with all other classes that include the mixin.
|
45
|
+
# This process-wide default logger can be set or retrieved using module-level accessors:
|
46
|
+
#
|
47
|
+
# # default_logger starts out as a NullLogger; you probably want to set it to something different
|
48
|
+
# puts "Current logger: "+ RightSupport::Log::Mixin.default_logger.class
|
49
|
+
# RightSupport::Log::Mixin.default_logger = SyslogLogger.new('my program')
|
50
|
+
#
|
51
|
+
# It is good form to set the default logger; however, if your class needs additional or different
|
52
|
+
# logging functionality, you can override the logger on a per-class level:
|
53
|
+
# AwesomenessProcessor.logger = Logger.new(File.open('awesomeness.log', 'w'))
|
54
|
+
#
|
55
|
+
# Finally, you can override the logger on a per-instance level for truly fine-grained control.
|
56
|
+
# This is generally useless, but just in case:
|
57
|
+
# processor = AwesomenessProcessor.new
|
58
|
+
# processor.logger = Logger.new(File.open("#{processor.object_id}.log", 'w'))
|
59
|
+
#
|
60
|
+
module Mixin
|
61
|
+
# A decorator class which will be wrapped around any logger that is
|
62
|
+
# provided to any of the setter methods. This ensures that ExceptionLogger's
|
63
|
+
# methods will always be available to anyone who uses this mixin for logging.
|
64
|
+
Decorator = RightSupport::Log::ExceptionLogger
|
65
|
+
|
66
|
+
# Class methods that become available to classes that include Mixin.
|
67
|
+
module ClassMethods
|
68
|
+
def logger
|
69
|
+
@logger || RightSupport::Log::Mixin.default_logger
|
70
|
+
end
|
71
|
+
|
72
|
+
def logger=(logger)
|
73
|
+
logger = Decorator.new(logger) unless logger.nil? || logger.is_a?(Decorator)
|
74
|
+
@logger = logger
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Instance methods that become available to classes that include Mixin.
|
79
|
+
module InstanceMethods
|
80
|
+
def logger
|
81
|
+
@logger || self.class.logger
|
82
|
+
end
|
83
|
+
|
84
|
+
def logger=(logger)
|
85
|
+
logger = Decorator.new(logger) unless logger.nil? || logger.is_a?(Decorator)
|
86
|
+
@logger = logger
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.default_logger
|
91
|
+
@default_logger ||= Decorator.new(RightSupport::Log::NullLogger.new)
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.default_logger=(logger)
|
95
|
+
logger = Decorator.new(logger) unless logger.nil? || logger.is_a?(Decorator)
|
96
|
+
@default_logger = logger
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.included(base)
|
100
|
+
base.extend(ClassMethods)
|
101
|
+
base.__send__(:include, InstanceMethods)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2012 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightSupport::Log
|
24
|
+
# A log multiplexer that uses method_missing to dispatch method calls to zero or more
|
25
|
+
# target loggers. Caveat emptor: _you_ are responsible for ensuring that all of the targets
|
26
|
+
# respond to all of the messages you care to send; this class will perform no error checking
|
27
|
+
# for you!
|
28
|
+
class Multiplexer
|
29
|
+
|
30
|
+
# Access to underlying list of multiplexed objects
|
31
|
+
attr_reader :targets
|
32
|
+
|
33
|
+
# Prevent Kernel#warn from being called; #warn should be multiplexed to targets.
|
34
|
+
undef warn rescue nil
|
35
|
+
|
36
|
+
# Create a new multiplexer with a default list of targets.
|
37
|
+
#
|
38
|
+
# === Parameters
|
39
|
+
# targets(Object):: Targets that should receive the method calls
|
40
|
+
def initialize(*targets)
|
41
|
+
@targets = targets || []
|
42
|
+
end
|
43
|
+
|
44
|
+
# Add object to list of multiplexed targets
|
45
|
+
#
|
46
|
+
# === Parameters
|
47
|
+
# target(Object):: Add target to list of multiplexed targets
|
48
|
+
#
|
49
|
+
# === Return
|
50
|
+
# self(RightScale::Multiplexer):: self so operation can be chained
|
51
|
+
def add(target)
|
52
|
+
@targets << target unless @targets.include?(target)
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
# Remove object from list of multiplexed targets
|
57
|
+
#
|
58
|
+
# === Parameters
|
59
|
+
# target(Object):: Remove target from list of multiplexed targets
|
60
|
+
#
|
61
|
+
# === Return
|
62
|
+
# self(RightScale::Multiplexer):: self so operation can be chained
|
63
|
+
def remove(target)
|
64
|
+
@targets.delete_if { |t| t == target }
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
# Access target at given index
|
69
|
+
#
|
70
|
+
# === Parameters
|
71
|
+
# index(Integer):: Target index
|
72
|
+
#
|
73
|
+
# === Return
|
74
|
+
# target(Object):: Target at index 'index' or nil if none
|
75
|
+
def [](index)
|
76
|
+
target = @targets[index]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Forward any method invocation to targets
|
80
|
+
#
|
81
|
+
# === Parameters
|
82
|
+
# m(Symbol):: Method that should be multiplexed
|
83
|
+
# args(Array):: Arguments
|
84
|
+
#
|
85
|
+
# === Return
|
86
|
+
# res(Object):: Result of first target in list
|
87
|
+
def method_missing(m, *args)
|
88
|
+
res = @targets.inject([]) { |res, t| res << t.__send__(m, *args) }
|
89
|
+
res[0]
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2012 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'logger'
|
24
|
+
|
25
|
+
module RightSupport::Log
|
26
|
+
# A logger than does not perform any logging. This is useful to send log entries
|
27
|
+
# to "the bit bucket" or "to /dev/null" -- hence the name.
|
28
|
+
class NullLogger < Logger
|
29
|
+
# Initialize a new instance of this class.
|
30
|
+
#
|
31
|
+
def initialize
|
32
|
+
super(nil)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Do nothing. This method exists for interface compatibility with Logger.
|
36
|
+
#
|
37
|
+
# === Parameters
|
38
|
+
# severity(Integer):: one of the Logger severity constants
|
39
|
+
# message(String):: the message to log, or nil
|
40
|
+
# progname(String):: the program name, or nil
|
41
|
+
#
|
42
|
+
# === Block
|
43
|
+
# If message == nil and a block is given, yields to the block. The block's
|
44
|
+
# output value is ignored.
|
45
|
+
#
|
46
|
+
# === Return
|
47
|
+
# always returns true
|
48
|
+
def add(severity, message = nil, progname = nil, &block)
|
49
|
+
#act like a real Logger w/r/t the block
|
50
|
+
yield if message.nil? && block_given?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
# Do nothing. This method exists for interface compatibility with Logger.
|
55
|
+
#
|
56
|
+
# === Parameters
|
57
|
+
# msg(String):: the message to log, or nil
|
58
|
+
#
|
59
|
+
# === Block
|
60
|
+
# If message == nil and a block is given, yields to the block. The block's
|
61
|
+
# output value is ignored.
|
62
|
+
#
|
63
|
+
# === Return
|
64
|
+
def <<(msg)
|
65
|
+
msg.to_s.size
|
66
|
+
end
|
67
|
+
|
68
|
+
# Do nothing. This method exists for interface compatibility with Logger.
|
69
|
+
#
|
70
|
+
# === Return
|
71
|
+
# always returns true
|
72
|
+
def close
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|