right_support 2.8.46 → 2.9.1
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.
- checksums.yaml +5 -13
- data/.travis.yml +5 -0
- data/VERSION +1 -1
- data/features/balancer_health_check.feature +1 -1
- data/lib/right_support/log/syslog/remote.rb +217 -0
- data/lib/right_support/log/system_logger.rb +50 -4
- data/right_support.gemspec +5 -4
- data/spec/log/system_logger_spec.rb +106 -53
- metadata +20 -19
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
Njc1MTJlMzVjOTBmZmRkNTQxNTVlYWFiMmUyNDE3Nzc0ZWZkMDVmNg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c00cbfd4e07ebbe5552f5ad98a567c61b66cc3f8
|
4
|
+
data.tar.gz: 10a8a64f785328beee4becbc12a9ccce43c42807
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZjlhNzA4ODg4ZGZlYjc0YTQ1NjA0ZjlkNDhhZTU0NGExNGNmZGViMzBjMTlj
|
11
|
-
MDkxMTEyZTUzYmUzZDRlNjE2NjU1YjcyMjcxYzVjYmI4ZjIxYjA=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZDY0MDM0NjkwYzJmNjA5NDY1ZTA1NDgzNTZjZGEyZDRlYTNhZWQ0YTg1N2Fi
|
14
|
-
YWQ4ZDIwMzZiMzdlN2RlOTNlYTk4ZmYzZjJjNjY1NzZhNjZiNmRkZmQ1YjIw
|
15
|
-
ZmQzMDIwMGE5YmRiM2I0ZDU2OTY3ZWU1NGQxYjJmOTJkNjRjYjk=
|
6
|
+
metadata.gz: fbf3db59b98e9b18274aceec2790a9513953e25128f33b264b7ab95966a16772d6529291913dbeeeb2a79964246b7e665fecc8702186531cf8b1ed787b5ce063
|
7
|
+
data.tar.gz: 3c56b3ffcba5b0425be7772a15c2680f2918d2a102dfd99b1d3259c5d4fe53ad847648eb2a7aaae245e5f6c741e6cd03b17b3c7ca38f38c556e9899f92ac4aef
|
data/.travis.yml
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.9.1
|
@@ -30,4 +30,4 @@ Scenario: mixed servers (condition commented by Tony https://rightscale.acunote.
|
|
30
30
|
And 1 server that responds with 200
|
31
31
|
And HealthCheck balancing policy
|
32
32
|
When a client makes a load-balanced request to '/' with timeout 1 and open_timeout 2
|
33
|
-
Then the request should complete in less than
|
33
|
+
Then the request should complete in less than 4 seconds
|
@@ -0,0 +1,217 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 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 'socket'
|
24
|
+
require 'uri'
|
25
|
+
|
26
|
+
module RightSupport
|
27
|
+
module Log
|
28
|
+
module Syslog
|
29
|
+
# declare module once
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module RightSupport::Log::Syslog
|
35
|
+
|
36
|
+
# partially implements the Syslog interface for a remote syslog connection.
|
37
|
+
# the Syslog.open method is restricted to only using the '/dev/log' socket
|
38
|
+
# (or darwin equivalent).
|
39
|
+
class Remote
|
40
|
+
|
41
|
+
# errors
|
42
|
+
class RemoteSyslogError < StandardError; end
|
43
|
+
|
44
|
+
# documented severity constants.
|
45
|
+
module Severity
|
46
|
+
EMERG = 0
|
47
|
+
ALERT = 1
|
48
|
+
CRIT = 2
|
49
|
+
ERR = 3
|
50
|
+
WARNING = 4
|
51
|
+
NOTICE = 5
|
52
|
+
INFO = 6
|
53
|
+
DEBUG = 7
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(uri, program_name, facility, options = {})
|
57
|
+
@uri = ::URI.parse(uri.to_s)
|
58
|
+
@program_name = program_name
|
59
|
+
@facility = facility
|
60
|
+
@identity = "#{program_name}[#{$$}]"
|
61
|
+
@hostname = ::Socket.gethostname.split('.').first
|
62
|
+
@mutex = ::Mutex.new
|
63
|
+
@socket = nil
|
64
|
+
@error_handler = options[:error_handler]
|
65
|
+
@error_mode = false
|
66
|
+
end
|
67
|
+
|
68
|
+
def connect
|
69
|
+
close if @socket
|
70
|
+
opener = nil
|
71
|
+
case @uri.scheme
|
72
|
+
when 'tcp'
|
73
|
+
opener = lambda do
|
74
|
+
::TCPSocket.new(@uri.host, @uri.port)
|
75
|
+
end
|
76
|
+
when 'udp'
|
77
|
+
opener = lambda do
|
78
|
+
s = ::UDPSocket.new
|
79
|
+
s.connect(@uri.host, @uri.port)
|
80
|
+
s
|
81
|
+
end
|
82
|
+
else
|
83
|
+
raise RemoteSyslogError, "Unxpected URI scheme: #{@uri.scheme}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# backoff/retry connection. each log call will attempt to reconnect on
|
87
|
+
# write failure but only the first will backoff/retry the connection.
|
88
|
+
# the issue is to try and keep the service running and logging while
|
89
|
+
# syslog is being restarted for routine maintainance. if syslog is offline
|
90
|
+
# indefinitely then the app must continue without slowing. the caller can
|
91
|
+
# provide an error_handler to perform graceful shutdown, etc.
|
92
|
+
sleeper = 1
|
93
|
+
attempts = 0
|
94
|
+
begin
|
95
|
+
@socket = opener.call
|
96
|
+
rescue => e
|
97
|
+
# do not repeat backoff/retry when already in error mode.
|
98
|
+
raise if @error_mode
|
99
|
+
attempts += 1
|
100
|
+
if attempts <= 6 # about one minute
|
101
|
+
STDERR.puts("Sleeping #{sleeper}s due to failure to (re)connect to syslog: #{e.message}\n")
|
102
|
+
sleep(sleeper)
|
103
|
+
sleeper *= 2
|
104
|
+
retry
|
105
|
+
else
|
106
|
+
raise
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def close
|
112
|
+
if @socket && !@socket.closed?
|
113
|
+
@socket.close
|
114
|
+
end
|
115
|
+
rescue => e
|
116
|
+
STDERR.puts("Failed to close syslog socket: #{e.message}")
|
117
|
+
ensure
|
118
|
+
@socket = nil
|
119
|
+
end
|
120
|
+
|
121
|
+
def emerg(message)
|
122
|
+
log(@facility, Severity::EMERG, message)
|
123
|
+
end
|
124
|
+
|
125
|
+
def alert(message)
|
126
|
+
log(@facility, Severity::ALERT, message)
|
127
|
+
end
|
128
|
+
|
129
|
+
def crit(message)
|
130
|
+
log(@facility, Severity::CRIT, message)
|
131
|
+
end
|
132
|
+
|
133
|
+
def err(message)
|
134
|
+
log(@facility, Severity::ERR, message)
|
135
|
+
end
|
136
|
+
|
137
|
+
def warning(message)
|
138
|
+
log(@facility, Severity::WARNING, message)
|
139
|
+
end
|
140
|
+
|
141
|
+
def notice(message)
|
142
|
+
log(@facility, Severity::NOTICE, message)
|
143
|
+
end
|
144
|
+
|
145
|
+
def info(message)
|
146
|
+
log(@facility, Severity::INFO, message)
|
147
|
+
end
|
148
|
+
|
149
|
+
def debug(message)
|
150
|
+
log(@facility, Severity::DEBUG, message)
|
151
|
+
end
|
152
|
+
|
153
|
+
def log(facility, severity, message)
|
154
|
+
protocol_message = "<#{(facility & 0xf8) | (severity & 0x07)}> "\
|
155
|
+
"#{::Time.now.strftime('%b %d %H:%M:%S')} " \
|
156
|
+
"#{@hostname} " \
|
157
|
+
"#{@identity}" \
|
158
|
+
": " \
|
159
|
+
"#{message.gsub("\n", '#012')}\n"
|
160
|
+
@mutex.synchronize do
|
161
|
+
last_error = nil
|
162
|
+
begin
|
163
|
+
@socket.write(protocol_message)
|
164
|
+
rescue => e
|
165
|
+
if reconnect
|
166
|
+
begin
|
167
|
+
@socket.write(protocol_message)
|
168
|
+
rescue => e
|
169
|
+
last_error = e
|
170
|
+
end
|
171
|
+
else
|
172
|
+
last_error = e
|
173
|
+
end
|
174
|
+
end
|
175
|
+
if last_error
|
176
|
+
# we are only here if reconnection attempts have timed out at least
|
177
|
+
# once. the timeout is skipped when we are already in error mode.
|
178
|
+
if @error_mode
|
179
|
+
# no need to repeat the warning or invoke callback for each
|
180
|
+
# failure to write.
|
181
|
+
::STDERR.puts(protocol_message)
|
182
|
+
else
|
183
|
+
@error_mode = true
|
184
|
+
msg = <<EOF
|
185
|
+
WARNING: Failed writing to syslog: #{last_error.message}
|
186
|
+
Dumping raw messages to stderr until rsyslog connection is restored.
|
187
|
+
EOF
|
188
|
+
::STDERR.puts(msg)
|
189
|
+
::STDERR.puts(protocol_message)
|
190
|
+
|
191
|
+
# the caller may want to gracefully shutdown, etc. graceful shutdown
|
192
|
+
# will trigger alerts whereas silently ignoring failure to write to
|
193
|
+
# syslog can lead to other problems.
|
194
|
+
@error_handler.call(last_error) if @error_handler
|
195
|
+
end
|
196
|
+
else
|
197
|
+
@error_mode = false
|
198
|
+
end
|
199
|
+
end
|
200
|
+
true
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
|
205
|
+
def reconnect
|
206
|
+
connect
|
207
|
+
true
|
208
|
+
rescue => e
|
209
|
+
# no need to repeat warnings when already in error mode.
|
210
|
+
unless @error_mode
|
211
|
+
::STDERR.puts("WARNING: Failed to reconnect to syslog: #{e.message}")
|
212
|
+
end
|
213
|
+
false
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
@@ -69,7 +69,8 @@ module RightSupport::Log
|
|
69
69
|
DEFAULT_OPTIONS = {
|
70
70
|
:split=>false,
|
71
71
|
:color=>false,
|
72
|
-
:facility=>'local0'
|
72
|
+
:facility=>'local0',
|
73
|
+
:connection=>:autodetect
|
73
74
|
}
|
74
75
|
|
75
76
|
@@syslog = nil
|
@@ -87,6 +88,14 @@ module RightSupport::Log
|
|
87
88
|
# facility:: the syslog facility to use for messages, 'local0' by default
|
88
89
|
# split(true|false):: if true, splits multi-line messages into separate syslog entries
|
89
90
|
# color(true|false):: if true, passes ANSI escape sequences through to syslog
|
91
|
+
# connection(type):: if :local, connects using local Unix socket. if :autodetect,
|
92
|
+
# it may choose a remote connection if the 'syslog' host is known. otherwise
|
93
|
+
# a URI such as 'tcp://127.0.0.1:514' can be passed explicitly.
|
94
|
+
# error_handler(callback):: callback for write failures in order to give
|
95
|
+
# the application a change to gracefully shutdown, etc.
|
96
|
+
# default is to dump errors to STDERR and continue.
|
97
|
+
# parameters = [exception]
|
98
|
+
# currently only called by remote syslog
|
90
99
|
#
|
91
100
|
# === Raise
|
92
101
|
# ArgumentError:: if an invalid facility is given
|
@@ -104,10 +113,47 @@ module RightSupport::Log
|
|
104
113
|
@@syslog.close ; @@syslog = nil
|
105
114
|
end
|
106
115
|
|
107
|
-
@@syslog
|
108
|
-
|
116
|
+
unless @@syslog
|
117
|
+
if @options[:connection] == :autodetect
|
118
|
+
# don't even want to know if this code is supported on older Ruby.
|
119
|
+
# this logic is intended to help dockerization, which for us
|
120
|
+
# begins at Ruby v2.1+
|
121
|
+
@options[:connection] = :local # local if all attempts fail
|
122
|
+
if RUBY_VERSION >= '2.1'
|
123
|
+
# only choose the 'syslog' host when explicitly declared in
|
124
|
+
# '/etc/hosts'. use built-in Resolv module to check.
|
125
|
+
begin
|
126
|
+
require 'resolv'
|
127
|
+
host = ::Resolv::Hosts.new.getaddress('syslog')
|
128
|
+
begin
|
129
|
+
::TCPSocket.new(host, 514).close
|
130
|
+
@options[:connection] = 'tcp://syslog:514'
|
131
|
+
rescue ::Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
132
|
+
# not listening on TCP port 514
|
133
|
+
end
|
134
|
+
rescue ::Resolv::ResolvError
|
135
|
+
# not set
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
109
139
|
|
110
|
-
|
140
|
+
case @options[:connection]
|
141
|
+
when :local
|
142
|
+
@@syslog = ::Syslog.open(program_name, nil, facility)
|
143
|
+
else
|
144
|
+
require ::File.expand_path('../syslog/remote', __FILE__)
|
145
|
+
syslogger = ::RightSupport::Log::Syslog::Remote.new(
|
146
|
+
@options[:connection],
|
147
|
+
program_name,
|
148
|
+
facility,
|
149
|
+
:error_handler => @options[:error_handler])
|
150
|
+
syslogger.connect
|
151
|
+
@@syslog = syslogger
|
152
|
+
end
|
153
|
+
end
|
154
|
+
@@program_name = program_name
|
155
|
+
end
|
156
|
+
@@syslog.info("Connected to syslog: #{@options[:connection].inspect}")
|
111
157
|
end
|
112
158
|
|
113
159
|
# Log a message if the given severity is high enough. This is the generic
|
data/right_support.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: right_support 2.
|
5
|
+
# stub: right_support 2.9.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "right_support"
|
9
|
-
s.version = "2.
|
9
|
+
s.version = "2.9.1"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Tony Spataro", "Sergey Sergyenko", "Ryan Williamson", "Lee Kirchhoff", "Alexey Karpik", "Scott Messier"]
|
14
|
-
s.date = "2015-
|
14
|
+
s.date = "2015-09-23"
|
15
15
|
s.description = "A toolkit of useful, reusable foundation code created by RightScale."
|
16
16
|
s.email = "support@rightscale.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -70,6 +70,7 @@ Gem::Specification.new do |s|
|
|
70
70
|
"lib/right_support/log/mixin.rb",
|
71
71
|
"lib/right_support/log/multiplexer.rb",
|
72
72
|
"lib/right_support/log/null_logger.rb",
|
73
|
+
"lib/right_support/log/syslog/remote.rb",
|
73
74
|
"lib/right_support/log/system_logger.rb",
|
74
75
|
"lib/right_support/net.rb",
|
75
76
|
"lib/right_support/net/address_helper.rb",
|
@@ -148,7 +149,7 @@ Gem::Specification.new do |s|
|
|
148
149
|
]
|
149
150
|
s.homepage = "https://github.com/rightscale/right_support"
|
150
151
|
s.licenses = ["MIT"]
|
151
|
-
s.rubygems_version = "2.2.
|
152
|
+
s.rubygems_version = "2.2.3"
|
152
153
|
s.summary = "Reusable foundation code."
|
153
154
|
|
154
155
|
if s.respond_to? :specification_version then
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'socket'
|
2
3
|
|
3
4
|
# NOTE: this spec does not get defined or executed unless SystemLogger
|
4
5
|
# is defined, which only happens if Ruby standard-library 'syslog' module is
|
@@ -13,80 +14,132 @@ describe 'RightSupport::Log::SystemLogger' do
|
|
13
14
|
SEVERITY_MAP = RightSupport::Log::SystemLogger::SEVERITY_MAP
|
14
15
|
FACILITY_MAP = RightSupport::Log::SystemLogger::FACILITY_MAP
|
15
16
|
|
16
|
-
before(:each) do
|
17
|
-
@mock_syslog = flexmock(Syslog)
|
18
|
-
#indicates we sent a bogus severity to syslog!
|
19
|
-
@mock_syslog.should_receive(SEVERITY_MAP[Logger::UNKNOWN]).never
|
20
|
-
flexmock(Syslog).should_receive(:open).and_return(@mock_syslog).by_default
|
21
|
-
end
|
22
|
-
|
23
17
|
after(:each) do
|
24
18
|
subject.instance_eval { class_variable_set(:@@syslog, nil) }
|
25
19
|
end
|
26
20
|
|
27
|
-
context :
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
context :local do
|
22
|
+
before(:each) do
|
23
|
+
@mock_syslog = flexmock(Syslog)
|
24
|
+
#indicates we sent a bogus severity to syslog!
|
25
|
+
@mock_syslog.should_receive(SEVERITY_MAP[Logger::UNKNOWN]).never
|
26
|
+
flexmock(Syslog).should_receive(:open).and_return(@mock_syslog).by_default
|
27
|
+
@mock_syslog.should_receive(:info).with('Connected to syslog: :local').once
|
28
|
+
end
|
29
|
+
|
30
|
+
context :initialize do
|
31
|
+
context 'with :facility option' do
|
32
|
+
FACILITY_MAP.each_pair do |name, const|
|
33
|
+
it "should handle #{name}" do
|
34
|
+
@mock_syslog.should_receive(:open).with('unit tests', nil, const).and_return(@mock_syslog)
|
35
|
+
subject.new('unit tests', :facility=>name, :connection=>:local)
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
36
|
-
end
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
41
|
+
context :add do
|
42
|
+
context 'severity levels' do
|
43
|
+
levels = { :debug=>:debug,
|
44
|
+
:info=>:info, :warn=>:notice,
|
45
|
+
:error=>:warning, :fatal=>:err }
|
46
|
+
|
47
|
+
levels.each_pair do |logger_method, syslog_method|
|
48
|
+
it "translates Logger##{logger_method} to Syslog##{syslog_method}" do
|
49
|
+
@logger = subject.new('spec', :connection=>:local)
|
50
|
+
@mock_syslog.should_receive(syslog_method).with('moo bah oink')
|
51
|
+
@logger.__send__(logger_method, 'moo bah oink')
|
52
|
+
end
|
49
53
|
end
|
50
54
|
end
|
51
|
-
end
|
52
55
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
+
it 'escapes % characters to avoid confusing printf()' do
|
57
|
+
@logger = subject.new('spec', :connection=>:local)
|
58
|
+
@mock_syslog.should_receive(:info).with('All systems 100%% -- %%licious!')
|
56
59
|
|
57
|
-
|
58
|
-
|
60
|
+
@logger.info('All systems 100% -- %licious!')
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
flexmock(@logger).should_receive(:emit_syslog).times(5)
|
63
|
+
context 'given :split option' do
|
64
|
+
it 'when true, splits multi-line messages' do
|
65
|
+
@logger = subject.new('spec', :split=>true, :connection=>:local)
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
+
actual = []
|
68
|
+
@mock_syslog.should_receive(:info).and_return do |message|
|
69
|
+
actual << message
|
70
|
+
true
|
71
|
+
end
|
67
72
|
|
68
|
-
|
69
|
-
|
70
|
-
|
73
|
+
@logger.info("This is a\nmulti line\r\nlog message\n\rwith all kinds\n\n\rof stuff")
|
74
|
+
actual.should == ["This is a", "multi line", "log message", "with all kinds", "of stuff"]
|
75
|
+
end
|
71
76
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
77
|
+
it 'when false, passes through multi-line messages' do
|
78
|
+
@logger = subject.new('spec', :split=>false, :connection=>:local)
|
75
79
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
+
actual = []
|
81
|
+
@mock_syslog.should_receive(:info).and_return do |message|
|
82
|
+
actual << message
|
83
|
+
true
|
84
|
+
end
|
80
85
|
|
81
|
-
|
86
|
+
msg = "This is a\nmulti line\r\nlog message\n\rwith all kinds\n\n\rof stuff"
|
87
|
+
@logger.info(msg)
|
88
|
+
actual.should == [msg]
|
89
|
+
end
|
82
90
|
end
|
83
91
|
|
84
|
-
|
85
|
-
|
86
|
-
|
92
|
+
context 'given :color option' do
|
93
|
+
it 'when true, passes through ANSI color codes' do
|
94
|
+
@logger = subject.new('spec', :color=>true, :connection=>:local)
|
87
95
|
|
88
|
-
|
96
|
+
actual = []
|
97
|
+
@mock_syslog.should_receive(:info).and_return do |message|
|
98
|
+
actual << message
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
msg = "This has \e[16;32mcolor\e[7;0m inside it!"
|
103
|
+
@logger.info(msg)
|
104
|
+
actual.should == [msg]
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'when false, strips out ANSI color codes' do
|
108
|
+
@logger = subject.new('spec', :color=>false, :connection=>:local)
|
109
|
+
|
110
|
+
actual = []
|
111
|
+
@mock_syslog.should_receive(:info).and_return do |message|
|
112
|
+
actual << message
|
113
|
+
true
|
114
|
+
end
|
115
|
+
|
116
|
+
@logger.info("This has \e[16;32mcolor\e[7;0m inside it!")
|
117
|
+
actual.should == ['This has color inside it!']
|
118
|
+
end
|
89
119
|
end
|
90
120
|
end
|
91
121
|
end
|
92
|
-
|
122
|
+
|
123
|
+
context :remote do
|
124
|
+
it 'sends protocol-formatted messages to a syslog service' do
|
125
|
+
server = ::TCPServer.new(2345)
|
126
|
+
data = nil
|
127
|
+
::Thread.start do
|
128
|
+
client = server.accept
|
129
|
+
data = client.readline
|
130
|
+
client.close
|
131
|
+
end
|
132
|
+
logger = subject.new('spec', :connection=>'tcp://localhost:2345')
|
133
|
+
stop_time = ::Time.now + 3
|
134
|
+
while data.nil?
|
135
|
+
sleep(0.1)
|
136
|
+
fail 'Did not receive expected data' if ::Time.now >= stop_time
|
137
|
+
end
|
138
|
+
|
139
|
+
# example: "<134> Sep 23 13:45:42 ubuntu spec[3891]: Connected to syslog: \"tcp://localhost:2345\"\n"
|
140
|
+
regex = /^<134> \w+ \d+ \d+:\d+:\d+ .+ spec\[\d+\]: Connected to syslog: \"tcp:\/\/localhost:2345\"$/
|
141
|
+
data.chomp.should match(regex)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end if defined?(RightSupport::Log::SystemLogger)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Spataro
|
@@ -13,76 +13,76 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2015-
|
16
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: rake
|
20
20
|
requirement: !ruby/object:Gem::Requirement
|
21
21
|
requirements:
|
22
|
-
- - ~>
|
22
|
+
- - "~>"
|
23
23
|
- !ruby/object:Gem::Version
|
24
24
|
version: '10.0'
|
25
25
|
type: :development
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
|
-
- - ~>
|
29
|
+
- - "~>"
|
30
30
|
- !ruby/object:Gem::Version
|
31
31
|
version: '10.0'
|
32
32
|
- !ruby/object:Gem::Dependency
|
33
33
|
name: jeweler
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
36
|
-
- - ~>
|
36
|
+
- - "~>"
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: '2.0'
|
39
39
|
type: :development
|
40
40
|
prerelease: false
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
42
|
requirements:
|
43
|
-
- - ~>
|
43
|
+
- - "~>"
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '2.0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: ruby-debug
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
requirements:
|
50
|
-
- -
|
50
|
+
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '0'
|
53
53
|
type: :development
|
54
54
|
prerelease: false
|
55
55
|
version_requirements: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- -
|
57
|
+
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: '0'
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: pry
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
|
-
- -
|
64
|
+
- - ">="
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: '0'
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
69
|
version_requirements: !ruby/object:Gem::Requirement
|
70
70
|
requirements:
|
71
|
-
- -
|
71
|
+
- - ">="
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: '0'
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
75
|
name: pry-byebug
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
|
-
- -
|
78
|
+
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
type: :development
|
82
82
|
prerelease: false
|
83
83
|
version_requirements: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
|
-
- -
|
85
|
+
- - ">="
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: '0'
|
88
88
|
description: A toolkit of useful, reusable foundation code created by RightScale.
|
@@ -93,10 +93,10 @@ extra_rdoc_files:
|
|
93
93
|
- LICENSE
|
94
94
|
- README.md
|
95
95
|
files:
|
96
|
-
- .coveralls.yml
|
97
|
-
- .rspec
|
98
|
-
- .simplecov
|
99
|
-
- .travis.yml
|
96
|
+
- ".coveralls.yml"
|
97
|
+
- ".rspec"
|
98
|
+
- ".simplecov"
|
99
|
+
- ".travis.yml"
|
100
100
|
- CHANGELOG.rdoc
|
101
101
|
- Gemfile
|
102
102
|
- Gemfile.lock
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- lib/right_support/log/mixin.rb
|
145
145
|
- lib/right_support/log/multiplexer.rb
|
146
146
|
- lib/right_support/log/null_logger.rb
|
147
|
+
- lib/right_support/log/syslog/remote.rb
|
147
148
|
- lib/right_support/log/system_logger.rb
|
148
149
|
- lib/right_support/net.rb
|
149
150
|
- lib/right_support/net/address_helper.rb
|
@@ -229,17 +230,17 @@ require_paths:
|
|
229
230
|
- lib
|
230
231
|
required_ruby_version: !ruby/object:Gem::Requirement
|
231
232
|
requirements:
|
232
|
-
- -
|
233
|
+
- - ">="
|
233
234
|
- !ruby/object:Gem::Version
|
234
235
|
version: '0'
|
235
236
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
236
237
|
requirements:
|
237
|
-
- -
|
238
|
+
- - ">="
|
238
239
|
- !ruby/object:Gem::Version
|
239
240
|
version: '0'
|
240
241
|
requirements: []
|
241
242
|
rubyforge_project:
|
242
|
-
rubygems_version: 2.2.
|
243
|
+
rubygems_version: 2.2.3
|
243
244
|
signing_key:
|
244
245
|
specification_version: 4
|
245
246
|
summary: Reusable foundation code.
|