module OneApm::Collector::CollectorService::HttpConnection
Constants
- OA_API_VERSION
- OA_CONNECTION_ERRORS
These include Errno connection errors, and all indicate that the underlying TCP connection may be in a bad state.
Public Instance Methods
cert_file_path()
click to toggle source
The path to the certificate file used to verify the SSL connection if verify_peer is enabled
# File lib/one_apm/collector/collector/http_connection.rb, line 215 def cert_file_path if path_override = OneApm::Manager.config[:ca_bundle_path] OneApm::Manager.logger.warn("Couldn't find CA bundle from configured ca_bundle_path: #{path_override}") unless File.exists? path_override path_override else File.expand_path(File.join(probe.oneapm_root, 'config', 'cert', 'cacert.pem')) end end
check_post_size(post_string)
click to toggle source
Raises an UnrecoverableServerException
if the post_string is longer than the limit configured in the probe object
# File lib/one_apm/collector/collector/http_connection.rb, line 244 def check_post_size(post_string) return if post_string.size < OneApm::Manager.config[:post_size_limit] OneApm::Manager.logger.debug "Tried to send too much data: #{post_string.size} bytes" raise UnrecoverableServerException.new('413 Request Entity Too Large') end
compress_request(data)
click to toggle source
Compress request data
# File lib/one_apm/collector/collector/http_connection.rb, line 225 def compress_request(data) encoding = 'deflate' data = OneApm::Support::Encoders::Compressed.encode(data) check_post_size(data) [data, encoding] end
create_and_start_http_connection()
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 163 def create_and_start_http_connection conn = create_http_connection start_connection(conn) conn end
create_http_connection()
click to toggle source
Return the Net::HTTP
with proxy configuration given the OneApm::Support::Server
object.
# File lib/one_apm/collector/collector/http_connection.rb, line 176 def create_http_connection # Proxy returns regular HTTP if @proxy_host is nil (the default) http_class = Net::HTTP::Proxy(proxy_server.name, proxy_server.port, proxy_server.user, proxy_server.password) conn = http_class.new((@collector.ip || @collector.name), @collector.port) setup_connection_for_ssl(conn) if OneApm::Manager.config[:ssl] setup_connection_timeouts(conn) OneApm::Manager.logger.debug("Created net/http handle to #{conn.address}:#{conn.port}") conn end
decompress_response(response)
click to toggle source
Decompresses the response from the server, if it is gzip encoded, otherwise returns it verbatim
# File lib/one_apm/collector/collector/http_connection.rb, line 234 def decompress_response(response) if response['content-encoding'] == 'gzip' Zlib::GzipReader.new(StringIO.new(response.body)).read else response.body end end
http_connection()
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 131 def http_connection if @in_session establish_shared_connection else create_http_connection end end
invoke_remote(method, payload = [], options = {},query_params={})
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 11 def invoke_remote(method, payload = [], options = {},query_params={}) start_ts = Time.now data = nil begin data = @marshaller.dump(payload, options) rescue StandardError, SystemStackError => e handle_serialization_error(method, e) end serialize_finish_ts = Time.now data, encoding = compress_request(data) size = data.size uri = remote_method_uri(method, @marshaller.format,query_params) full_uri = "#{@collector}#{uri}" @audit_logger.log_request(full_uri, payload, @marshaller) response = send_request(:data => data, :uri => uri, :encoding => encoding, :collector => @collector) response = @marshaller.load(decompress_response(response)) @audit_logger.log_response(response) response ensure record_timing_supportability_metrics(method, start_ts, serialize_finish_ts) if size record_size_supportability_metrics(method, size, options[:item_count]) end end
remote_method_uri(method, format, query_params={})
click to toggle source
The path on the server that we should post our data to
# File lib/one_apm/collector/collector/http_connection.rb, line 44 def remote_method_uri(method, format, query_params={}) params = {'run_id' => @agent_id, 'marshal_format' => format}.merge(query_params) uri = "/tpm/agent.do?PROTOCOL_VERSION=#{OA_PROTOCOL_VERSION}&license_key=#{@license_key}&method=#{method}" uri << '&' + params.map do |k,v| next unless v "#{k}=#{v}" end.compact.join('&') uri end
send_request(opts)
click to toggle source
Posts to the specified server
Options:
- :uri => the path to request on the server (a misnomer of course) - :encoding => the encoding to pass to the server - :collector => a URI object that responds to the 'name' method and returns the name of the collector to contact - :data => the data to send as the body of the request
# File lib/one_apm/collector/collector/http_connection.rb, line 64 def send_request(opts) request = Net::HTTP::Post.new(opts[:uri], 'CONTENT-ENCODING' => opts[:encoding], 'HOST' => opts[:collector].name, 'API-VERSION' => OA_API_VERSION) request['user-agent'] = user_agent request['_SKIP_CAT_'] = true request.body = opts[:data] #see http://jira.oneapm.me/browse/AI-3227 #old content_type is "multipart/form-data; boundary=-oneapm-#{request.object_id}-" request.content_type = 'application/json' response = nil attempts = 0 max_attempts = 2 begin attempts += 1 conn = http_connection OneApm::Manager.logger.debug "Sending request to #{opts[:collector]}#{opts[:uri]}" OneApm::TimerLib.timeout(@request_timeout) do response = conn.request(request) end rescue *OA_CONNECTION_ERRORS => e close_shared_connection if attempts < max_attempts OneApm::Manager.logger.debug("Retrying request to #{opts[:collector]}#{opts[:uri]} after #{e}") retry else raise ServerConnectionException, "Recoverable error talking to #{@collector} after #{attempts} attempts: #{e}" end end log_and_return_response response end
session(&block)
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 98 def session(&block) raise ArgumentError, "#{self.class}#shared_connection must be passed a block" unless block_given? begin t0 = Time.now @in_session = true if OneApm::Manager.config[:aggressive_keepalive] session_with_keepalive(&block) else session_without_keepalive(&block) end rescue *OA_CONNECTION_ERRORS => e elapsed = Time.now - t0 raise OneApm::ServerConnectionException, "Recoverable error connecting to #{@collector} after #{elapsed} seconds: #{e}" ensure @in_session = false end end
session_with_keepalive(&block)
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 117 def session_with_keepalive(&block) establish_shared_connection block.call end
session_without_keepalive(&block)
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 122 def session_without_keepalive(&block) begin establish_shared_connection block.call ensure close_shared_connection end end
setup_connection_for_ssl(conn)
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 189 def setup_connection_for_ssl(conn) # Jruby 1.6.8 requires a gem for full ssl support and will throw # an error when use_ssl=(true) is called and jruby-openssl isn't # installed conn.use_ssl = true conn.verify_mode = OpenSSL::SSL::VERIFY_PEER conn.cert_store = ssl_cert_store rescue StandardError, LoadError msg = "Agent is configured to use SSL, but SSL is not available in the environment. " msg << "Either disable SSL in the agent configuration, or install SSL support." raise UnrecoverableAgentException.new(msg) end
setup_connection_timeouts(conn)
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 154 def setup_connection_timeouts(conn) # We use Timeout explicitly instead of this conn.read_timeout = nil if conn.respond_to?(:keep_alive_timeout) && OneApm::Manager.config[:aggressive_keepalive] conn.keep_alive_timeout = OneApm::Manager.config[:keep_alive_timeout] end end
ssl_cert_store()
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 202 def ssl_cert_store path = cert_file_path if !@ssl_cert_store || path != @cached_cert_store_path OneApm::Manager.logger.debug("Creating SSL certificate store from file at #{path}") @ssl_cert_store = OpenSSL::X509::Store.new @ssl_cert_store.add_file(path) @cached_cert_store_path = path end @ssl_cert_store end
start_connection(conn)
click to toggle source
# File lib/one_apm/collector/collector/http_connection.rb, line 169 def start_connection(conn) OneApm::Manager.logger.debug("Opening TCP connection to #{conn.address}:#{conn.port}") OneApm::TimerLib.timeout(@request_timeout) { conn.start } conn end