From fc9f774685445c03102fc553b324715569a2d3e5 Mon Sep 17 00:00:00 2001 From: Ganga Mahesh Siddem Date: Sat, 16 May 2020 13:54:34 -0700 Subject: [PATCH 1/6] add proxy support for telemetry client --- .../channel/asynchronous_sender.rb | 5 +++-- lib/application_insights/channel/sender_base.rb | 10 ++++++++-- lib/application_insights/channel/synchronous_sender.rb | 7 ++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/application_insights/channel/asynchronous_sender.rb b/lib/application_insights/channel/asynchronous_sender.rb index da573f0..25b63ef 100644 --- a/lib/application_insights/channel/asynchronous_sender.rb +++ b/lib/application_insights/channel/asynchronous_sender.rb @@ -20,15 +20,16 @@ class AsynchronousSender < SenderBase SERVICE_ENDPOINT_URI = 'https://dc.services.visualstudio.com/v2/track' # Initializes a new instance of the class. # @param [String] service_endpoint_uri the address of the service to send + # @param [Hash] proxy server configuration to send (optional) # telemetry data to. - def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI) + def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI, proxy = {}) @send_interval = 1.0 @send_remaining_time = 0 @send_time = 3.0 @lock_work_thread = Mutex.new @work_thread = nil @start_notification_processed = true - super service_endpoint_uri + super service_endpoint_uri, proxy end # The time span in seconds at which the the worker thread will check the diff --git a/lib/application_insights/channel/sender_base.rb b/lib/application_insights/channel/sender_base.rb index 2431bf7..f58ea69 100644 --- a/lib/application_insights/channel/sender_base.rb +++ b/lib/application_insights/channel/sender_base.rb @@ -16,12 +16,14 @@ module Channel class SenderBase # Initializes a new instance of the class. # @param [String] service_endpoint_uri the address of the service to send + # @param [Hash] proxy server configuration to send (optional) # telemetry data to. - def initialize(service_endpoint_uri) + def initialize(service_endpoint_uri, proxy = {}) @service_endpoint_uri = service_endpoint_uri @queue = nil @send_buffer_size = 100 @logger = Logger.new(STDOUT) + @proxy = proxy end # The service endpoint URI where this sender will send data to. @@ -60,7 +62,11 @@ def send(data_to_send) compressed_data = compress(json) request.body = compressed_data - http = Net::HTTP.new uri.hostname, uri.port + if @proxy.nil? || @proxy.empty? + http = Net::HTTP.new uri.hostname, uri.port + else + http = Net::HTTP.new(uri.hostname, uri.port, @proxy[:addr], @proxy[:port], @proxy[:user], @proxy[:pass]) + end if uri.scheme.downcase == 'https' http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE diff --git a/lib/application_insights/channel/synchronous_sender.rb b/lib/application_insights/channel/synchronous_sender.rb index ade2f08..ffaf0f7 100644 --- a/lib/application_insights/channel/synchronous_sender.rb +++ b/lib/application_insights/channel/synchronous_sender.rb @@ -1,4 +1,4 @@ -require_relative 'sender_base' +require_relative "sender_base" module ApplicationInsights module Channel @@ -8,9 +8,10 @@ class SynchronousSender < SenderBase SERVICE_ENDPOINT_URI = 'https://dc.services.visualstudio.com/v2/track' # Initializes a new instance of the class. # @param [String] service_endpoint_uri the address of the service to send + # @param [Hash] proxy server configuration to send (optional) # telemetry data to. - def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI) - super service_endpoint_uri + def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI, proxy = {}) + super service_endpoint_uri, proxy end end end From b6e2dd1862ea8244679ce334cc35f16389d56fed Mon Sep 17 00:00:00 2001 From: Ganga Mahesh Siddem Date: Sat, 16 May 2020 14:10:50 -0700 Subject: [PATCH 2/6] update README.md with proxy example --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index d7444f2..0563e71 100644 --- a/README.md +++ b/README.md @@ -162,3 +162,19 @@ req['Request-Id'] = "#{application_insights_request_id}1" if application_insight Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) } ``` + +### Configuring Telemetry client with Proxy endpoint ### +```ruby +require 'application_insights' +# if proxy server doesnt have authentication, provide arbitrary username and password +# : Address or FQDN of the proxy server +# : port number for the proxy server +proxy = { :addr => '', :port => '', :user: '', :pass: '' } +sender = ApplicationInsights::Channel::AsynchronousSender.new 'https://dc.services.visualstudio.com/v2/track', proxy +queue = ApplicationInsights::Channel::AsynchronousQueue.new sender +channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue +tc = ApplicationInsights::TelemetryClient.new '', channel +# Note: the event will be sent on a separate thread; if the app finishes before +# the thread finishes, the data is lost +tc.track_event 'My event' +``` From b0f17bb6395ec145f6c823b0da9580b2f8dced8f Mon Sep 17 00:00:00 2001 From: Ganga Mahesh Siddem Date: Sat, 16 May 2020 14:25:31 -0700 Subject: [PATCH 3/6] add accessor for proxy --- .../channel/sender_base.rb | 25 +++++++++++-------- .../channel/synchronous_sender.rb | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/application_insights/channel/sender_base.rb b/lib/application_insights/channel/sender_base.rb index f58ea69..b74f7de 100644 --- a/lib/application_insights/channel/sender_base.rb +++ b/lib/application_insights/channel/sender_base.rb @@ -1,9 +1,9 @@ -require 'json' -require 'net/http' -require 'openssl' -require 'stringio' -require 'zlib' -require 'logger' +require "json" +require "net/http" +require "openssl" +require "stringio" +require "zlib" +require "logger" module ApplicationInsights module Channel @@ -43,6 +43,9 @@ def initialize(service_endpoint_uri, proxy = {}) # The logger for the sender. attr_accessor :logger + # The proxy for the sender. + attr_accessor :proxy + # Immediately sends the data passed in to {#service_endpoint_uri}. If the # service request fails, the passed in items are pushed back to the {#queue}. # @param [Array] data_to_send an array of @@ -50,9 +53,9 @@ def initialize(service_endpoint_uri, proxy = {}) def send(data_to_send) uri = URI(@service_endpoint_uri) headers = { - 'Accept' => 'application/json', - 'Content-Type' => 'application/json; charset=utf-8', - 'Content-Encoding' => 'gzip' + "Accept" => "application/json", + "Content-Type" => "application/json; charset=utf-8", + "Content-Encoding" => "gzip", } request = Net::HTTP::Post.new(uri.path, headers) @@ -67,7 +70,7 @@ def send(data_to_send) else http = Net::HTTP.new(uri.hostname, uri.port, @proxy[:addr], @proxy[:port], @proxy[:user], @proxy[:pass]) end - if uri.scheme.downcase == 'https' + if uri.scheme.downcase == "https" http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE end @@ -76,7 +79,7 @@ def send(data_to_send) http.finish if http.started? if !response.kind_of? Net::HTTPSuccess - @logger.warn('application_insights') { "Failed to send data: #{response.message}" } + @logger.warn("application_insights") { "Failed to send data: #{response.message}" } end end diff --git a/lib/application_insights/channel/synchronous_sender.rb b/lib/application_insights/channel/synchronous_sender.rb index ffaf0f7..4b5ca09 100644 --- a/lib/application_insights/channel/synchronous_sender.rb +++ b/lib/application_insights/channel/synchronous_sender.rb @@ -1,4 +1,4 @@ -require_relative "sender_base" +require_relative 'sender_base' module ApplicationInsights module Channel From 08e6140f876eb3da57421df750db8c57e39bedf2 Mon Sep 17 00:00:00 2001 From: Ganga Mahesh Siddem Date: Sat, 16 May 2020 14:30:10 -0700 Subject: [PATCH 4/6] revert redundant changes --- .../channel/sender_base.rb | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/application_insights/channel/sender_base.rb b/lib/application_insights/channel/sender_base.rb index b74f7de..894ff43 100644 --- a/lib/application_insights/channel/sender_base.rb +++ b/lib/application_insights/channel/sender_base.rb @@ -1,9 +1,9 @@ -require "json" -require "net/http" -require "openssl" -require "stringio" -require "zlib" -require "logger" +require 'json' +require 'net/http' +require 'openssl' +require 'stringio' +require 'zlib' +require 'logger' module ApplicationInsights module Channel @@ -53,9 +53,9 @@ def initialize(service_endpoint_uri, proxy = {}) def send(data_to_send) uri = URI(@service_endpoint_uri) headers = { - "Accept" => "application/json", - "Content-Type" => "application/json; charset=utf-8", - "Content-Encoding" => "gzip", + 'Accept' => 'application/json', + 'Content-Type' => 'application/json; charset=utf-8', + 'Content-Encoding' => 'gzip', } request = Net::HTTP::Post.new(uri.path, headers) @@ -70,7 +70,7 @@ def send(data_to_send) else http = Net::HTTP.new(uri.hostname, uri.port, @proxy[:addr], @proxy[:port], @proxy[:user], @proxy[:pass]) end - if uri.scheme.downcase == "https" + if uri.scheme.downcase == 'https' http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE end @@ -79,7 +79,7 @@ def send(data_to_send) http.finish if http.started? if !response.kind_of? Net::HTTPSuccess - @logger.warn("application_insights") { "Failed to send data: #{response.message}" } + @logger.warn('application_insights') { "Failed to send data: #{response.message}" } end end From 18f7c117845a3d9adbbddec1a5ed849ea05f8a9e Mon Sep 17 00:00:00 2001 From: Ganga Mahesh Siddem Date: Sat, 16 May 2020 14:31:32 -0700 Subject: [PATCH 5/6] revert redundant change --- lib/application_insights/channel/sender_base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/application_insights/channel/sender_base.rb b/lib/application_insights/channel/sender_base.rb index 894ff43..fedd2f1 100644 --- a/lib/application_insights/channel/sender_base.rb +++ b/lib/application_insights/channel/sender_base.rb @@ -55,7 +55,7 @@ def send(data_to_send) headers = { 'Accept' => 'application/json', 'Content-Type' => 'application/json; charset=utf-8', - 'Content-Encoding' => 'gzip', + 'Content-Encoding' => 'gzip' } request = Net::HTTP::Post.new(uri.path, headers) From bb76904a11a5e6d4aace13f50d9e8dfc219f32f0 Mon Sep 17 00:00:00 2001 From: Ganga Mahesh Siddem Date: Thu, 21 May 2020 10:56:58 -0700 Subject: [PATCH 6/6] use ai endpoint if not passed in --- lib/application_insights/channel/asynchronous_sender.rb | 4 ++++ lib/application_insights/channel/synchronous_sender.rb | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/application_insights/channel/asynchronous_sender.rb b/lib/application_insights/channel/asynchronous_sender.rb index 25b63ef..4786aa1 100644 --- a/lib/application_insights/channel/asynchronous_sender.rb +++ b/lib/application_insights/channel/asynchronous_sender.rb @@ -23,6 +23,10 @@ class AsynchronousSender < SenderBase # @param [Hash] proxy server configuration to send (optional) # telemetry data to. def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI, proxy = {}) + # callers which requires proxy dont require to maintain service endpoint uri which potentially can change + if service_endpoint_uri.nil? || service_endpoint_uri.empty? + service_endpoint_uri = SERVICE_ENDPOINT_URI + end @send_interval = 1.0 @send_remaining_time = 0 @send_time = 3.0 diff --git a/lib/application_insights/channel/synchronous_sender.rb b/lib/application_insights/channel/synchronous_sender.rb index 4b5ca09..7bf8f8a 100644 --- a/lib/application_insights/channel/synchronous_sender.rb +++ b/lib/application_insights/channel/synchronous_sender.rb @@ -5,12 +5,16 @@ module Channel # A synchronous sender that works in conjunction with the {SynchronousQueue}. # The queue will call {#send} on the current instance with the data to send. class SynchronousSender < SenderBase - SERVICE_ENDPOINT_URI = 'https://dc.services.visualstudio.com/v2/track' + SERVICE_ENDPOINT_URI = "https://dc.services.visualstudio.com/v2/track" # Initializes a new instance of the class. # @param [String] service_endpoint_uri the address of the service to send # @param [Hash] proxy server configuration to send (optional) # telemetry data to. def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI, proxy = {}) + # callers which requires proxy dont require to maintain service endpoint uri which potentially can change + if service_endpoint_uri.nil? || service_endpoint_uri.empty? + service_endpoint_uri = SERVICE_ENDPOINT_URI + end super service_endpoint_uri, proxy end end