right_support 0.9.4 → 0.9.8

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,125 @@
1
+ # Copyright (c) 2009-2011 RightScale, Inc, All Rights Reserved Worldwide.
2
+ #
3
+ # THIS PROGRAM IS CONFIDENTIAL AND PROPRIETARY TO RIGHTSCALE
4
+ # AND CONSTITUTES A VALUABLE TRADE SECRET. Any unauthorized use,
5
+ # reproduction, modification, or disclosure of this program is
6
+ # strictly prohibited. Any use of this program by an authorized
7
+ # licensee is strictly subject to the terms and conditions,
8
+ # including confidentiality obligations, set forth in the applicable
9
+ # License Agreement between RightScale.com, Inc. and the licensee.
10
+
11
+ require 'socket'
12
+
13
+ module RightSupport::Net
14
+ # A helper module that provides some useful methods for querying the local machine about its network
15
+ # addresses.
16
+ #
17
+ # This module is automatically included into the eigenclass of RightSupport::Net for convenience. Any
18
+ # of the methods available in this module can be called as RightSupport::Net.foo without needing to
19
+ # include this module.
20
+ module AddressHelper
21
+ class NoSuitableInterface < RuntimeError; end
22
+
23
+ PRIVATE_IP_REGEX = /^(10\.|192\.168\.|172\.(1[6789]|2[0-9]|3[01]))/
24
+ LOOPBACK_IP_REGEX = /^(127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})/
25
+
26
+ # Determine the network address of some local interface that has a route to the public Internet.
27
+ #
28
+ # On some systems, Socket.getaddrinfo(Socket.gethostname, ...) does not return any IP addresses,
29
+ # for instance because the local hostname cannot be resolved by DNS. This method can be used to
30
+ # detect "my IP address" in such cases.
31
+ #
32
+ # This code does NOT make a connection or send any packets (to 64.233.187.99 which is google).
33
+ # Since UDP is a stateless protocol, connect() merely makes a system call which figures out how
34
+ # to route the packets based on the address and what interface (and therefore IP address) it
35
+ # should bind to. addr() returns an array containing the family (AF_INET), local port, and
36
+ # local address (which is what we want) of the socket.
37
+ #
38
+ # === Parameters
39
+ # address_family(Integer):: Socket::AF_INET or Socket::AF_INET6
40
+ #
41
+ # === Return
42
+ # address(String):: a single IP address in dotted-quad notation
43
+ def local_routable_address(address_family)
44
+ case address_family
45
+ when Socket::AF_INET
46
+ remote_address = '64.233.187.99'
47
+ when Socket::AF_INET6
48
+ remote_address = '2607:f8b0:4003:c00::68'
49
+ else
50
+ raise ArgumentError, "Routable address discovery only works for AF_INET or AF_INET6"
51
+ end
52
+
53
+ # turn off reverse DNS resolution temporarily
54
+ orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
55
+ UDPSocket.open(address_family) do |s|
56
+ s.connect remote_address, 1
57
+ s.addr.last
58
+ end
59
+ ensure
60
+ Socket.do_not_reverse_lookup = orig
61
+ end
62
+
63
+ # Determine all network addresses of the local machine that are resolvable using either the machine's
64
+ # hostname or "localhost". Typically this allows us to discover the local IP addresses of
65
+ # "interesting" network interfaces without relying on OS-specific tools such as ifconfig/ipconfig.
66
+ #
67
+ # === Parameters
68
+ # address_family(Integer):: Socket::AF_INET or Socket::AF_INET6
69
+ #
70
+ # === Return
71
+ # addresses(Array):: a list of IP addresses in dotted-quad notation
72
+ def local_hostname_addresses(address_family)
73
+ loopback = Socket.getaddrinfo('localhost', 1,
74
+ address_family, Socket::SOCK_STREAM,
75
+ nil, nil).collect { |x| x[3] }
76
+
77
+ real = Socket.getaddrinfo(Socket.gethostname, 1,
78
+ address_family, Socket::SOCK_STREAM,
79
+ nil, nil).collect { |x| x[3] }
80
+ (loopback + real).uniq
81
+ end
82
+
83
+ # Determine all IPv4 addresses of the local machine that fall into the given range of IP address space
84
+ # (public, private or loopback).
85
+ #
86
+ # === Parameters
87
+ # flavor(Symbol):: One of :public, :private or :loopback
88
+ #
89
+ # === Return
90
+ # addresses(Array):: a list of IP addresses in dotted-quad notation
91
+ def my_ipv4_addresses(flavor=:private)
92
+ all = local_hostname_addresses(Socket::AF_INET)
93
+ all << local_routable_address(Socket::AF_INET)
94
+ all.uniq!
95
+
96
+ case flavor
97
+ when :public
98
+ return all.select { |ip| ip !~ PRIVATE_IP_REGEX && ip !~ LOOPBACK_IP_REGEX }
99
+ when :private
100
+ return all.select { |ip| ip =~ PRIVATE_IP_REGEX }
101
+ when :loopback
102
+ return all.select { |ip| ip =~ LOOPBACK_IP_REGEX }
103
+ else
104
+ raise ArgumentError, "flavor must be :public, :private or :loopback"
105
+ end
106
+ end
107
+
108
+ # Determine an IPv4 address of the local machine that falls into the given range of IP address space
109
+ # (public, private or loopback). If multiple suitable addresses are found, the same address will be
110
+ # consistently returned but there is no way to influence _which_ address that will be.
111
+ #
112
+ # === Parameters
113
+ # flavor(Symbol):: One of :public, :private or :loopback
114
+ #
115
+ # === Return
116
+ # addresses(Array):: a list of IP addresses in dotted-quad notation
117
+ def my_ipv4_address(flavor=:private)
118
+ candidates = my_ipv4_addresses(flavor)
119
+ raise NoSuitableInterface, "No interface had a #{flavor} IPv4 address" if candidates.empty?
120
+
121
+ #Ensure we consistently the same interface by doing a lexical sort
122
+ return candidates.sort.first
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,14 @@
1
+ class RightSupport::Net::RequestBalancer::Policy
2
+ def next_endpoint
3
+ raise NotImplementedError, "Subclass responsibility"
4
+ end
5
+
6
+ def report_success(endpoint)
7
+ #no-op
8
+ end
9
+
10
+ def report_failure(endpoint)
11
+ #no-op
12
+ end
13
+ end
14
+
@@ -0,0 +1,7 @@
1
+ class RightSupport::Net::RequestBalancer::RoundRobin < Policy
2
+ def next_endpoint(endpoints)
3
+ result = @endpoints[ @counter % @endpoints.size ]
4
+ @counter += 1
5
+ return result
6
+ end
7
+ end
@@ -91,12 +91,16 @@ module RightSupport::Net
91
91
 
92
92
  exceptions = []
93
93
  result = nil
94
- success = false
94
+ complete = false
95
+ n = 0
96
+
97
+ while !complete && n < @endpoints.size
98
+ endpoint = next_endpoint
99
+ n += 1
95
100
 
96
- @endpoints.each do |endpoint|
97
101
  begin
98
- result = yield(endpoint)
99
- success = true
102
+ result = yield(endpoint)
103
+ complete = true
100
104
  break
101
105
  rescue Exception => e
102
106
  if to_raise = handle_exception(endpoint, e)
@@ -107,7 +111,7 @@ module RightSupport::Net
107
111
  end
108
112
  end
109
113
 
110
- return result if success
114
+ return result if complete
111
115
 
112
116
  exceptions = exceptions.map { |e| e.class.name }.uniq.join(', ')
113
117
  raise NoResult, "All URLs in the rotation failed! Exceptions: #{exceptions}"
@@ -142,6 +146,13 @@ module RightSupport::Net
142
146
  end
143
147
  end
144
148
 
149
+ def next_endpoint
150
+ @round_robin ||= 0
151
+ result = @endpoints[ @round_robin % @endpoints.size ]
152
+ @round_robin += 1
153
+ return result
154
+ end
155
+
145
156
  # Test that something is a callable (Proc, Lambda or similar) with the expected arity.
146
157
  # Used mainly by the initializer to test for correct options.
147
158
  def test_callable_arity(callable, arity, optional)
@@ -32,3 +32,5 @@ end
32
32
  Dir[File.expand_path('../net/*.rb', __FILE__)].each do |filename|
33
33
  require filename
34
34
  end
35
+
36
+ RightSupport::Net.extend(RightSupport::Net::AddressHelper)
@@ -22,41 +22,37 @@
22
22
 
23
23
  require 'logger'
24
24
 
25
- module RightSupport
26
- module Rack
27
- # A Rack middleware that allows an arbitrary object to be used as the Rack logger.
28
- # This is more flexible than Rack's built-in Logger middleware, which always logs
29
- # to a file-based Logger and doesn't allow you to control anything other than the
30
- # filename.
31
- class CustomLogger
32
- # Initialize an instance of the middleware.
33
- #
34
- # === Parameters
35
- # app(Object):: the inner application or middleware layer; must respond to #call
36
- # level(Integer):: one of the Logger constants: DEBUG, INFO, WARN, ERROR, FATAL
37
- # logger(Logger):: (optional) the Logger object to use, if other than default
38
- #
39
- def initialize(app, level = ::Logger::INFO, logger = nil)
40
- @app, @level = app, level
25
+ module RightSupport::Rack
26
+ # A Rack middleware that allows an arbitrary object to be used as the Rack logger.
27
+ # This is more flexible than Rack's built-in Logger middleware, which always logs
28
+ # to a file-based Logger and doesn't allow you to control anything other than the
29
+ # filename.
30
+ class CustomLogger
31
+ # Initialize an instance of the middleware.
32
+ #
33
+ # === Parameters
34
+ # app(Object):: the inner application or middleware layer; must respond to #call
35
+ # level(Integer):: one of the Logger constants: DEBUG, INFO, WARN, ERROR, FATAL
36
+ # logger(Logger):: (optional) the Logger object to use, if other than default
37
+ #
38
+ def initialize(app, level = ::Logger::INFO, logger = nil)
39
+ @app, @level = app, level
41
40
 
42
- logger ||= ::Logger.new(env['rack.errors'])
43
- logger.level = @level
44
- @logger = logger
45
- end
41
+ logger ||= ::Logger.new(env['rack.errors'])
42
+ logger.level = @level
43
+ @logger = logger
44
+ end
46
45
 
47
- # Add a logger to the Rack environment and call the next middleware.
48
- #
49
- # === Parameters
50
- # env(Hash):: the Rack environment
51
- #
52
- # === Return
53
- # always returns whatever value is returned by the next layer of middleware
54
- def call(env)
55
- env['rack.logger'] = @logger
56
- return @app.call(env)
57
- ensure
58
- @logger.close
59
- end
46
+ # Add a logger to the Rack environment and call the next middleware.
47
+ #
48
+ # === Parameters
49
+ # env(Hash):: the Rack environment
50
+ #
51
+ # === Return
52
+ # always returns whatever value is returned by the next layer of middleware
53
+ def call(env)
54
+ env['rack.logger'] = @logger
55
+ return @app.call(env)
60
56
  end
61
57
  end
62
58
  end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Copyright (c) 2011 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
24
+ #
25
+ # A namespace for Rack middleware and other enhancements.
26
+ #
27
+ module Rack
28
+
29
+ end
30
+ end
31
+
32
+ Dir[File.expand_path('../rack/*.rb', __FILE__)].each do |filename|
33
+ require filename
34
+ end
@@ -1,5 +1,5 @@
1
- module RightSupport
2
- module KernelExtensions
1
+ module RightSupport::Ruby
2
+ module ObjectExtensions
3
3
  # Attempt to require one or more source files; if the require succeeds (or
4
4
  # if the files have already been successfully required), yield to the block.
5
5
  #
@@ -26,5 +26,5 @@ module RightSupport
26
26
  end
27
27
 
28
28
  class Object
29
- include RightSupport::KernelExtensions
29
+ include RightSupport::Ruby::ObjectExtensions
30
30
  end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Copyright (c) 2011 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
24
+ #
25
+ # A namespace for extensions to Ruby builtin classes.
26
+ #
27
+ module Ruby
28
+
29
+ end
30
+ end
31
+
32
+ Dir[File.expand_path('../ruby/*.rb', __FILE__)].each do |filename|
33
+ require filename
34
+ end
@@ -1,176 +1,3 @@
1
- #
2
- # Copyright (c) 2011 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
1
  module RightSupport
26
- if_require_succeeds('syslog') do
27
- # A logger that forwards log entries to the Unix syslog facility, but complies
28
- # with the interface of the Ruby Logger object and faithfully translates log
29
- # severities and other concepts. Provides optional cleanup/filtering in order
30
- # to keep the syslog from having weird characters or being susceptible to log
31
- # forgery.
32
- class SystemLogger < Logger
33
- LOGGER_LEVELS = {
34
- UNKNOWN => :alert,
35
- FATAL => :err,
36
- ERROR => :warning,
37
- WARN => :notice,
38
- INFO => :info,
39
- DEBUG => :debug
40
- }
41
-
42
- SYSLOG_LEVELS = LOGGER_LEVELS.invert
43
- DEFAULT_SYSLOG_LEVEL = :alert
44
-
45
- DEFAULT_OPTIONS = {:split=>false, :color=>false}
46
-
47
- @@syslog = nil
48
-
49
- # Initialize this process's syslog facilities and construct a new syslog
50
- # logger object.
51
- #
52
- # === Parameters
53
- # program_name(String):: the syslog program name, 'ruby' by default
54
- # options(Hash):: (optional) configuration options to use, see below
55
- #
56
- # === Options
57
- # facility:: the syslog facility to use for messages, 'local0' by default
58
- # split(true|false):: if true, splits multi-line messages into separate syslog entries
59
- # color(true|false):: if true, passes ANSI escape sequences through to syslog
60
- #
61
- def initialize(program_name='ruby', options={})
62
- @options = DEFAULT_OPTIONS.merge(options)
63
- @level = Logger::DEBUG
64
-
65
- facility = options[:facility] || 'local0'
66
- fac_map = {'user'=>8}
67
- (0..7).each { |i| fac_map['local'+i.to_s] = 128+8*i }
68
-
69
- @@syslog ||= Syslog.open(program_name, nil, fac_map[facility.to_s])
70
- end
71
-
72
- # Log a message if the given severity is high enough. This is the generic
73
- # logging method. Users will be more inclined to use #debug, #info, #warn,
74
- # #error, and #fatal.
75
- #
76
- # === Parameters
77
- # severity(Integer):: one of the severity constants defined by Logger
78
- # message(Object):: the message to be logged
79
- # progname(String):: ignored, the program name is fixed at initialization
80
- #
81
- # === Block
82
- # If message is nil and a block is supplied, this method will yield to
83
- # obtain the log message.
84
- #
85
- # === Return
86
- # true:: always returns true
87
- #
88
- def add(severity, message = nil, progname = nil, &block)
89
- severity ||= UNKNOWN
90
- if @@syslog.nil? or severity < @level
91
- return true
92
- end
93
-
94
- progname ||= @progname
95
-
96
- if message.nil?
97
- if block_given?
98
- message = yield
99
- else
100
- message = progname
101
- progname = @progname
102
- end
103
- end
104
-
105
- parts = clean(message)
106
- parts.each { |part| emit_syslog(severity, part) }
107
- return true
108
- end
109
-
110
- # Emit a log entry at INFO severity.
111
- #
112
- # === Parameters
113
- # msg(Object):: the message to log
114
- #
115
- # === Return
116
- # true:: always returns true
117
- #
118
- def <<(msg)
119
- info(msg)
120
- end
121
-
122
- # Do nothing. This method is provided for Logger interface compatibility.
123
- #
124
- # === Return
125
- # true:: always returns true
126
- #
127
- def close
128
- return true
129
- end
130
-
131
- private
132
-
133
- # Call the syslog function to emit a syslog entry.
134
- #
135
- # === Parameters
136
- # severity(Integer):: one of the Logger severity constants
137
- # message(String):: the log message
138
- #
139
- # === Return
140
- # true:: always returns true
141
- def emit_syslog(severity, message)
142
- level = SYSLOG_LEVELS[severity] || DEFAULT_SYSLOG_LEVEL
143
- @@syslog.send(level, message)
144
- return true
145
- end
146
-
147
- # Perform cleanup, output escaping and splitting on message.
148
- # The operations that it performs can vary, depending on the
149
- # options that were passed to this logger at initialization
150
- # time.
151
- #
152
- # === Parameters
153
- # message(String):: raw log message
154
- #
155
- # === Return
156
- # log_lines([String]):: an array of String messages that should be logged separately to syslog
157
- def clean(message)
158
- message = message.to_s.dup
159
- message.strip!
160
- message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf)
161
-
162
- unless @options[:color]
163
- message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes
164
- end
165
-
166
- if @options[:split]
167
- bits = message.split(/[\n\r]+/)
168
- else
169
- bits = [message]
170
- end
171
-
172
- return bits
173
- end
174
- end
175
- end
176
- end
2
+ SystemLogger = RightSupport::Log::SystemLogger
3
+ end
@@ -1,72 +1,3 @@
1
- #
2
- # Copyright (c) 2011 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
1
  module RightSupport
26
- # A logger that prepends a tag to every message that is emitted. Can be used to
27
- # correlate logs with a Web session ID, transaction ID or other context.
28
- #
29
- # The user of this logger is responsible for calling #tag= to set the tag as
30
- # appropriate, e.g. in a Web request around-filter.
31
- #
32
- # This logger uses thread-local storage (TLS) to provide tagging on a per-thread
33
- # basis; however, it does not account for EventMachine, neverblock, the use of
34
- # Ruby fibers, or any other phenomenon that can "hijack" a thread's call stack.
35
- #
36
- class TagLogger < FilterLogger
37
- # Prepend the current tag to the log message; return the same severity and
38
- # the modified message.
39
- #
40
- # === Parameters
41
- # severity(Integer):: one of the severity constants defined by Logger
42
- # messgae(String):: the log message
43
- #
44
- # === Return
45
- # Returns a pair consisting of the filtered [severity, message].
46
- #
47
- def filter(severity, message)
48
- @tls_id ||= "tag_logger_#{self.object_id}"
49
- tag = Thread.current[@tls_id] || ''
50
- if tag
51
- return [severity, tag + message]
52
- else
53
- return [severity, message]
54
- end
55
- end
56
-
57
- attr_reader :tag
58
-
59
- # Set the tag for this logger.
60
- #
61
- # === Parameters
62
- # tag(String|nil):: the new tag, or nil to remove the tag
63
- #
64
- # === Return
65
- # String:: returns the new tag
66
- def tag=(tag)
67
- @tag = tag
68
- @tls_id ||= "tag_logger_#{self.object_id}"
69
- Thread.current[@tls_id] = @tag
70
- end
71
- end
2
+ TagLogger = RightSupport::Log::TagLogger
72
3
  end
data/lib/right_support.rb CHANGED
@@ -1,9 +1,13 @@
1
- require 'right_support/kernel_extensions'
1
+ # Namespaces for RightSupport
2
+ require 'right_support/ruby'
3
+ require 'right_support/db'
4
+ require 'right_support/log'
5
+ require 'right_support/net'
6
+ require 'right_support/rack'
7
+ require 'right_support/validation'
8
+
9
+ # Deprecated stubs
10
+ require 'right_support/cassandra_model'
2
11
  require 'right_support/filter_logger'
3
12
  require 'right_support/system_logger'
4
13
  require 'right_support/tag_logger'
5
- require 'right_support/rack/custom_logger'
6
-
7
- require 'right_support/validation'
8
-
9
- require 'right_support/net'
@@ -7,8 +7,8 @@ spec = Gem::Specification.new do |s|
7
7
  s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
8
8
 
9
9
  s.name = 'right_support'
10
- s.version = '0.9.4'
11
- s.date = '2011-05-13'
10
+ s.version = '0.9.8'
11
+ s.date = '2011-08-13'
12
12
 
13
13
  s.authors = ['Tony Spataro']
14
14
  s.email = 'tony@rightscale.com'