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