diff --git a/lib/application_insights/channel/contracts/reopenings.rb b/lib/application_insights/channel/contracts/reopenings.rb index 394bf8a..8581530 100644 --- a/lib/application_insights/channel/contracts/reopenings.rb +++ b/lib/application_insights/channel/contracts/reopenings.rb @@ -23,5 +23,17 @@ def http_method=(http_method) @properties["httpMethod"] = http_method end end + + def client_ip + @properties["clientIp"] if @properties + end + + def client_ip=(client_ip) + if client_ip + @properties ||= {} + @properties["clientIp"] = client_ip + end + end + end end \ No newline at end of file diff --git a/lib/application_insights/rack/track_request.rb b/lib/application_insights/rack/track_request.rb index 62c2b08..1361306 100644 --- a/lib/application_insights/rack/track_request.rb +++ b/lib/application_insights/rack/track_request.rb @@ -15,11 +15,12 @@ class TrackRequest # send to Application Insights when buffer is full. # @param [Fixnum] send_interval the frequency (in seconds) to check buffer # and send buffered requests to Application Insights if any. - def initialize(app, instrumentation_key, buffer_size = 500, send_interval = 60) + def initialize(app, instrumentation_key, buffer_size = 500, send_interval = 60, store_ip = false) @app = app @instrumentation_key = instrumentation_key @buffer_size = buffer_size @send_interval = send_interval + @store_ip = store_ip @sender = Channel::AsynchronousSender.new @sender.send_interval = @send_interval @@ -119,11 +120,13 @@ def operation_id(id) end def options_hash(request) - { + options = { name: "#{request.request_method} #{request.path}", http_method: request.request_method, url: request.url } + options[:client_ip] = request.ip if @store_ip + options end def request_data(request_id, start_time, duration, status, success, options) @@ -137,7 +140,8 @@ def request_data(request_id, start_time, duration, status, success, options) :properties => options[:properties] || {}, :measurements => options[:measurements] || {}, # Must initialize http_method after properties because it's actually stored in properties - :http_method => options[:http_method] + :http_method => options[:http_method], + :client_ip => options[:client_ip] ) end diff --git a/test/application_insights/rack/test_track_request.rb b/test/application_insights/rack/test_track_request.rb index 9771efc..cb24e31 100644 --- a/test/application_insights/rack/test_track_request.rb +++ b/test/application_insights/rack/test_track_request.rb @@ -43,6 +43,32 @@ def test_call_works_as_expected assert Time.parse(payload[0].time) - start_time < 0.01 end + def test_call_with_ip + response_code = rand(200..204) + app = Proc.new {|env| sleep(2.5); [response_code, {"Content-Type" => "text/html"}, ["Hello Rack!"]]} + url = "http://localhost:8080/foo?a=b" + ip = "1.1.1.1" + http_method = 'PUT' + env = Rack::MockRequest.env_for(url, :method => http_method, "REMOTE_ADDR" => ip) + instrumentation_key = 'key' + sender = MockAsynchronousSender.new + track_request = TrackRequest.new app, instrumentation_key, 500, 1, true + track_request.send(:sender=, sender) + start_time = Time.now + + SecureRandom.expects(:base64).with(10).returns('y0NM2eOY/fnQPw==') + result = track_request.call(env) + + app_result = app.call(env) + assert_equal app_result, result + sleep(sender.send_interval) + + payload = sender.buffer[0] + request_data = payload[0].data.base_data + + assert_equal request_data.properties['clientIp'], ip + end + def test_call_with_failed_request response_code = rand(400..600) app = Proc.new {|env| [response_code, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}