Giter Club home page Giter Club logo

applicationinsights-ruby's Introduction

Application Insights SDK for Ruby

Gem Version Build Status

Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write. -- Ruby - Official Site

This project extends the Application Insights API surface to support Ruby. Application Insights is a service that allows developers to keep their application available, performing and succeeding. This Ruby gem will allow you to send telemetry of various kinds (event, trace, exception, etc.) to the Application Insights service where they can be visualized in the Azure Portal.

Status

This SDK is NOT maintained or supported by Microsoft even though we've contributed to it in the past. Note that Azure Monitor only provides support when using the supported SDKs. We’re constantly assessing opportunities to expand our support for other languages, so follow our GitHub Announcements page to receive the latest SDK news.

Requirements

Ruby 1.9.3 and above are currently supported by this gem.

Installation

To install the latest release you can use gem.

$ gem install application_insights

Usage

Once installed, you can send telemetry to Application Insights. Here are a few samples.

Note: before you can send data to you will need an instrumentation key. Please see the Getting an Application Insights Instrumentation Key section for more information.

Sending a simple event telemetry item

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
tc.track_event 'My event'
tc.flush

Sending an event telemetry item with custom properties and measurements

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
tc.track_event 'My event', :properties => { 'custom property' => 'some value' }, :measurements => { 'custom metric' => 13 }
tc.flush

Sending a trace telemetry item with custom properties

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
tc.track_trace 'My trace statement', ApplicationInsights::Channel::Contracts::SeverityLevel::INFORMATION, :properties => { 'custom property' => 'some value' }
tc.flush

Sending a metric telemetry item (without and with optional values)

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
tc.track_metric 'My metric', 42
# with all optional values set
tc.track_metric 'My metric', 42, :kind => ApplicationInsights::Channel::Contracts::DataPointType::AGGREGATION, :count => 3, :min => 1, :max => 100, :std_dev => 10, :properties => { 'custom property' => 'some value' }
tc.flush

Sending an exception telemetry item with custom properties and measurements

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
begin
  raise ArgumentError, 'Something has gone wrong!'
rescue => e
  tc.track_exception e
end
tc.flush

Configuring context for a telemetry client instance

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
tc.context.application.ver = '1.2.3'
tc.context.device.id = 'My current device'
tc.context.device.oem_name = 'Asus'
tc.context.device.model = 'X31A'
tc.context.device.type = "Other"
tc.context.user.id = '[email protected]'
tc.track_trace 'My trace with context'
tc.flush

Configuring synchronous (default) channel properties

require 'application_insights'
tc = ApplicationInsights::TelemetryClient.new
# flush telemetry if we have 10 or more telemetry items in our queue
tc.channel.queue.max_queue_length = 10
# send telemetry to the service in batches of 5
tc.channel.sender.send_buffer_size = 5

Configuring an asynchronous channel instead of the synchronous default

require 'application_insights'
sender = ApplicationInsights::Channel::AsynchronousSender.new
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>', 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'

Configuring asynchronous channel properties

require 'application_insights'
sender = ApplicationInsights::Channel::AsynchronousSender.new
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>', channel
# flush telemetry if we have 10 or more telemetry items in our queue
tc.channel.queue.max_queue_length = 10
# send telemetry to the service in batches of 5
tc.channel.sender.send_buffer_size = 5
# the background worker thread will be active for 5 seconds before it shuts down. if
# during this time items are picked up from the queue, the timer is reset.
tc.channel.sender.send_time = 5
# the background worker thread will poll the queue every 0.5 seconds for new items
tc.channel.sender.send_interval = 0.5

Collecting unhandled exceptions

require 'application_insights'
# setup unhandled exception handler
ApplicationInsights::UnhandledException.collect('<YOUR INSTRUMENTATION KEY GOES HERE>')
# raise an exception and this would be send to Application Insights Service
raise Exception, 'Boom!'

Collecting requests for rack applications

# set up the TrackRequest middleware in the rackup (config.ru) file
require 'application_insights'
use ApplicationInsights::Rack::TrackRequest, '<YOUR INSTRUMENTATION KEY GOES HERE>', <buffer size>
# For rails, suggest to set up this middleware in application.rb so that unhandled exceptions from controllers are also collected
config.middleware.use 'ApplicationInsights::Rack::TrackRequest', '<YOUR INSTRUMENTATION KEY GOES HERE>', <buffer size>

Rerieving the Request-Id value from ApplicationInsights

# from time to time you may need to access a request's id from within your app
application_insights_request_id = request.env['ApplicationInsights.request.id']

# this can be used for a number of different purposes, including telemetry correlation
uri = URI('http://api.example.com/search/?q=test')

req = Net::HTTP::Get.new(uri)
req['Request-Id'] = "#{application_insights_request_id}1" if application_insights_request_id

Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) }

applicationinsights-ruby's People

Contributors

aaronpatterson avatar dmitry-matveev avatar dnduffy avatar emancu avatar joshk avatar lukekim avatar mattmccleary avatar mattrayner avatar satoryu avatar sergeykanzhelev avatar soph avatar tobyndockerill avatar yantang-msft avatar yoonjishin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

applicationinsights-ruby's Issues

Mongoid model named Channel is overriden by Channel module

For some reason, once requiring this gem, I get the following error message when server boots

WARN -- : Channel is not a class

Channel is defined for me as a model in the models folder.

for some reason module from this gem overrides my class definition.

Add logging to the TrackRequest middleware

The Problem

When debugging a Ruby application by reviewing logs after the fact, it would be useful to know the ApplicationInsights Request-Id for further investigation.

Proposed Solution

It would be good to add logging both before a request is executed, and after a request is completed - noting the Request-Id value as mentioned in the examples here:

https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/HierarchicalRequestId.md#example

This would allow a user to know from application logs, what the ApplicationInsights ID is for a potentially problematic request

Rails logs

Anyway to configure a Rails application's logs to automatically go to application insights?

Bug: OpenSSL Error for `tc.flush`

When attempting to execute the sample code in the README I run into an OpenSSL error (copied below.) I noticed that this only occurred when tc.flush was called.

Upon further investigation I found that the openssl library wasn't required in the sender_base.rb file. adding require 'openssl' resolved the issue for me.

/Users/dkullmann/.rvm/gems/ruby-2.1.3/gems/application_insights-0.5.0/lib/application_insights/channel/sender_base.rb:54:in `send': uninitialized constant ApplicationInsights::Channel::SenderBase::OpenSSL (NameError)
    from /Users/dkullmann/.rvm/gems/ruby-2.1.3/gems/application_insights-0.5.0/lib/application_insights/channel/synchronous_queue.rb:34:in `flush'
    from /Users/dkullmann/.rvm/gems/ruby-2.1.3/gems/application_insights-0.5.0/lib/application_insights/channel/telemetry_channel.rb:47:in `flush'
    from /Users/dkullmann/.rvm/gems/ruby-2.1.3/gems/application_insights-0.5.0/lib/application_insights/telemetry_client.rb:214:in `flush'
    from test.rb:4:in `<main>'

Here is a link to line 54 where the error is from.

Add a CI service

Given it is an open source project, is very important to see the status build.
Adding a simple badge and a free CI service would be enough

Open to external contributions?

Hi,
I was wondering what the current roadmap for this gem is?

Are you open to some external contributions/suggestions for features?

Thanks,
Matt

Format of the request duration TimeSpan in Rack middleware is incorrect

Recently, a typo in the description of the RequestData duration string has been fixed in the Application Insights API. Unfortunately, the Rack 'TrackRequest' middleware sends incorrectly formatted requests, because the format_request_duration method still uses the incorrect format d:hh:mm:ss.fffffff, whereas it should be d.h:mm:ss.fffffff (the 'days' portion of the duration string needs to be separated with a dot, not a colon).

Related pull request: #19

Release date for 0.5.7

We're using this gem and everything's going well but we'd like to use the ApplicationInsights::Rack::InjectJavaScriptTracking middleware, ideally without adding the Github repo to our gemfile.

Is there a scheduled release date for 0.5.7?

undefined method `new' for "ApplicationInsights::Rack::TrackRequest":String when starting server or sidekiq on Rails 5.2

Just updated my Rails app from 5.0 -> 5.2 and now I cant start the rails server.

/Users/dmevans/.rvm/gems/ruby-2.4.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/stack.rb:37:in `build': undefined method `new' for "ApplicationInsights::Rack::TrackRequest":String (NoMethodError)
Did you mean?  next
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/stack.rb:101:in `block in build'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/stack.rb:101:in `each'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/stack.rb:101:in `inject'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/stack.rb:101:in `build'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/scout_apm-2.4.24/lib/scout_apm/instruments/middleware_summary.rb:31:in `build_with_scout_instruments'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/engine.rb:510:in `block in app'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/engine.rb:506:in `synchronize'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/engine.rb:506:in `app'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/application/finisher.rb:47:in `block in <module:Finisher>'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/initializable.rb:32:in `instance_exec'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/initializable.rb:32:in `run'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/initializable.rb:61:in `block in run_initializers'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:228:in `block in tsort_each'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:431:in `each_strongly_connected_component_from'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:349:in `block in each_strongly_connected_component'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:347:in `each'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:347:in `call'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:347:in `each_strongly_connected_component'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:226:in `tsort_each'
	from /Users/dmevans/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/tsort.rb:205:in `tsort_each'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/initializable.rb:60:in `run_initializers'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/application.rb:361:in `initialize!'
	from /Users/dmevans/Repos/Bookly/config/environment.rb:5:in `<main>'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `block in require'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:257:in `load_dependency'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
	from config.ru:24:in `block in <main>'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/builder.rb:55:in `instance_eval'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/builder.rb:55:in `initialize'
	from config.ru:in `new'
	from config.ru:in `<main>'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/builder.rb:49:in `eval'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/builder.rb:49:in `new_from_string'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/builder.rb:40:in `parse_file'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/server.rb:319:in `build_app_and_options_from_config'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/server.rb:219:in `app'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands/server/server_command.rb:27:in `app'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/rack-2.0.7/lib/rack/server.rb:354:in `wrapped_app'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands/server/server_command.rb:89:in `log_to_stdout'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands/server/server_command.rb:51:in `start'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands/server/server_command.rb:147:in `block in perform'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands/server/server_command.rb:142:in `tap'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands/server/server_command.rb:142:in `perform'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/thor-0.19.4/lib/thor/command.rb:27:in `run'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/thor-0.19.4/lib/thor/invocation.rb:126:in `invoke_command'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/thor-0.19.4/lib/thor.rb:369:in `dispatch'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/command/base.rb:65:in `perform'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/command.rb:46:in `invoke'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/railties-5.2.3/lib/rails/commands.rb:18:in `<main>'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/bootsnap-1.4.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `block in require'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:257:in `load_dependency'
	from /Users/dmevans/.rvm/gems/ruby-2.4.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
	from bin/rails:4:in `<main>'

Success always false in TelemetryClient.track_request?

Hi folks,

I noticed a little oddity while overriding code from telemetry_client.rb.

The ternary operator (full snippet below) seems to use = rather than == and so it seems like success will always be false.
:success => success = nil ? true : success,

telemetry_client.rb

def track_request(id, start_time, duration, response_code, success, options={})
  data = Channel::Contracts::RequestData.new(
    :success => success = nil ? true : success,
    # etc ...
  )

  self.channel.write(data, self.context)
end

Error in documentation (?)

I think there is an error in the [Documentation/README](tc = ApplicationInsights::TelemetryClient.new(config['ai_instrumentation_key'])
tc.context.application.id = SERVICE_NAME), where it instructs users to do the following:

tc = ApplicationInsights::TelemetryClient.new my_ai_key
tc.context.application.id = 'My App id'   # <-- this line is problematic

I get an error when I do this, as id is not a member of the Applications class, as we can see in the source code here. Is it not supported to associate an id with an application object directly?

Output full stack trace when async sender dies

I'm using this gem in conjunction with the fluentd-plugin-application-insights gem. However, when trying to use this in a fluentd DaemonSet on Kubernetes, I get this:

E, [2019-07-19T21:18:07.752463 #20580] ERROR -- application_insights: Asynchronous sender work thread terminated abnormally: "\x92" from ASCII-8BIT to UTF-8

The problem is... that doesn't tell me where in the 50-ish line send block this is happening. I can't fix it because I can't figure out the actual source of the error.

I found the line where this is getting thrown but it would be more helpful to provide an actual stack trace of the source of the issue (maybe in debug-level logging if you don't want it in the default error message) so things can be traced down.

Since I can only see this replicated in a mixed Linux/Windows AKS cluster, right now the only way I can troubleshoot it is to fork both this gem and the fluentd-plugin-application-insights gem, add the logging I need, then update a custom Docker image to use those. (Sorta painful. Not impossible, but definitely some work that could be saved with some better logging.)

Unable to set role_name and role_instance

Hi there,

Could someone explain me how to set role_name and role_instance?
I've set like this:
sender = ApplicationInsights::Channel::AsynchronousSender.new
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
tc = ApplicationInsights::TelemetryClient.new 'key', channel
tc.context.cloud.role_name = 'Sample Name'
tc.context.cloud.role_instance = 'Sample Instance'

But role_name and role_instance dont appear on Application Insights Dashboard > Application Map

Refactor Contracts

I know there is not too much logic in this objects, actually they are very simple. The thing is the objects are simpler than the code written and I have a refactor in mind that will help a lot to the simplicity and easiness of code maintenance.

I don't know if you are already working on a refactor of those objects, but I'll try to send a PR tonight so I can start contributing to this gem and you can start reviewing it. I'll be looking forward to see your feedback on the PR.

Also, I'm available to pair program with any of you if you think it is necessary.

Build failure

travis build fails with this error:

Using application_insights 0.5.4 from source at `.`
Using bundler 1.16.1
Fetching power_assert 1.1.1
Installing power_assert 1.1.1
Fetching rack 2.0.5
Installing rack 2.0.5
Gem::RuntimeRequirementNotMetError: rack requires Ruby version >= 2.2.2. The
current ruby version is 1.9.1.
An error occurred while installing rack (2.0.5), and Bundler cannot

Bug: NoMethodError: undefined method `[]' for nil:NilClass

The track_exception method of TelemetryClient fails when the regexp won't match.

Look at the code

Exception:

NoMethodError: undefined method `[]' for nil:NilClass
    /srv/apps/ui-annotator/gems/gems/application_insights-0.5.1/lib/application_insights/telemetry_client.rb:78:in `block in track_exception'
    /srv/apps/ui-annotator/gems/gems/application_insights-0.5.1/lib/application_insights/telemetry_client.rb:74:in `each'
    /srv/apps/ui-annotator/gems/gems/application_insights-0.5.1/lib/application_insights/telemetry_client.rb:74:in `track_exception'
    /srv/apps/ui-annotator/gems/gems/application_insights-0.5.1/lib/application_insights/rack/track_request.rb:57:in `call'
    /srv/apps/ui-annotator/gems/gems/appinsights-0.0.5/lib/appinsights/middlewares/exception_handling.rb:10:in `call'
    /srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:75:in `call'
    /var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/lint.rb:49:in `_call'
    /var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/lint.rb:37:in `call'
    /var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/showexceptions.rb:24:in `call'
    /var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/commonlogger.rb:33:in `call'
    /var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/loader.rb:86:in `proceed_as_child'
    /var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/loader.rb:31:in `call!'
    /var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/loader.rb:18:in `call'
    /var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/favicon.rb:12:in `call'
    /var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/static.rb:14:in `call'
    /var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/builder.rb:153:in `call'
    /var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/handler/webrick.rb:89:in `service'
    /usr/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'
    /usr/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'
    /usr/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'

The regexp doesn't match because this line:

pry> match
=> "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:-6:in `instance_eval'"

Full backtrace

pry> exception.backtrace
=> ["/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:36:in `[]'",
 "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:36:in `block (2 levels) in singleton class'",
 "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:35:in `each'",
 "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:35:in `block in singleton class'",
 "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:-6:in `instance_eval'",
 "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:-6:in `singleton class'",
 "/srv/apps/ui-annotator/current/webapp/views/admin.html.erb:-8:in `__tilt_16978360'",
 "/srv/apps/ui-annotator/gems/gems/tilt-2.0.1/lib/tilt/template.rb:155:in `call'",
 "/srv/apps/ui-annotator/gems/gems/tilt-2.0.1/lib/tilt/template.rb:155:in `evaluate'",
 "/srv/apps/ui-annotator/gems/gems/tilt-2.0.1/lib/tilt/template.rb:96:in `render'",
 "/srv/apps/ui-annotator/gems/gems/armadillo-0.0.5/lib/armadillo.rb:170:in `_render'",
 "/srv/apps/ui-annotator/gems/gems/armadillo-0.0.5/lib/armadillo.rb:146:in `render'",
 "/srv/apps/ui-annotator/current/webapp/helpers.rb:32:in `render'",
 "/srv/apps/ui-annotator/current/webapp/helpers.rb:44:in `render_view'",
 "/srv/apps/ui-annotator/current/webapp/routes/admin.rb:17:in `block (2 levels) in <class:Admin>'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:181:in `block in on'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:192:in `try'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:162:in `on'",
 "/srv/apps/ui-annotator/current/webapp/routes/admin.rb:13:in `block in <class:Admin>'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:128:in `instance_eval'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:128:in `block in call!'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:127:in `catch'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:127:in `call!'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:112:in `call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/auth/basic.rb:25:in `call'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:75:in `call'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:328:in `run'",
 "/srv/apps/ui-annotator/current/webapp/app.rb:31:in `block (2 levels) in <top (required)>'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:181:in `block in on'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:192:in `try'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:162:in `on'",
 "/srv/apps/ui-annotator/current/webapp/app.rb:30:in `block in <top (required)>'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:128:in `instance_eval'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:128:in `block in call!'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:127:in `catch'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:127:in `call!'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:112:in `call'",
 "/srv/apps/ui-annotator/gems/gems/application_insights-0.5.1/lib/application_insights/rack/track_request.rb:28:in `call'",
 "/srv/apps/ui-annotator/gems/gems/appinsights-0.0.5/lib/appinsights/middlewares/exception_handling.rb:10:in `call'",
 "/srv/apps/ui-annotator/gems/gems/cuba-3.1.1/lib/cuba.rb:75:in `call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/lint.rb:49:in `_call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/lint.rb:37:in `call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/showexceptions.rb:24:in `call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/commonlogger.rb:33:in `call'",
 "/var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/loader.rb:86:in `proceed_as_child'",
 "/var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/loader.rb:31:in `call!'",
 "/var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/loader.rb:18:in `call'",
 "/var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/favicon.rb:12:in `call'",
 "/var/lib/gems/2.1.0/gems/shotgun-0.9/lib/shotgun/static.rb:14:in `call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/builder.rb:153:in `call'",
 "/var/lib/gems/2.1.0/gems/rack-1.6.0/lib/rack/handler/webrick.rb:89:in `service'",
 "/usr/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'",
 "/usr/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'",
 "/usr/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'"]

Test suite sporadically fails with `test_asynchronous_queue.rb:44`

Whilst working on #48 I've noticed that you have a sporadic test failure (appears roughly one in 10 times for me)

Stack trace

================================================================================================================================================
Error: test_flush_works_as_expected(TestAsynchronousQueue)
:
  fatal: No live threads left. Deadlock?
  1 threads, 1 sleeps current:0x00007ff7cd7b8930 main thread:0x00007ff7cbc0c4b0
  * #<Thread:0x00007ff7cc081c60 sleep_forever>
     rb_thread_t:0x00007ff7cbc0c4b0 native:0x00007fff928ab380 int:1
     /Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:61:in `sleep'
     /Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:61:in `wait'
     /Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:61:in `block in wait'
     /Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:60:in `synchronize'
     /Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:60:in `wait'
     /Users/mattrayner/projects/ApplicationInsights-Ruby/test/application_insights/channel/test_asynchronous_queue.rb:44:in `test_flush_works_as_expected'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/testcase.rb:697:in `run_test'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/testcase.rb:437:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/testsuite.rb:121:in `run_test'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/testsuite.rb:53:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/testsuite.rb:121:in `run_test'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/testsuite.rb:53:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunnermediator.rb:65:in `run_suite'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunnermediator.rb:44:in `block in run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunnermediator.rb:100:in `with_listener'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunnermediator.rb:40:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunner.rb:40:in `start_mediator'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunner.rb:25:in `start'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/ui/testrunnerutilities.rb:24:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/autorunner.rb:403:in `block in run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/autorunner.rb:459:in `change_work_directory'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/autorunner.rb:402:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit/autorunner.rb:59:in `run'
     /Users/mattrayner/.rvm/gems/ruby-2.5.1/gems/test-unit-3.0.9/lib/test/unit.rb:502:in `block (2 levels) in <top (required)>'
/Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:61:in `sleep'
/Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:61:in `wait'
/Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:61:in `block in wait'
/Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:60:in `synchronize'
/Users/mattrayner/projects/ApplicationInsights-Ruby/lib/application_insights/channel/event.rb:60:in `wait'
/Users/mattrayner/projects/ApplicationInsights-Ruby/test/application_insights/channel/test_asynchronous_queue.rb:44:in `test_flush_works_as_expected'
     41:     assert_equal false, result
     42:     queue.flush
     43:     assert_equal 1, sender.start_call_count
  => 44:     result = queue.flush_notification.wait
     45:     assert_equal true, result
     46:   end
     47: end
================================================================================================================================================

I'm going to have a go at investigating, but wanted to raise it early

When using `ApplicationInsights::Rack::TrackRequest`, expose a request's ID

The Problem

At @ukparliament, we have a number of components which use ApplicationInsights for logging. To help with analytics and monitoring, we'd like to implement hierarchical request IDs as detailed here:

https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/HierarchicalRequestId.md#example

Proposed Solution

I propose modifying ApplicationInsights::Rack::TrackRequest#call so that id generation on line 47: track_request.rb#L47

Is moved to the top of the method, and that the id is exposed to the application via the env hash.

An example could be something like:

      # Track requests and send data to Application Insights asynchronously.
      # @param [Hash] env the rack environment.
      def call(env)
        id = rand(16**32).to_s(16)
        env['ApplicationInsight.Request.Id'] = id
        start = Time.now
        begin
          status, headers, response = @app.call(env)
        rescue Exception => ex
          status = 500
        
        # Clipped for brevity

        request = ::Rack::Request.new env
        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

        # Clipped for brevity

      end

This would enable something like the following from within the application:

uri = URI('http://api.example.com/search/?q=test')

req = Net::HTTP::Get.new(uri)
req['Request-Id'] = "|#{env['ApplicationInsight.Request.Id']}." if env['ApplicationInsight.Request.Id']

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}

I'd love to know what your opinion is on this?

Different SERVICE_ENDPOINT_URI for Azure china

Hi everyone,

we're experiencing the error message

WARN -- application_insights: Failed to send data: Invalid instrumentation key

for our application insights setup in https://portal.azure.cn/ (only our china setup is effected). We double checked the instrumentation key and it is certainly correct.

Is it possible that the SERVICE_ENDPOINT_URI defined here is different for Azure China?

If not, do you have another idea what could result in this error message?

Thanks in advance,
Dennis

Edit 1:
There seem to be several other URLs:
https://docs.microsoft.com/en-us/azure/azure-monitor/app/custom-endpoints#regions-that-require-endpoint-modification
Could you point me to the correct one?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.