Class: ScoutAgent::Server
- Inherits:
-
Object
- Object
- ScoutAgent::Server
- Defined in:
- lib/scout_agent/server.rb
Overview
This class is a thin wrapper over RestClient for Scout’s check-in API. Public methods are provided for each action you can perform againt the API.
Defined Under Namespace
Classes: AgentTimeoutError
Constant Summary collapse
- REQUEST_TIMEOUT =
Another Timeout for Net::Http requests. Their limit doesn’t always seem to trigger in the face of server errors, so we add this redundant check to avoid hanging on check-in.
5 * 60
Instance Attribute Summary collapse
-
#log ⇒ Object
readonly
The log connection notes will be written to.
Instance Method Summary collapse
-
#get_plan(additional_headers = { }) ⇒ Object
This method fetches the current plan for this agent.
-
#initialize(log = WireTap.new(nil)) ⇒ Server
constructor
Create a new API wrapper, optionally with a
log
to write connection details to. -
#post_checkin(data) ⇒ Object
This method can be used to send
data
to the Scout API as a check-in. -
#post_log(log_file) ⇒ Object
Uploads
log_file
to the server for troubleshooting.
Constructor Details
#initialize(log = WireTap.new(nil)) ⇒ Server
Create a new API wrapper, optionally with a log
to write connection details to.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/scout_agent/server.rb', line 24 def initialize(log = WireTap.new(nil)) @log = log @rest_client = RestClient::Resource.new( Plan.agent_url, :headers => { :client_version => ScoutAgent::VERSION, :accept_encoding => "gzip" }, :ssl_ca_file => File.join( File.dirname(__FILE__), *%w[.. .. data cacert.pem] ), :verify_ssl => OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT ) # make sure proxy is set, if needed RestClient.proxy = Plan.proxy_url end |
Instance Attribute Details
#log ⇒ Object (readonly)
The log connection notes will be written to.
40 41 42 |
# File 'lib/scout_agent/server.rb', line 40 def log @log end |
Instance Method Details
#get_plan(additional_headers = { }) ⇒ Object
This method fetches the current plan for this agent. You can pass any additional_headers
for the request if needed (mainly useful for :if_modified_since
).
This method will return the raw plan when it is successfully fetched. An empty String is returned if the plan is malformed or unchanged. Finally, nil
is returned if the plan cannot be retrieved for some reason.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/scout_agent/server.rb', line 51 def get_plan(additional_headers = { }) request { @rest_client["plan.scout"].get(additional_headers) } rescue Zlib::Error # could not decompress response log.warn("Plan was malformed zipped data.") "" # replace bad plan with empty plan rescue RestClient::RequestFailed => error # RestClient bug workaround log.warn("Plan was returned as a failure code: #{error.http_code}.") nil # failed to retrieve plan rescue RestClient::NotModified log.info("Plan was not modified.") "" # empty plan rescue OpenSSL::SSL::SSLError log.warn("SSL verification failed. The plan could not be trusted.") nil # cannot trust any plan we received rescue Exception => error # networking problem log.warn("Plan could not be retrieved: #{error.class}.") nil # failed to retrieve plan end |
#post_checkin(data) ⇒ Object
This method can be used to send data
to the Scout API as a check-in. The data is zipped before it is sent to reduce the cost duplicated reports as much as possible.
If the ckeck-in succeeds, true
is returned. However, false
doesn’t ensure that we failed. RestClient may timeout a long connection attempt, but the server may still complete it eventually.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/scout_agent/server.rb', line 81 def post_checkin(data) io = StringIO.new gzip = Zlib::GzipWriter.new(io) gzip << data.to_json gzip.close request do @rest_client["checkin.scout"].post( io.string, :content_type => "application/json", :content_encoding => "gzip" ) end true rescue Zlib::Error # could not compress data for sending log.error("Check-in could not be zipped.") false rescue RestClient::RequestFailed => error # RestClient bug workaround log.warn( "Check-in was returned as a failure code: " + "#{error.http_code}." ) false rescue OpenSSL::SSL::SSLError log.warn( "SSL verification failed. " + "Could not send check-in to untrusted server." ) false # cannot trust server rescue Exception => error # networking problem # bypass for a RestClient bug if error.is_a?(NoMethodError) and error.backtrace and error.backtrace.first.to_s =~ /\brest-client\b/ return true end log.warn("Check-in could not be sent: #{error.class}.") false # we failed to send and will retry later end |
#post_log(log_file) ⇒ Object
Uploads log_file
to the server for troubleshooting. Returns true
if the upload succeeded.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/scout_agent/server.rb', line 120 def post_log(log_file) request do @rest_client["log.scout"].post( log_file.read, :content_type => "text/plain", :content_encoding => "gzip" ) end true rescue RestClient::RequestFailed => error # RestClient bug workaround log.warn( "Log upload was returned as a failure code: " + "#{error.http_code}." ) false rescue OpenSSL::SSL::SSLError log.warn( "SSL verification failed. " + "Could not send log to untrusted server." ) false # cannot trust server rescue Exception => error # networking problem log.warn("Log could not be sent: #{error.class}.") false # could not send log end |