right_support 2.8.46 → 2.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|