Class: Datadog::HTTPTransport
- Inherits:
-
Object
- Object
- Datadog::HTTPTransport
- Defined in:
- lib/ddtrace/transport.rb
Overview
Transport class that handles the spans delivery to the local trace-agent. The class wraps a Net:HTTP instance so that the Transport is thread-safe.
Constant Summary collapse
- TIMEOUT =
seconds before the transport timeout
1
Instance Attribute Summary collapse
-
#hostname ⇒ Object
Returns the value of attribute hostname.
-
#port ⇒ Object
Returns the value of attribute port.
-
#services_endpoint ⇒ Object
readonly
Returns the value of attribute services_endpoint.
-
#traces_endpoint ⇒ Object
readonly
Returns the value of attribute traces_endpoint.
Instance Method Summary collapse
- #client_error?(code) ⇒ Boolean
-
#downgrade! ⇒ Object
Downgrade the connection to a compatibility version of the HTTPTransport; this method should target a stable API that works whatever is the agent or the tracing client versions.
-
#downgrade?(code) ⇒ Boolean
receiving a 404 means that we’re targeting an endpoint that is not available in the trace agent.
-
#handle_response(response) ⇒ Object
handles the server response; here you can log the trace-agent response or do something more complex to recover from a possible error.
- #informational?(code) ⇒ Boolean
-
#initialize(hostname, port, options = {}) ⇒ HTTPTransport
constructor
A new instance of HTTPTransport.
-
#post(url, data) ⇒ Object
send data to the trace-agent; the method is thread-safe.
- #redirect?(code) ⇒ Boolean
-
#send(endpoint, data) ⇒ Object
route the send to the right endpoint.
- #server_error?(code) ⇒ Boolean
- #stats ⇒ Object
- #success?(code) ⇒ Boolean
Constructor Details
#initialize(hostname, port, options = {}) ⇒ HTTPTransport
Returns a new instance of HTTPTransport.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/ddtrace/transport.rb', line 17 def initialize(hostname, port, = {}) @hostname = hostname @port = port @traces_endpoint = '/v0.3/traces'.freeze @services_endpoint = '/v0.3/services'.freeze @compatibility_mode = false @encoder = .fetch(:encoder, Datadog::Encoding::MsgpackEncoder.new()) # overwrite the Content-type with the one chosen in the Encoder @headers = .fetch(:headers, {}) @headers['Content-Type'] = @encoder.content_type # stats @mutex = Mutex.new @count_success = 0 @count_client_error = 0 @count_server_error = 0 @count_internal_error = 0 end |
Instance Attribute Details
#hostname ⇒ Object
Returns the value of attribute hostname.
11 12 13 |
# File 'lib/ddtrace/transport.rb', line 11 def hostname @hostname end |
#port ⇒ Object
Returns the value of attribute port.
11 12 13 |
# File 'lib/ddtrace/transport.rb', line 11 def port @port end |
#services_endpoint ⇒ Object (readonly)
Returns the value of attribute services_endpoint.
12 13 14 |
# File 'lib/ddtrace/transport.rb', line 12 def services_endpoint @services_endpoint end |
#traces_endpoint ⇒ Object (readonly)
Returns the value of attribute traces_endpoint.
12 13 14 |
# File 'lib/ddtrace/transport.rb', line 12 def traces_endpoint @traces_endpoint end |
Instance Method Details
#client_error?(code) ⇒ Boolean
94 95 96 |
# File 'lib/ddtrace/transport.rb', line 94 def client_error?(code) code.between?(400, 499) end |
#downgrade! ⇒ Object
Downgrade the connection to a compatibility version of the HTTPTransport; this method should target a stable API that works whatever is the agent or the tracing client versions.
74 75 76 77 78 79 80 |
# File 'lib/ddtrace/transport.rb', line 74 def downgrade! @compatibility_mode = true @traces_endpoint = '/v0.2/traces'.freeze @services_endpoint = '/v0.2/services'.freeze @encoder = Datadog::Encoding::JSONEncoder.new() @headers['Content-Type'] = @encoder.content_type end |
#downgrade?(code) ⇒ Boolean
receiving a 404 means that we’re targeting an endpoint that is not available in the trace agent. Usually this means that we’ve an up-to-date tracing client, while running an obsolete agent. receiving a 415 means that we’re using an unsupported content-type with an existing endpoint. Usually this means that we’re using a newer encoder with a previous endpoint. In both cases, we’re going to downgrade the transporter encoder so that it will target a stable API.
109 110 111 |
# File 'lib/ddtrace/transport.rb', line 109 def downgrade?(code) code == 404 || code == 415 end |
#handle_response(response) ⇒ Object
handles the server response; here you can log the trace-agent response or do something more complex to recover from a possible error. This function is handled within the HTTP mutex.synchronize so it’s thread-safe.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/ddtrace/transport.rb', line 116 def handle_response(response) status_code = response.code.to_i if success?(status_code) Datadog::Tracer.log.debug('Payload correctly sent to the trace agent.') @mutex.synchronize { @count_success += 1 } elsif downgrade?(status_code) Datadog::Tracer.log.debug("calling the endpoint but received #{status_code}; downgrading the API") elsif client_error?(status_code) Datadog::Tracer.log.error("Client error: #{response.message}") @mutex.synchronize { @count_client_error += 1 } elsif server_error?(status_code) Datadog::Tracer.log.error("Server error: #{response.message}") @mutex.synchronize { @count_server_error += 1 } end status_code rescue StandardError => e Datadog::Tracer.log.error(e.) @mutex.synchronize { @count_internal_error += 1 } 500 end |
#informational?(code) ⇒ Boolean
82 83 84 |
# File 'lib/ddtrace/transport.rb', line 82 def informational?(code) code.between?(100, 199) end |
#post(url, data) ⇒ Object
send data to the trace-agent; the method is thread-safe
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/ddtrace/transport.rb', line 59 def post(url, data) Datadog::Tracer.log.debug("Sending data from process: #{Process.pid}") request = Net::HTTP::Post.new(url, @headers) request.body = data response = Net::HTTP.start(@hostname, @port, read_timeout: TIMEOUT) { |http| http.request(request) } handle_response(response) rescue StandardError => e Datadog::Tracer.log.error(e.) 500 end |
#redirect?(code) ⇒ Boolean
90 91 92 |
# File 'lib/ddtrace/transport.rb', line 90 def redirect?(code) code.between?(300, 399) end |
#send(endpoint, data) ⇒ Object
route the send to the right endpoint
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ddtrace/transport.rb', line 38 def send(endpoint, data) case endpoint when :services payload = @encoder.encode_services(data) status_code = post(@services_endpoint, payload) when :traces payload = @encoder.encode_traces(data) status_code = post(@traces_endpoint, payload) else Datadog::Tracer.log.error("Unsupported endpoint: #{endpoint}") return nil end return status_code unless downgrade?(status_code) && !@compatibility_mode # the API endpoint is not available so we should downgrade the connection and re-try the call downgrade! send(endpoint, data) end |
#server_error?(code) ⇒ Boolean
98 99 100 |
# File 'lib/ddtrace/transport.rb', line 98 def server_error?(code) code.between?(500, 599) end |
#stats ⇒ Object
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ddtrace/transport.rb', line 139 def stats @mutex.synchronize do { success: @count_success, client_error: @count_client_error, server_error: @count_server_error, internal_error: @count_internal_error } end end |
#success?(code) ⇒ Boolean
86 87 88 |
# File 'lib/ddtrace/transport.rb', line 86 def success?(code) code.between?(200, 299) end |