From 931c835cde963ac5f4f46aa181450d264f336484 Mon Sep 17 00:00:00 2001 From: "Jing Li (AI)" Date: Sat, 7 Feb 2015 23:40:10 -0800 Subject: [PATCH] Fix auto loading TrackRequest middleware --- lib/application_insights.rb | 6 +- .../rack/track_request.rb | 137 +++++++++--------- lib/application_insights/telemetry_client.rb | 2 +- .../rack/test_track_request.rb | 2 +- 4 files changed, 76 insertions(+), 71 deletions(-) diff --git a/lib/application_insights.rb b/lib/application_insights.rb index 6523341..eefc7e7 100644 --- a/lib/application_insights.rb +++ b/lib/application_insights.rb @@ -2,4 +2,8 @@ require_relative 'application_insights/telemetry_client' require_relative 'application_insights/unhandled_exception' require_relative 'application_insights/version' -autoload :TrackRequest, "application_insights/rack/track_request" \ No newline at end of file +module ApplicationInsights + module Rack + autoload :TrackRequest, "application_insights/rack/track_request" + end +end diff --git a/lib/application_insights/rack/track_request.rb b/lib/application_insights/rack/track_request.rb index 1bf11cc..b5803c2 100644 --- a/lib/application_insights/rack/track_request.rb +++ b/lib/application_insights/rack/track_request.rb @@ -1,83 +1,84 @@ require 'rack' -require 'securerandom' require_relative '../channel/contracts/request_data' require_relative '../telemetry_client' module ApplicationInsights - # Track every request and sends the request data to Application Insights. - class TrackRequest - # Initializes a new instance of the class. - # @param [Object] app the inner rack application. - # @param [String] instrumentation_key to identify which Application Insights application this data is for. - # @param [Fixnum] buffer_size the buffer size and the buffered requests would 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) - @app = app - @instrumentation_key = instrumentation_key - @buffer_size = buffer_size - @send_interval = send_interval - end - - # Track requests and send data to Application Insights asynchronously. - # @param [Hash] env the rack environment. - def call(env) - start = Time.now - begin - status, headers, response = @app.call(env) - rescue Exception => ex - status = 500 - exception = ex - end - stop = Time.now - - if !@client - sender = @sender || Channel::AsynchronousSender.new - sender.send_interval = @send_interval - queue = Channel::AsynchronousQueue.new sender - queue.max_queue_length = @buffer_size - channel = Channel::TelemetryChannel.new nil, queue - @client = TelemetryClient.new @instrumentation_key, channel + module Rack + # Track every request and sends the request data to Application Insights. + class TrackRequest + # Initializes a new instance of the class. + # @param [Object] app the inner rack application. + # @param [String] instrumentation_key to identify which Application Insights application this data is for. + # @param [Fixnum] buffer_size the buffer size and the buffered requests would 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) + @app = app + @instrumentation_key = instrumentation_key + @buffer_size = buffer_size + @send_interval = send_interval end - request = Rack::Request.new env - id = rand(16**32).to_s(16) - start_time = start.iso8601(7) - duration = format_request_duration(stop - start) - success = status.to_i < 400 - options = { - :name => "#{request.request_method} #{request.path}", - :http_method => request.request_method, - :url => request.url - } - @client.track_request id, start_time, duration, status, success, options + # Track requests and send data to Application Insights asynchronously. + # @param [Hash] env the rack environment. + def call(env) + start = Time.now + begin + status, headers, response = @app.call(env) + rescue Exception => ex + status = 500 + exception = ex + end + stop = Time.now - if exception == nil - [status, headers, response] - elsif - @client.track_exception exception, handled_at: 'Unhandled' - raise exception - end - end + if !@client + sender = @sender || Channel::AsynchronousSender.new + sender.send_interval = @send_interval + queue = Channel::AsynchronousQueue.new sender + queue.max_queue_length = @buffer_size + channel = Channel::TelemetryChannel.new nil, queue + @client = TelemetryClient.new @instrumentation_key, channel + end - private + request = ::Rack::Request.new env + id = rand(16**32).to_s(16) + start_time = start.iso8601(7) + duration = format_request_duration(stop - start) + success = status.to_i < 400 + options = { + :name => "#{request.request_method} #{request.path}", + :http_method => request.request_method, + :url => request.url + } + @client.track_request id, start_time, duration, status, success, options - def sender=(sender) - @sender = sender if sender.is_a? Channel::AsynchronousSender - end - - def client - @client - end - - def format_request_duration(duration_seconds) - if duration_seconds >= 86400 - # just return 1 day when it takes more than 1 day which should not happen for requests. - return "%d:%02d:%02d:%02d.%07d" % [1, 0, 0, 0, 0] + if exception == nil + [status, headers, response] + elsif + @client.track_exception exception, handled_at: 'Unhandled' + raise exception + end end - Time.at(duration_seconds).gmtime.strftime("0:%H:%M:%S.%7N") + private + + def sender=(sender) + @sender = sender if sender.is_a? Channel::AsynchronousSender + end + + def client + @client + end + + def format_request_duration(duration_seconds) + if duration_seconds >= 86400 + # just return 1 day when it takes more than 1 day which should not happen for requests. + return "%d:%02d:%02d:%02d.%07d" % [1, 0, 0, 0, 0] + end + + Time.at(duration_seconds).gmtime.strftime("0:%H:%M:%S.%7N") + end end end end \ No newline at end of file diff --git a/lib/application_insights/telemetry_client.rb b/lib/application_insights/telemetry_client.rb index 29fc3bd..6024f9c 100644 --- a/lib/application_insights/telemetry_client.rb +++ b/lib/application_insights/telemetry_client.rb @@ -167,7 +167,7 @@ module ApplicationInsights # @param [Hash] options the options to create the {Channel::Contracts::EventData} object. # @option options [Hash] :properties the set of custom properties the client wants attached to this # data item. (defaults to: {}) - def track_trace(name, severity_level = nil, options={}) + def track_trace(name, severity_level = Channel::Contracts::SeverityLevel::INFORMATION, options={}) data_attributes = { :message => name || 'Null', :severity_level => severity_level || Channel::Contracts::SeverityLevel::INFORMATION, diff --git a/test/application_insights/rack/test_track_request.rb b/test/application_insights/rack/test_track_request.rb index 680c216..d1670d1 100644 --- a/test/application_insights/rack/test_track_request.rb +++ b/test/application_insights/rack/test_track_request.rb @@ -3,7 +3,7 @@ require 'rack/mock' require_relative '../mock_sender' require_relative '../../../lib/application_insights/rack/track_request' -include ApplicationInsights +include ApplicationInsights::Rack class TestTrackRequest < Test::Unit::TestCase def test_call_works_as_expected