right_agent 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/right_agent.rb +1 -0
- data/lib/right_agent/actor.rb +0 -28
- data/lib/right_agent/actors/agent_manager.rb +20 -18
- data/lib/right_agent/agent.rb +69 -87
- data/lib/right_agent/agent_tag_manager.rb +1 -1
- data/lib/right_agent/clients/api_client.rb +0 -1
- data/lib/right_agent/clients/auth_client.rb +2 -6
- data/lib/right_agent/clients/balanced_http_client.rb +2 -2
- data/lib/right_agent/clients/base_retry_client.rb +12 -19
- data/lib/right_agent/clients/right_http_client.rb +1 -5
- data/lib/right_agent/clients/router_client.rb +8 -15
- data/lib/right_agent/command/command_parser.rb +3 -3
- data/lib/right_agent/command/command_runner.rb +1 -1
- data/lib/right_agent/connectivity_checker.rb +7 -11
- data/lib/right_agent/dispatcher.rb +7 -42
- data/lib/right_agent/enrollment_result.rb +2 -2
- data/lib/right_agent/error_tracker.rb +202 -0
- data/lib/right_agent/log.rb +0 -2
- data/lib/right_agent/packets.rb +1 -1
- data/lib/right_agent/pending_requests.rb +10 -4
- data/lib/right_agent/pid_file.rb +3 -3
- data/lib/right_agent/protocol_version_mixin.rb +3 -3
- data/lib/right_agent/scripts/agent_deployer.rb +13 -1
- data/lib/right_agent/sender.rb +14 -30
- data/lib/right_agent/serialize/secure_serializer.rb +4 -4
- data/right_agent.gemspec +2 -2
- data/spec/agent_spec.rb +5 -5
- data/spec/clients/auth_client_spec.rb +1 -1
- data/spec/clients/balanced_http_client_spec.rb +4 -2
- data/spec/clients/base_retry_client_spec.rb +5 -6
- data/spec/clients/router_client_spec.rb +1 -4
- data/spec/dispatcher_spec.rb +6 -55
- data/spec/error_tracker_spec.rb +293 -0
- data/spec/pending_requests_spec.rb +2 -2
- data/spec/sender_spec.rb +3 -3
- data/spec/spec_helper.rb +4 -2
- metadata +33 -66
@@ -20,8 +20,8 @@ module RightScale
|
|
20
20
|
# Versions 5 and above use an identical format for the enrollment result
|
21
21
|
SUPPORTED_VERSIONS = 5..AgentConfig.protocol_version
|
22
22
|
|
23
|
-
class IntegrityFailure <
|
24
|
-
class VersionError <
|
23
|
+
class IntegrityFailure < StandardError; end
|
24
|
+
class VersionError < StandardError; end
|
25
25
|
|
26
26
|
attr_reader :r_s_version, :timestamp, :router_cert, :id_cert, :id_key
|
27
27
|
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# Copyright (c) 2014 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
|
10
|
+
# the licensee.
|
11
|
+
|
12
|
+
module RightScale
|
13
|
+
|
14
|
+
# Tracker for unexpected errors
|
15
|
+
# Logs them with appropriate trace information
|
16
|
+
# Accumulates statistics about exceptions
|
17
|
+
# Reports exceptions to external Errbit service via HydraulicBrake
|
18
|
+
class ErrorTracker
|
19
|
+
|
20
|
+
include RightSupport::Ruby::EasySingleton
|
21
|
+
|
22
|
+
# Container for exception statistics
|
23
|
+
attr_reader :exception_stats
|
24
|
+
|
25
|
+
# Initialize error tracker
|
26
|
+
#
|
27
|
+
# @param [Object] agent object using this tracker
|
28
|
+
# @param [String] agent_name uniquely identifying agent process on given server
|
29
|
+
#
|
30
|
+
# @option options [Integer, NilClass] :shard_id identifying shard of database in use
|
31
|
+
# @option options [Hash] :trace_level for restricting backtracing and Errbit reporting
|
32
|
+
# with exception class as key and :no_trace, :caller, or :trace as value; exceptions
|
33
|
+
# with :no_trace are not backtraced when logging nor are they recorded in stats
|
34
|
+
# or reported to Errbit
|
35
|
+
# @option options [String] :airbrake_endpoint URL for Airbrake for reporting exceptions
|
36
|
+
# to Errbit
|
37
|
+
# @option options [String] :airbrake_api_key for using the Airbrake API to access Errbit
|
38
|
+
#
|
39
|
+
# @return [TrueClass] always true
|
40
|
+
def init(agent, agent_name, options = {})
|
41
|
+
@agent = agent
|
42
|
+
@trace_level = options[:trace_level] || {}
|
43
|
+
notify_init(agent_name, options[:shard_id], options[:airbrake_endpoint], options[:airbrake_api_key])
|
44
|
+
reset_stats
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
# Log error and optionally track in stats
|
49
|
+
# Errbit notification is left to the callback configured in the stats tracker
|
50
|
+
#
|
51
|
+
# @param [String, Object] component reporting error; non-string is snake-cased
|
52
|
+
# @param [String] description of failure for use in logging
|
53
|
+
# @param [Exception, String] exception to be logged and tracked in stats;
|
54
|
+
# string errors are logged but not tracked in stats
|
55
|
+
# @param [Packet, Hash, NilClass] packet associated with exception
|
56
|
+
# @param [Symbol, NilClass] trace level override unless excluded by configured
|
57
|
+
# trace levels
|
58
|
+
#
|
59
|
+
# @return [Boolean] true if successfully logged, otherwise false
|
60
|
+
def log(component, description, exception = nil, packet = nil, trace = nil)
|
61
|
+
if exception.nil?
|
62
|
+
Log.error(description)
|
63
|
+
elsif exception.is_a?(String)
|
64
|
+
Log.error(description, exception)
|
65
|
+
else
|
66
|
+
trace = (@trace_level && @trace_level[exception.class]) || trace || :trace
|
67
|
+
Log.error(description, exception, trace)
|
68
|
+
track(component, exception, packet) if trace != :no_trace
|
69
|
+
end
|
70
|
+
true
|
71
|
+
rescue StandardError => e
|
72
|
+
Log.error("Failed to log error", e, :trace) rescue nil
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
76
|
+
# Track error in stats
|
77
|
+
#
|
78
|
+
# @param [String] component reporting error
|
79
|
+
# @param [Exception] exception to be tracked
|
80
|
+
# @param [Packet, Hash, NilClass] packet associated with exception
|
81
|
+
#
|
82
|
+
# @return [TrueClass] always true
|
83
|
+
def track(component, exception, packet = nil)
|
84
|
+
component = component.class.name.split("::").last.snake_case unless component.is_a?(String)
|
85
|
+
@exception_stats.track(component, exception, packet)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Notify Errbit of error if notification enabled
|
89
|
+
#
|
90
|
+
# @param [Exception, String] exception raised
|
91
|
+
# @param [Packet, Hash] packet associated with exception
|
92
|
+
# @param [Object] agent object reporting error
|
93
|
+
# @param [String] component or service area where error occurred
|
94
|
+
#
|
95
|
+
# @return [TrueClass] always true
|
96
|
+
def notify(exception, packet = nil, agent = nil, component = nil)
|
97
|
+
if @notify_enabled
|
98
|
+
data = {
|
99
|
+
:error_message => exception.respond_to?(:message) ? exception.message : exception.to_s,
|
100
|
+
:backtrace => exception.respond_to?(:backtrace) ? exception.backtrace : caller,
|
101
|
+
:environment_name => ENV["RAILS_ENV"],
|
102
|
+
}
|
103
|
+
if agent
|
104
|
+
data[:cgi_data] = (@cgi_data || {}).merge(:agent_class => agent.class.name)
|
105
|
+
elsif @cgi_data
|
106
|
+
data[:cgi_data] = @cgi_data
|
107
|
+
end
|
108
|
+
data[:error_class] = exception.class.name if exception.is_a?(Exception)
|
109
|
+
data[:component] = component if component
|
110
|
+
if packet && packet.is_a?(Packet)
|
111
|
+
data[:action] = packet.type.split("/").last if packet.respond_to?(:type)
|
112
|
+
data[:parameters] = packet.payload if packet.respond_to?(:payload)
|
113
|
+
uuid = packet.token if packet.respond_to?(:token)
|
114
|
+
elsif packet.is_a?(Hash)
|
115
|
+
action = packet[:path] || packet["path"]
|
116
|
+
data[:action] = action.split("/").last if action
|
117
|
+
data[:parameters] = packet[:data] || packet["data"]
|
118
|
+
uuid = packet[:uuid] || packet["uuid"]
|
119
|
+
end
|
120
|
+
data[:session_data] = {:uuid => uuid} if uuid
|
121
|
+
HydraulicBrake.notify(data)
|
122
|
+
end
|
123
|
+
true
|
124
|
+
rescue Exception => e
|
125
|
+
Log.error("Failed to notify Errbit", e, :trace)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Create proc for making callback to notifier
|
129
|
+
#
|
130
|
+
# @return [Proc] notifier callback
|
131
|
+
def notify_callback
|
132
|
+
Proc.new do |exception, packet, agent, component|
|
133
|
+
notify(exception, packet, agent, component)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Get exception statistics
|
138
|
+
#
|
139
|
+
# @param reset [Boolean] Whether to reset the statistics after getting the current ones
|
140
|
+
#
|
141
|
+
# @return [Hash] current statistics
|
142
|
+
def stats(reset = false)
|
143
|
+
stats = {"exceptions" => @exception_stats.all}
|
144
|
+
reset_stats if reset
|
145
|
+
stats
|
146
|
+
end
|
147
|
+
|
148
|
+
protected
|
149
|
+
|
150
|
+
# Reset statistics
|
151
|
+
# Do not recreate exception stats since may be referenced externally
|
152
|
+
#
|
153
|
+
# @return [TrueClass] always true
|
154
|
+
def reset_stats
|
155
|
+
@exception_stats ||= RightSupport::Stats::Exceptions.new(@agent, notify_callback)
|
156
|
+
@exception_stats.reset
|
157
|
+
end
|
158
|
+
|
159
|
+
# Configure HydraulicBreak for exception notification
|
160
|
+
#
|
161
|
+
# @param [String] agent_name uniquely identifying agent process on given server
|
162
|
+
# @param [Integer, NilClass] shard_id identifying shard of database in use
|
163
|
+
# @param [String] endpoint URL for Airbrake for reporting exceptions to Errbit
|
164
|
+
# @param [String] api_key for using the Airbrake API to access Errbit
|
165
|
+
#
|
166
|
+
# @return [TrueClass] always true
|
167
|
+
#
|
168
|
+
# @raise [RuntimeError] hydraulic_brake gem missing
|
169
|
+
def notify_init(agent_name, shard_id, endpoint, api_key)
|
170
|
+
if endpoint && api_key
|
171
|
+
unless require_succeeds?("hydraulic_brake")
|
172
|
+
raise RuntimeError, "hydraulic_brake gem missing - required if airbrake options used in ErrorTracker"
|
173
|
+
end
|
174
|
+
|
175
|
+
@cgi_data = {
|
176
|
+
:shard_id => shard_id,
|
177
|
+
:process => $0,
|
178
|
+
:pid => Process.pid,
|
179
|
+
:agent_name => agent_name
|
180
|
+
}
|
181
|
+
@cgi_data[:shard_id] = shard_id if shard_id
|
182
|
+
@cgi_data[:sha] = CURRENT_SOURCE_SHA if defined?(CURRENT_SOURCE_SHA)
|
183
|
+
|
184
|
+
uri = URI.parse(endpoint)
|
185
|
+
HydraulicBrake.configure do |config|
|
186
|
+
config.secure = (uri.scheme == "https")
|
187
|
+
config.host = uri.host
|
188
|
+
config.port = uri.port
|
189
|
+
config.api_key = api_key
|
190
|
+
config.project_root = AgentConfig.root_dir
|
191
|
+
end
|
192
|
+
@notify_enabled = true
|
193
|
+
else
|
194
|
+
@cgi_data = {}
|
195
|
+
@notify_enabled = false
|
196
|
+
end
|
197
|
+
true
|
198
|
+
end
|
199
|
+
|
200
|
+
end # ErrorTracker
|
201
|
+
|
202
|
+
end # RightScale
|
data/lib/right_agent/log.rb
CHANGED
data/lib/right_agent/packets.rb
CHANGED
@@ -107,7 +107,7 @@ module RightScale
|
|
107
107
|
}.to_msgpack(*a)
|
108
108
|
@size = msg.size
|
109
109
|
# For ruby 1.9 size attribute moves from front to back of packet
|
110
|
-
re = RUBY_VERSION < "1.9.0" ?
|
110
|
+
re = RUBY_VERSION < "1.9.0" ? Regexp.new("size\xC0") : Regexp.new("size\xC0$", nil, "n")
|
111
111
|
# For msgpack 0.5.1 the to_msgpack result is a MessagePack::Packer so need to convert to string
|
112
112
|
msg = msg.to_s.sub!(re) { |m| "size" + @size.to_msgpack }
|
113
113
|
msg
|
@@ -97,12 +97,15 @@ module RightScale
|
|
97
97
|
|
98
98
|
# Get age of youngest pending request
|
99
99
|
#
|
100
|
+
# === Parameters
|
101
|
+
# pending_requests(Hash):: Pending requests to be examined
|
102
|
+
#
|
100
103
|
# === Return
|
101
104
|
# age(Integer):: Age of youngest request
|
102
|
-
def youngest_age
|
105
|
+
def self.youngest_age(pending_requests)
|
103
106
|
now = Time.now
|
104
107
|
age = nil
|
105
|
-
|
108
|
+
pending_requests.each_value do |r|
|
106
109
|
seconds = (now - r.receive_time).to_i
|
107
110
|
age = seconds if age.nil? || seconds < age
|
108
111
|
end
|
@@ -111,12 +114,15 @@ module RightScale
|
|
111
114
|
|
112
115
|
# Get age of oldest pending request
|
113
116
|
#
|
117
|
+
# === Parameters
|
118
|
+
# pending_requests(Hash):: Pending requests to be examined
|
119
|
+
#
|
114
120
|
# === Return
|
115
121
|
# age(Integer):: Age of oldest request
|
116
|
-
def oldest_age
|
122
|
+
def self.oldest_age(pending_requests)
|
117
123
|
now = Time.now
|
118
124
|
age = nil
|
119
|
-
|
125
|
+
pending_requests.each_value do |r|
|
120
126
|
seconds = (now - r.receive_time).to_i
|
121
127
|
age = seconds if age.nil? || seconds > age
|
122
128
|
end
|
data/lib/right_agent/pid_file.rb
CHANGED
@@ -31,7 +31,7 @@ module RightScale
|
|
31
31
|
# the command protocol
|
32
32
|
class PidFile
|
33
33
|
|
34
|
-
class AlreadyRunning <
|
34
|
+
class AlreadyRunning < RuntimeError; end
|
35
35
|
|
36
36
|
attr_reader :identity, :pid_file, :cookie_file
|
37
37
|
|
@@ -72,8 +72,8 @@ module RightScale
|
|
72
72
|
FileUtils.mkdir_p(@pid_dir)
|
73
73
|
open(@pid_file,'w') { |f| f.write(Process.pid) }
|
74
74
|
File.chmod(0644, @pid_file)
|
75
|
-
rescue
|
76
|
-
|
75
|
+
rescue StandardError => e
|
76
|
+
ErrorTracker.log(self, "Failed to create PID file", e, nil, :caller)
|
77
77
|
raise
|
78
78
|
end
|
79
79
|
true
|
@@ -34,9 +34,9 @@ module RightScale
|
|
34
34
|
# Packet::DEFAULT_VERSION, which is true of all with version >= 12)
|
35
35
|
def can_put_version_in_packet?(version); version && version != 0 end
|
36
36
|
|
37
|
-
# Test whether given version of agent uses /
|
38
|
-
# deprecated TagQuery packet
|
39
|
-
def
|
37
|
+
# Test whether given version of agent uses /router/query_tags or /mapper/query_tags
|
38
|
+
# rather than the deprecated TagQuery packet
|
39
|
+
def can_use_router_query_tags?(version); version && version >= 8 end
|
40
40
|
|
41
41
|
# Test whether given version of agent can handle a request that is being retried
|
42
42
|
# as indicated by a retries count in the Request packet
|
@@ -45,6 +45,8 @@
|
|
45
45
|
# --grace-timeout SEC Set number of seconds before graceful termination times out
|
46
46
|
# --[no-]dup-check Set whether to check for and reject duplicate requests, .e.g., due to retries
|
47
47
|
# --fiber-pool-size, -f N Set size of fiber pool
|
48
|
+
# --airbrake-endpoint URL Set URL for Airbrake endpoint for reporting exceptions to Errbit
|
49
|
+
# --airbrake-api-key KEY Set Airbrake API key for use in reporting exceptions to Errbit
|
48
50
|
# --options, -o KEY=VAL Set options that act as final override for any persisted configuration settings
|
49
51
|
# --monit Generate monit configuration file
|
50
52
|
# --test Build test deployment using default test settings
|
@@ -205,6 +207,14 @@ module RightScale
|
|
205
207
|
options[:heartbeat] = sec.to_i
|
206
208
|
end
|
207
209
|
|
210
|
+
opts.on('--airbrake-endpoint URL') do |url|
|
211
|
+
options[:airbrake_endpoint] = url
|
212
|
+
end
|
213
|
+
|
214
|
+
opts.on('--airbrake-api-key KEY') do |key|
|
215
|
+
options[:airbrake_api_key] = key
|
216
|
+
end
|
217
|
+
|
208
218
|
opts.on('-o', '--options OPT') do |e|
|
209
219
|
fail("Invalid option definition #{e}' (use '=' to separate name and value)") unless e.include?('=')
|
210
220
|
key, val = e.split(/=/)
|
@@ -277,7 +287,7 @@ module RightScale
|
|
277
287
|
actors_dirs = AgentConfig.actors_dirs
|
278
288
|
actors.each do |a|
|
279
289
|
found = false
|
280
|
-
actors_dirs.each { |d| break if found = File.exist?(File.normalize_path(File.join(d, "#{a}.rb"))) }
|
290
|
+
actors_dirs.each { |d| break if (found = File.exist?(File.normalize_path(File.join(d, "#{a}.rb")))) }
|
281
291
|
fail("Cannot find source for actor #{a.inspect} in #{actors_dirs.inspect}") unless found
|
282
292
|
end
|
283
293
|
true
|
@@ -318,6 +328,8 @@ module RightScale
|
|
318
328
|
cfg[:http_proxy] = options[:http_proxy] if options[:http_proxy]
|
319
329
|
cfg[:http_no_proxy] = options[:http_no_proxy] if options[:http_no_proxy]
|
320
330
|
cfg[:fiber_pool_size] = options[:fiber_pool_size] if options[:fiber_pool_size]
|
331
|
+
cfg[:airbrake_endpoint] = options[:airbrake_endpoint] if options[:airbrake_endpoint]
|
332
|
+
cfg[:airbrake_api_key] = options[:airbrake_api_key] if options[:airbrake_api_key]
|
321
333
|
cfg
|
322
334
|
end
|
323
335
|
|
data/lib/right_agent/sender.rb
CHANGED
@@ -68,10 +68,6 @@ module RightScale
|
|
68
68
|
#
|
69
69
|
# === Parameters
|
70
70
|
# agent(Agent):: Agent using this sender; uses its identity, client, and following options:
|
71
|
-
# :exception_callback(Proc):: Callback with following parameters that is activated on exception events:
|
72
|
-
# exception(Exception):: Exception
|
73
|
-
# message(Packet):: Message being processed
|
74
|
-
# agent(Agent):: Reference to agent
|
75
71
|
# :offline_queueing(Boolean):: Whether to queue request if client currently disconnected,
|
76
72
|
# also requires agent invocation of initialize_offline_queue and start_offline_queue methods below,
|
77
73
|
# as well as enable_offline_mode and disable_offline_mode as client connection status changes
|
@@ -102,7 +98,7 @@ module RightScale
|
|
102
98
|
@connectivity_checker = if @mode == :amqp
|
103
99
|
# Only need connectivity checker for AMQP broker since RightHttpClient does its own checking
|
104
100
|
# via periodic session renewal
|
105
|
-
ConnectivityChecker.new(self, @options[:ping_interval] || 0, @ping_stats
|
101
|
+
ConnectivityChecker.new(self, @options[:ping_interval] || 0, @ping_stats)
|
106
102
|
end
|
107
103
|
@@instance = self
|
108
104
|
end
|
@@ -418,7 +414,7 @@ module RightScale
|
|
418
414
|
@offline_handler.terminate
|
419
415
|
@connectivity_checker.terminate if @connectivity_checker
|
420
416
|
pending = @pending_requests.kind(:send_request)
|
421
|
-
[pending.size,
|
417
|
+
[pending.size, PendingRequests.youngest_age(pending)]
|
422
418
|
else
|
423
419
|
[0, nil]
|
424
420
|
end
|
@@ -448,9 +444,6 @@ module RightScale
|
|
448
444
|
#
|
449
445
|
# === Return
|
450
446
|
# stats(Hash):: Current statistics:
|
451
|
-
# "exceptions"(Hash|nil):: Exceptions raised per category, or nil if none
|
452
|
-
# "total"(Integer):: Total exceptions for this category
|
453
|
-
# "recent"(Array):: Most recent as a hash of "count", "type", "message", "when", and "where"
|
454
447
|
# "non-deliveries"(Hash|nil):: Non-delivery activity stats with keys "total", "percent", "last",
|
455
448
|
# and 'rate' with percentage breakdown per reason, or nil if none
|
456
449
|
# "offlines"(Hash|nil):: Offline activity stats with keys "total", "last", and "duration",
|
@@ -482,11 +475,10 @@ module RightScale
|
|
482
475
|
pending["pushes"] = @pending_requests.kind(:send_push).size
|
483
476
|
requests = @pending_requests.kind(:send_request)
|
484
477
|
if (pending["requests"] = requests.size) > 0
|
485
|
-
pending["oldest age"] =
|
478
|
+
pending["oldest age"] = PendingRequests.oldest_age(requests)
|
486
479
|
end
|
487
480
|
end
|
488
481
|
stats = {
|
489
|
-
"exceptions" => @exception_stats.stats,
|
490
482
|
"non-deliveries" => @non_delivery_stats.all,
|
491
483
|
"offlines" => offlines,
|
492
484
|
"pings" => @ping_stats.all,
|
@@ -520,7 +512,6 @@ module RightScale
|
|
520
512
|
@offline_stats = RightSupport::Stats::Activity.new(measure_rate = false)
|
521
513
|
@request_kind_stats = RightSupport::Stats::Activity.new(measure_rate = false)
|
522
514
|
@send_failure_stats = RightSupport::Stats::Activity.new
|
523
|
-
@exception_stats = RightSupport::Stats::Exceptions.new(@agent, @options[:exception_callback])
|
524
515
|
true
|
525
516
|
end
|
526
517
|
|
@@ -614,9 +605,8 @@ module RightScale
|
|
614
605
|
EM_S.next_tick do
|
615
606
|
begin
|
616
607
|
http_send_once(kind, target, packet, received_at, &callback)
|
617
|
-
rescue
|
618
|
-
|
619
|
-
@exception_stats.track("request", e)
|
608
|
+
rescue StandardError => e
|
609
|
+
ErrorTracker.log(self, "Failed sending or handling response for #{packet.trace} #{packet.type}", e)
|
620
610
|
end
|
621
611
|
end
|
622
612
|
else
|
@@ -668,8 +658,7 @@ module RightScale
|
|
668
658
|
result = error_result(e.inspect)
|
669
659
|
else
|
670
660
|
agent_type = AgentIdentity.parse(@identity).agent_type
|
671
|
-
|
672
|
-
@exception_stats.track("request", e)
|
661
|
+
ErrorTracker.log(self, "Failed to send #{packet.trace} #{packet.type}", e)
|
673
662
|
result = error_result("#{agent_type.capitalize} agent internal error")
|
674
663
|
end
|
675
664
|
end
|
@@ -739,21 +728,17 @@ module RightScale
|
|
739
728
|
# TemporarilyOffline:: If cannot send request because RightNet client currently disconnected
|
740
729
|
# and offline queueing is disabled
|
741
730
|
def amqp_send_once(packet, ids = nil)
|
742
|
-
name =
|
743
731
|
exchange = {:type => :fanout, :name => @request_queue, :options => {:durable => true, :no_declare => @secure}}
|
744
732
|
@agent.client.publish(exchange, packet, :persistent => packet.persistent, :mandatory => true,
|
745
733
|
:log_filter => [:tags, :target, :tries, :persistent], :brokers => ids)
|
746
734
|
rescue RightAMQP::HABrokerClient::NoConnectedBrokers => e
|
747
|
-
|
748
|
-
Log.error(msg, e)
|
735
|
+
ErrorTracker.log(self, error = "Failed to publish request #{packet.trace} #{packet.type}", e, packet)
|
749
736
|
@send_failure_stats.update("NoConnectedBrokers")
|
750
|
-
raise TemporarilyOffline.new(
|
751
|
-
rescue
|
752
|
-
|
753
|
-
Log.error(msg, e, :trace)
|
737
|
+
raise TemporarilyOffline.new(error + " (#{e.class}: #{e.message})")
|
738
|
+
rescue StandardError => e
|
739
|
+
ErrorTracker.log(self, error = "Failed to publish request #{packet.trace} #{packet.type}", e, packet)
|
754
740
|
@send_failure_stats.update(e.class.name)
|
755
|
-
|
756
|
-
raise SendFailure.new(msg + " (#{e.class}: #{e.message})")
|
741
|
+
raise SendFailure.new(error + " (#{e.class}: #{e.message})")
|
757
742
|
end
|
758
743
|
|
759
744
|
# Send request via AMQP with one or more retries if do not receive a response in time
|
@@ -802,14 +787,13 @@ module RightScale
|
|
802
787
|
@connectivity_checker.check(check_broker_ids.first) if check_broker_ids.any? && count == 1
|
803
788
|
end
|
804
789
|
rescue TemporarilyOffline => e
|
805
|
-
|
790
|
+
ErrorTracker.log(self, "Failed retry for #{packet.trace} #{packet.type} because temporarily offline")
|
806
791
|
rescue SendFailure => e
|
807
|
-
|
792
|
+
ErrorTracker.log(self, "Failed retry for #{packet.trace} #{packet.type} because of send failure")
|
808
793
|
rescue Exception => e
|
809
794
|
# Not sending a response here because something more basic is broken in the retry
|
810
795
|
# mechanism and don't want an error response to preempt a delayed actual response
|
811
|
-
|
812
|
-
@exception_stats.track("retry", e, packet)
|
796
|
+
ErrorTracker.log(self, "Failed retry for #{packet.trace} #{packet.type} without responding", e, packet)
|
813
797
|
end
|
814
798
|
end
|
815
799
|
end
|