Class: Fluent::DatadogOutput::DatadogHTTPClient
- Inherits:
-
DatadogClient
- Object
- DatadogClient
- Fluent::DatadogOutput::DatadogHTTPClient
- Defined in:
- lib/fluent/plugin/out_datadog.rb
Overview
HTTP datadog client
Constant Summary collapse
- RETRYABLE_NETWORK_EXCEPTIONS =
Transient network exceptions that warrant a retry. This mirrors the set Ruby's Net::HTTP retries for idempotent requests (see Net::HTTP#max_retries=), which notably does NOT include POST, plus the connection-establishment errors net-http-persistent wraps in its own Error. Because our log POSTs are non-idempotent, Net::HTTP will not retry them for us, so we classify these ourselves and route them through send_retries (and, on exhaustion, up to Fluentd core).
[ Net::OpenTimeout, Net::ReadTimeout, EOFError, IOError, SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError, Net::HTTP::Persistent::Error, ].freeze
Instance Method Summary collapse
- #close ⇒ Object
-
#initialize(logger, use_ssl, no_ssl_validation, host, ssl_port, port, http_proxy, custom_headers, use_compression, api_key, force_v1_routes = false) ⇒ DatadogHTTPClient
constructor
A new instance of DatadogHTTPClient.
- #send(payload) ⇒ Object
Methods inherited from DatadogClient
Constructor Details
#initialize(logger, use_ssl, no_ssl_validation, host, ssl_port, port, http_proxy, custom_headers, use_compression, api_key, force_v1_routes = false) ⇒ DatadogHTTPClient
Returns a new instance of DatadogHTTPClient.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/fluent/plugin/out_datadog.rb', line 375 def initialize(logger, use_ssl, no_ssl_validation, host, ssl_port, port, http_proxy, custom_headers, use_compression, api_key, force_v1_routes = false) @logger = logger protocol = use_ssl ? "https" : "http" port = use_ssl ? ssl_port : port if force_v1_routes @uri = URI("#{protocol}://#{host}:#{port.to_s}/v1/input/#{api_key}") else @uri = URI("#{protocol}://#{host}:#{port.to_s}/api/v2/logs") end proxy_uri = :ENV if http_proxy proxy_uri = URI.parse(http_proxy) elsif ENV['HTTP_PROXY'] || ENV['http_proxy'] logger.info("Using HTTP proxy defined in `HTTP_PROXY`/`http_proxy` env vars") end logger.info("Starting HTTP connection to #{protocol}://#{host}:#{port.to_s} with compression " + (use_compression ? "enabled" : "disabled") + (force_v1_routes ? " using v1 routes" : " using v2 routes")) @client = Net::HTTP::Persistent.new name: "fluent-plugin-datadog-logcollector", proxy: proxy_uri @client.verify_mode = OpenSSL::SSL::VERIFY_NONE if no_ssl_validation custom_headers.each do |key, value| @client.override_headers[key] = value end unless force_v1_routes @client.override_headers["DD-API-KEY"] = api_key @client.override_headers["DD-EVP-ORIGIN"] = "fluent" @client.override_headers["DD-EVP-ORIGIN-VERSION"] = DatadogFluentPlugin::VERSION end @client.override_headers["Content-Type"] = "application/json" if use_compression @client.override_headers["Content-Encoding"] = "gzip" end if !@client.proxy_uri.nil? # Log the proxy settings as resolved by the HTTP client logger.info("Using HTTP proxy #{@client.proxy_uri.scheme}://#{@client.proxy_uri.host}:#{@client.proxy_uri.port} username: #{@client.proxy_uri.user ? "set" : "unset"}, password: #{@client.proxy_uri.password ? "set" : "unset"}") end end |
Instance Method Details
#close ⇒ Object
431 432 433 |
# File 'lib/fluent/plugin/out_datadog.rb', line 431 def close @client.shutdown end |
#send(payload) ⇒ Object
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/fluent/plugin/out_datadog.rb', line 411 def send(payload) request = Net::HTTP::Post.new @uri.request_uri request.body = payload begin response = @client.request @uri, request rescue *RETRYABLE_NETWORK_EXCEPTIONS => e # Transient network failure before we ever saw a response. Net::HTTP # won't retry a POST for us, so surface it as retryable. raise RetryableError.new "Unable to send payload, transient network error: #{e.class}: #{e.}" end res_code = response.code.to_i # on a backend error or on an http 429, retry with backoff if res_code >= 500 || res_code == 429 raise RetryableError.new "Unable to send payload: #{res_code} #{response.}" end if res_code >= 400 @logger.error("Unable to send payload due to client error: #{res_code} #{response.}") end end |