azure_application_insights 0.5.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +34 -0
- data/.gitignore +40 -0
- data/.travis.yml +22 -0
- data/CHANGELOG.md +17 -0
- data/CONTRIBUTING.md +68 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +11 -0
- data/README.md +161 -0
- data/Rakefile +15 -0
- data/application_insights.gemspec +30 -0
- data/lib/application_insights/channel/asynchronous_queue.rb +58 -0
- data/lib/application_insights/channel/asynchronous_sender.rb +133 -0
- data/lib/application_insights/channel/contracts/application.rb +14 -0
- data/lib/application_insights/channel/contracts/cloud.rb +14 -0
- data/lib/application_insights/channel/contracts/data.rb +14 -0
- data/lib/application_insights/channel/contracts/data_point.rb +24 -0
- data/lib/application_insights/channel/contracts/data_point_type.rb +7 -0
- data/lib/application_insights/channel/contracts/dependency_kind.rb +9 -0
- data/lib/application_insights/channel/contracts/dependency_source_type.rb +9 -0
- data/lib/application_insights/channel/contracts/device.rb +28 -0
- data/lib/application_insights/channel/contracts/envelope.rb +40 -0
- data/lib/application_insights/channel/contracts/event_data.rb +28 -0
- data/lib/application_insights/channel/contracts/exception_data.rb +37 -0
- data/lib/application_insights/channel/contracts/exception_details.rb +28 -0
- data/lib/application_insights/channel/contracts/internal.rb +14 -0
- data/lib/application_insights/channel/contracts/json_serializable.rb +59 -0
- data/lib/application_insights/channel/contracts/location.rb +16 -0
- data/lib/application_insights/channel/contracts/message_data.rb +24 -0
- data/lib/application_insights/channel/contracts/metric_data.rb +27 -0
- data/lib/application_insights/channel/contracts/operation.rb +19 -0
- data/lib/application_insights/channel/contracts/page_view_data.rb +30 -0
- data/lib/application_insights/channel/contracts/remote_dependency_data.rb +56 -0
- data/lib/application_insights/channel/contracts/request_data.rb +36 -0
- data/lib/application_insights/channel/contracts/session.rb +15 -0
- data/lib/application_insights/channel/contracts/severity_level.rb +13 -0
- data/lib/application_insights/channel/contracts/stack_frame.rb +17 -0
- data/lib/application_insights/channel/contracts/user.rb +19 -0
- data/lib/application_insights/channel/event.rb +68 -0
- data/lib/application_insights/channel/queue_base.rb +73 -0
- data/lib/application_insights/channel/sender_base.rb +88 -0
- data/lib/application_insights/channel/synchronous_queue.rb +45 -0
- data/lib/application_insights/channel/synchronous_sender.rb +17 -0
- data/lib/application_insights/channel/telemetry_channel.rb +131 -0
- data/lib/application_insights/channel/telemetry_context.rb +85 -0
- data/lib/application_insights/rack/track_request.rb +158 -0
- data/lib/application_insights/telemetry_client.rb +229 -0
- data/lib/application_insights/unhandled_exception.rb +49 -0
- data/lib/application_insights/version.rb +3 -0
- data/lib/application_insights.rb +9 -0
- data/test/application_insights/channel/contracts/test_application.rb +44 -0
- data/test/application_insights/channel/contracts/test_cloud.rb +44 -0
- data/test/application_insights/channel/contracts/test_data.rb +44 -0
- data/test/application_insights/channel/contracts/test_data_point.rb +109 -0
- data/test/application_insights/channel/contracts/test_device.rb +200 -0
- data/test/application_insights/channel/contracts/test_envelope.rb +209 -0
- data/test/application_insights/channel/contracts/test_event_data.rb +62 -0
- data/test/application_insights/channel/contracts/test_exception_data.rb +111 -0
- data/test/application_insights/channel/contracts/test_exception_details.rb +106 -0
- data/test/application_insights/channel/contracts/test_internal.rb +44 -0
- data/test/application_insights/channel/contracts/test_location.rb +70 -0
- data/test/application_insights/channel/contracts/test_message_data.rb +66 -0
- data/test/application_insights/channel/contracts/test_metric_data.rb +50 -0
- data/test/application_insights/channel/contracts/test_operation.rb +109 -0
- data/test/application_insights/channel/contracts/test_page_view_data.rb +88 -0
- data/test/application_insights/channel/contracts/test_remote_dependency_data.rb +209 -0
- data/test/application_insights/channel/contracts/test_request_data.rb +153 -0
- data/test/application_insights/channel/contracts/test_session.rb +57 -0
- data/test/application_insights/channel/contracts/test_stack_frame.rb +83 -0
- data/test/application_insights/channel/contracts/test_user.rb +96 -0
- data/test/application_insights/channel/test_asynchronous_queue.rb +47 -0
- data/test/application_insights/channel/test_asynchronous_sender.rb +81 -0
- data/test/application_insights/channel/test_event.rb +53 -0
- data/test/application_insights/channel/test_queue_base.rb +89 -0
- data/test/application_insights/channel/test_sender_base.rb +94 -0
- data/test/application_insights/channel/test_synchronous_queue.rb +28 -0
- data/test/application_insights/channel/test_synchronous_sender.rb +11 -0
- data/test/application_insights/channel/test_telemetry_channel.rb +167 -0
- data/test/application_insights/channel/test_telemetry_context.rb +83 -0
- data/test/application_insights/mock_sender.rb +37 -0
- data/test/application_insights/rack/test_track_request.rb +182 -0
- data/test/application_insights/test_logger.rb +10 -0
- data/test/application_insights/test_telemetry_client.rb +138 -0
- data/test/application_insights/test_unhandled_exception.rb +23 -0
- data/test/application_insights.rb +8 -0
- metadata +247 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d28bc24aac17bb3bd88e8080ec6abe6fa69faaebcda0dbb3d5f4746805f8dc6e
|
4
|
+
data.tar.gz: 06c89fcc256eef5c841b1cb214c7dff79f735213524fcc00b8b3c0a09c459e0d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07312cd55bc77c5ca5b37db7d50a93e11a4876a3b156272b9ebe73104c236881c52509427a5f0caebe5f8c690041786abea5844c606a5aac4e38e9de49c93969
|
7
|
+
data.tar.gz: 582cb4bb087073c4b579c99cac093f64b9a96a2f0a305f9345460095495a36ececac8496b4c3a0755cafbfe582e1bbb0761ff69b2ef893e303d69b7255b36980
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
create:
|
5
|
+
branches: [ "master" ]
|
6
|
+
tags:
|
7
|
+
- 'v*'
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
name: Build + Publish
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
environment: production
|
14
|
+
permissions:
|
15
|
+
contents: read
|
16
|
+
packages: write
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v3
|
20
|
+
- name: Set up Ruby 2.6
|
21
|
+
uses: actions/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: 2.6.x
|
24
|
+
|
25
|
+
- name: Publish to RubyGems
|
26
|
+
run: |
|
27
|
+
mkdir -p $HOME/.gem
|
28
|
+
touch $HOME/.gem/credentials
|
29
|
+
chmod 0600 $HOME/.gem/credentials
|
30
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
31
|
+
gem build *.gemspec
|
32
|
+
gem push *.gem
|
33
|
+
env:
|
34
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.gitignore
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.bundle
|
4
|
+
mkmf.log
|
5
|
+
/.config
|
6
|
+
/coverage/
|
7
|
+
/InstalledFiles
|
8
|
+
/doc/
|
9
|
+
/pkg/
|
10
|
+
/spec/reports/
|
11
|
+
/test/tmp/
|
12
|
+
/test/version_tmp/
|
13
|
+
/tmp/
|
14
|
+
|
15
|
+
## Specific to RubyMotion:
|
16
|
+
.dat*
|
17
|
+
.repl_history
|
18
|
+
build/
|
19
|
+
|
20
|
+
## Specific to RubyMine:
|
21
|
+
/.idea/
|
22
|
+
|
23
|
+
## Documentation cache and generated files:
|
24
|
+
/.yardoc/
|
25
|
+
/_yardoc/
|
26
|
+
/doc/
|
27
|
+
/rdoc/
|
28
|
+
|
29
|
+
## Environment normalisation:
|
30
|
+
/.bundle/
|
31
|
+
/lib/bundler/man/
|
32
|
+
|
33
|
+
# for a library or gem, you might want to ignore these files since the code is
|
34
|
+
# intended to run in multiple environments; otherwise, check them in:
|
35
|
+
Gemfile.lock
|
36
|
+
.ruby-version
|
37
|
+
.ruby-gemset
|
38
|
+
|
39
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
40
|
+
.rvmrc
|
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1.0
|
6
|
+
- 2.2.0
|
7
|
+
- 2.3.3
|
8
|
+
- 2.4.0
|
9
|
+
- 2.5.0
|
10
|
+
- ruby-head
|
11
|
+
|
12
|
+
cache: bundler
|
13
|
+
|
14
|
+
before_install:
|
15
|
+
- gem install bundler
|
16
|
+
|
17
|
+
matrix:
|
18
|
+
allow_failures:
|
19
|
+
- rvm: ruby-head
|
20
|
+
|
21
|
+
install:
|
22
|
+
- bundle install
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
This file needs to be updated with every significant pull request. It is used to write down release notes.
|
4
|
+
|
5
|
+
## Version 0.5.6
|
6
|
+
* Expose request id to parent Rack application when using `ApplicationInsights::Rack::TrackRequest` middleware through `env['ApplicationInsights.request.id']`.
|
7
|
+
* Implement operation context functionality for `ApplicationInsights::Rack::TrackRequest`.
|
8
|
+
* Add functionality to accept a Request-Id header for telemetry correlation.
|
9
|
+
* Add operation context to request tracking middleware.
|
10
|
+
|
11
|
+
## Version 0.5.5
|
12
|
+
* Add some basic logging when failed to send telemetry to the server
|
13
|
+
* Add timestamp as an optional parameter to the TelemetryChannel::write() method
|
14
|
+
|
15
|
+
## Version 0.5.4
|
16
|
+
|
17
|
+
Changelog started after this release.
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# How to Contribute
|
2
|
+
|
3
|
+
If you're interested in contributing, take a look at the general [contributer's guide](https://github.com/Microsoft/ApplicationInsights-Home/blob/master/CONTRIBUTING.md) first.
|
4
|
+
|
5
|
+
## Build Gem
|
6
|
+
|
7
|
+
Run ```gem build application_insights.gemspec``` to generate the gem file.
|
8
|
+
|
9
|
+
And you can install the gem to test it locally by running ```gem install application_insights-[version].gem```.
|
10
|
+
|
11
|
+
## Run Test
|
12
|
+
|
13
|
+
Make sure you have bundler installed, you can install it by ```sudo gem install bundler```. And run ```bundler install``` once to install all dependencies.
|
14
|
+
|
15
|
+
Run ```rake test```.
|
16
|
+
|
17
|
+
## Releasing new version
|
18
|
+
|
19
|
+
This is for repository maintainers only:
|
20
|
+
|
21
|
+
1. Create and merge develop->master PR https://github.com/Microsoft/ApplicationInsights-Ruby/compare/master...develop?expand=1
|
22
|
+
2. Checkout latest `master`
|
23
|
+
```
|
24
|
+
git checkout master
|
25
|
+
git pull
|
26
|
+
```
|
27
|
+
|
28
|
+
3. Remove old gem: `rm *.gem`
|
29
|
+
4. [Build gem](https://github.com/Microsoft/ApplicationInsights-Ruby/blob/develop/CONTRIBUTING.md#build-gem)
|
30
|
+
5. Push gem: `gem push application_insights-0.5.5.gem`
|
31
|
+
6. Check gem on [rubygems](https://rubygems.org/gems/application_insights)
|
32
|
+
7. Tag code:
|
33
|
+
```
|
34
|
+
git tag -a v0.5.5
|
35
|
+
git push origin v0.5.5
|
36
|
+
```
|
37
|
+
8. Update description of [release](https://github.com/Microsoft/ApplicationInsights-Ruby/releases/edit/v0.5.5) from [CHANGELOG.md](https://github.com/Microsoft/ApplicationInsights-Ruby/blob/master/CHANGELOG.md)
|
38
|
+
9. Create a branch off `develop` branch
|
39
|
+
```
|
40
|
+
git checkout develop
|
41
|
+
git pull
|
42
|
+
git checkout -b releaseUpdates
|
43
|
+
git push --set-upstream origin releaseUpdates
|
44
|
+
```
|
45
|
+
10. Update version in `/lib/application_insights/version.rb`
|
46
|
+
11. Create new entry for the next release in `/CHANGELOG.md`
|
47
|
+
12. Push changes
|
48
|
+
```
|
49
|
+
git add -A
|
50
|
+
git commit -m "post release updates"
|
51
|
+
git push
|
52
|
+
```
|
53
|
+
13. Submit releaseUpdates->develop PR: https://github.com/Microsoft/ApplicationInsights-Ruby/compare/develop...releaseUpdates?expand=1
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
This project welcomes contributions and suggestions. Most contributions require you to
|
58
|
+
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
|
59
|
+
and actually do, grant us the rights to use your contribution. For details, visit
|
60
|
+
https://cla.microsoft.com.
|
61
|
+
|
62
|
+
When you submit a pull request, a CLA-bot will automatically determine whether you need
|
63
|
+
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
|
64
|
+
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
|
65
|
+
|
66
|
+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
67
|
+
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
68
|
+
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
AppInsights-Ruby
|
2
|
+
Copyright (c) Microsoft Corporation
|
3
|
+
All rights reserved.
|
4
|
+
|
5
|
+
MIT License
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# Application Insights SDK for Ruby #
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/application_insights.svg)](http://badge.fury.io/rb/application_insights)
|
4
|
+
[![Build Status](https://travis-ci.org/Microsoft/ApplicationInsights-Ruby.svg)](https://travis-ci.org/Microsoft/ApplicationInsights-Ruby)
|
5
|
+
|
6
|
+
>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.
|
7
|
+
> -- <cite>[Ruby - Official Site](https://www.ruby-lang.org/en/)</cite>
|
8
|
+
|
9
|
+
This project extends the Application Insights API surface to support Ruby. [Application Insights](http://azure.microsoft.com/en-us/services/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.
|
10
|
+
|
11
|
+
|
12
|
+
## Requirements ##
|
13
|
+
|
14
|
+
Ruby 1.9.3 is currently supported by this gem.
|
15
|
+
|
16
|
+
## Installation ##
|
17
|
+
|
18
|
+
To install the latest release you can use *gem*.
|
19
|
+
|
20
|
+
```
|
21
|
+
$ gem install application_insights
|
22
|
+
```
|
23
|
+
|
24
|
+
## Usage ##
|
25
|
+
|
26
|
+
Once installed, you can send telemetry to Application Insights. Here are a few samples.
|
27
|
+
|
28
|
+
>**Note**: before you can send data to you will need an instrumentation key. Please see the [Getting an Application Insights Instrumentation Key](https://github.com/Microsoft/AppInsights-Home/wiki#getting-an-application-insights-instrumentation-key) section for more information.
|
29
|
+
|
30
|
+
|
31
|
+
### Sending a simple event telemetry item ###
|
32
|
+
```ruby
|
33
|
+
require 'application_insights'
|
34
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
35
|
+
tc.track_event 'My event'
|
36
|
+
tc.flush
|
37
|
+
```
|
38
|
+
|
39
|
+
### Sending an event telemetry item with custom properties and measurements ###
|
40
|
+
```ruby
|
41
|
+
require 'application_insights'
|
42
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
43
|
+
tc.track_event 'My event', :properties => { 'custom property' => 'some value' }, :measurements => { 'custom metric' => 13 }
|
44
|
+
tc.flush
|
45
|
+
```
|
46
|
+
|
47
|
+
### Sending a trace telemetry item with custom properties ###
|
48
|
+
```ruby
|
49
|
+
require 'application_insights'
|
50
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
51
|
+
tc.track_trace 'My trace statement', ApplicationInsights::Channel::Contracts::SeverityLevel::INFORMATION, :properties => { 'custom property' => 'some value' }
|
52
|
+
tc.flush
|
53
|
+
```
|
54
|
+
|
55
|
+
### Sending a metric telemetry item (without and with optional values) ###
|
56
|
+
```ruby
|
57
|
+
require 'application_insights'
|
58
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
59
|
+
tc.track_metric 'My metric', 42
|
60
|
+
# with all optional values set
|
61
|
+
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' }
|
62
|
+
tc.flush
|
63
|
+
```
|
64
|
+
|
65
|
+
### Sending an exception telemetry item with custom properties and measurements ###
|
66
|
+
```ruby
|
67
|
+
require 'application_insights'
|
68
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
69
|
+
begin
|
70
|
+
raise ArgumentError, 'Something has gone wrong!'
|
71
|
+
rescue => e
|
72
|
+
tc.track_exception e
|
73
|
+
end
|
74
|
+
tc.flush
|
75
|
+
```
|
76
|
+
|
77
|
+
### Configuring context for a telemetry client instance ###
|
78
|
+
```ruby
|
79
|
+
require 'application_insights'
|
80
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
81
|
+
tc.context.application.ver = '1.2.3'
|
82
|
+
tc.context.device.id = 'My current device'
|
83
|
+
tc.context.device.oem_name = 'Asus'
|
84
|
+
tc.context.device.model = 'X31A'
|
85
|
+
tc.context.device.type = "Other"
|
86
|
+
tc.context.user.id = 'santa@northpole.net'
|
87
|
+
tc.track_trace 'My trace with context'
|
88
|
+
tc.flush
|
89
|
+
```
|
90
|
+
|
91
|
+
### Configuring synchronous (default) channel properties ###
|
92
|
+
```ruby
|
93
|
+
require 'application_insights'
|
94
|
+
tc = ApplicationInsights::TelemetryClient.new
|
95
|
+
# flush telemetry if we have 10 or more telemetry items in our queue
|
96
|
+
tc.channel.queue.max_queue_length = 10
|
97
|
+
# send telemetry to the service in batches of 5
|
98
|
+
tc.channel.sender.send_buffer_size = 5
|
99
|
+
```
|
100
|
+
|
101
|
+
### Configuring an asynchronous channel instead of the synchronous default ###
|
102
|
+
```ruby
|
103
|
+
require 'application_insights'
|
104
|
+
sender = ApplicationInsights::Channel::AsynchronousSender.new
|
105
|
+
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
|
106
|
+
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
|
107
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>', channel
|
108
|
+
# Note: the event will be sent on a separate thread; if the app finishes before
|
109
|
+
# the thread finishes, the data is lost
|
110
|
+
tc.track_event 'My event'
|
111
|
+
```
|
112
|
+
|
113
|
+
### Configuring asynchronous channel properties ###
|
114
|
+
```ruby
|
115
|
+
require 'application_insights'
|
116
|
+
sender = ApplicationInsights::Channel::AsynchronousSender.new
|
117
|
+
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
|
118
|
+
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
|
119
|
+
tc = ApplicationInsights::TelemetryClient.new '<YOUR INSTRUMENTATION KEY GOES HERE>', channel
|
120
|
+
# flush telemetry if we have 10 or more telemetry items in our queue
|
121
|
+
tc.channel.queue.max_queue_length = 10
|
122
|
+
# send telemetry to the service in batches of 5
|
123
|
+
tc.channel.sender.send_buffer_size = 5
|
124
|
+
# the background worker thread will be active for 5 seconds before it shuts down. if
|
125
|
+
# during this time items are picked up from the queue, the timer is reset.
|
126
|
+
tc.channel.sender.send_time = 5
|
127
|
+
# the background worker thread will poll the queue every 0.5 seconds for new items
|
128
|
+
tc.channel.sender.send_interval = 0.5
|
129
|
+
```
|
130
|
+
|
131
|
+
### Collecting unhandled exceptions ###
|
132
|
+
```ruby
|
133
|
+
require 'application_insights'
|
134
|
+
# setup unhandled exception handler
|
135
|
+
ApplicationInsights::UnhandledException.collect('<YOUR INSTRUMENTATION KEY GOES HERE>')
|
136
|
+
# raise an exception and this would be send to Application Insights Service
|
137
|
+
raise Exception, 'Boom!'
|
138
|
+
```
|
139
|
+
|
140
|
+
### Collecting requests for rack applications ###
|
141
|
+
```ruby
|
142
|
+
# set up the TrackRequest middleware in the rackup (config.ru) file
|
143
|
+
require 'application_insights'
|
144
|
+
use ApplicationInsights::Rack::TrackRequest, '<YOUR INSTRUMENTATION KEY GOES HERE>', <buffer size>
|
145
|
+
# For rails, suggest to set up this middleware in application.rb so that unhandled exceptions from controllers are also collected
|
146
|
+
config.middleware.use 'ApplicationInsights::Rack::TrackRequest', '<YOUR INSTRUMENTATION KEY GOES HERE>', <buffer size>
|
147
|
+
```
|
148
|
+
|
149
|
+
#### Rerieving the Request-Id value from ApplicationInsights ####
|
150
|
+
```ruby
|
151
|
+
# from time to time you may need to access a request's id from within your app
|
152
|
+
application_insights_request_id = env['ApplicationInsights.request.id']
|
153
|
+
|
154
|
+
# this can be used for a number of different purposes, including telemetry correlation
|
155
|
+
uri = URI('http://api.example.com/search/?q=test')
|
156
|
+
|
157
|
+
req = Net::HTTP::Get.new(uri)
|
158
|
+
req['Request-Id'] = "#{application_insights_request_id}1" if application_insights_request_id
|
159
|
+
|
160
|
+
Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(req) }
|
161
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'yard'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |test|
|
6
|
+
test.libs << 'test'
|
7
|
+
test.test_files = FileList['test/application_insights.rb']
|
8
|
+
test.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
YARD::Rake::YardocTask.new do |task|
|
12
|
+
task.files = ['lib/**/*.rb', '-', 'LICENSE.txt', 'README.md']
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => [ :test, :build, :yard ]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'application_insights/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'azure_application_insights'
|
8
|
+
spec.version = ApplicationInsights::VERSION
|
9
|
+
spec.authors = ['Daniel Blasina']
|
10
|
+
spec.email = ['blzk100@gmail.com']
|
11
|
+
spec.summary = %q{Forked Application Insights SDK for Ruby}
|
12
|
+
spec.description = %q{This project extends the Application Insights API surface to support Ruby.}
|
13
|
+
spec.homepage = 'https://github.com/blasko03/ApplicationInsights-Ruby/'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 1.9.3'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'yard', '~> 0.9.11'
|
25
|
+
spec.add_development_dependency 'redcarpet', '~> 3.2.2'
|
26
|
+
spec.add_development_dependency 'rack', '>= 1.0.0'
|
27
|
+
spec.add_development_dependency 'test-unit', '~> 3.0.8'
|
28
|
+
spec.add_development_dependency 'mocha', '~> 1.5.0'
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative 'event'
|
2
|
+
require_relative 'queue_base'
|
3
|
+
|
4
|
+
module ApplicationInsights
|
5
|
+
module Channel
|
6
|
+
# An asynchronous queue for use in conjunction with the {AsynchronousSender}.
|
7
|
+
# The queue will notify the sender that it needs to pick up items when it
|
8
|
+
# reaches {#max_queue_length}, or when the consumer calls {#flush} via the
|
9
|
+
# {#flush_notification} event.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# require 'application_insights'
|
13
|
+
# require 'thread'
|
14
|
+
# queue = ApplicationInsights::Channel::AsynchronousQueue.new nil
|
15
|
+
# Thread.new do
|
16
|
+
# sleep 1
|
17
|
+
# queue.push 1
|
18
|
+
# queue.flush
|
19
|
+
# end
|
20
|
+
# queue.flush_notification.wait
|
21
|
+
# queue.flush_notification.clear
|
22
|
+
# result = queue.pop
|
23
|
+
class AsynchronousQueue < QueueBase
|
24
|
+
# Initializes a new instance of the class.
|
25
|
+
# @param [SenderBase] sender the sender object that will be used in
|
26
|
+
# conjunction with this queue. In addition to the sender object must
|
27
|
+
# support a {AsynchronousSender#start} method which is invoked each time
|
28
|
+
# an item is pushed to the queue as well as use the {#flush_notification}
|
29
|
+
# event.
|
30
|
+
def initialize(sender)
|
31
|
+
@flush_notification = Event.new
|
32
|
+
super sender
|
33
|
+
end
|
34
|
+
|
35
|
+
# The flush notification {ApplicationInsights::Channel::Event} that the {#sender}
|
36
|
+
# will use to get notified that a flush is needed.
|
37
|
+
# @return [Event] object that the {#sender} can wait on.
|
38
|
+
attr_reader :flush_notification
|
39
|
+
|
40
|
+
# Adds the passed in item object to the queue and notifies the {#sender}
|
41
|
+
# to start an asynchronous send operation
|
42
|
+
# by calling {AsynchronousSender#start}.
|
43
|
+
# @param [Contracts::Envelope] item the telemetry envelope object to send
|
44
|
+
# to the service.
|
45
|
+
def push(item)
|
46
|
+
super item
|
47
|
+
@sender.start if @sender
|
48
|
+
end
|
49
|
+
|
50
|
+
# Flushes the current queue by notifying the {#sender} via the
|
51
|
+
# {#flush_notification} event.
|
52
|
+
def flush
|
53
|
+
@flush_notification.set
|
54
|
+
@sender.start if @sender
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require_relative 'sender_base'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module ApplicationInsights
|
5
|
+
module Channel
|
6
|
+
# An asynchronous sender that works in conjunction with the {AsynchronousQueue}.
|
7
|
+
# The sender object will start a worker thread that will pull items from the
|
8
|
+
# {#queue}. The thread will be created when the client calls {#start} and
|
9
|
+
# will check for queue items every {#send_interval} seconds. The worker thread
|
10
|
+
# can also be forced to check the queue by setting the
|
11
|
+
# {AsynchronousQueue#flush_notification} event.
|
12
|
+
#
|
13
|
+
# - If no items are found, the thread will go back to sleep.
|
14
|
+
# - If items are found, the worker thread will send items to the specified
|
15
|
+
# service in batches of {#send_buffer_size}.
|
16
|
+
#
|
17
|
+
# If no queue items are found for {#send_time} seconds, the worker thread
|
18
|
+
# will shut down (and {#start} will need to be called again).
|
19
|
+
class AsynchronousSender < SenderBase
|
20
|
+
SERVICE_ENDPOINT_URI = 'https://dc.services.visualstudio.com/v2/track'
|
21
|
+
# Initializes a new instance of the class.
|
22
|
+
# @param [String] service_endpoint_uri the address of the service to send
|
23
|
+
# telemetry data to.
|
24
|
+
def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI)
|
25
|
+
@send_interval = 1.0
|
26
|
+
@send_remaining_time = 0
|
27
|
+
@send_time = 3.0
|
28
|
+
@lock_work_thread = Mutex.new
|
29
|
+
@work_thread = nil
|
30
|
+
@start_notification_processed = true
|
31
|
+
super service_endpoint_uri
|
32
|
+
end
|
33
|
+
|
34
|
+
# The time span in seconds at which the the worker thread will check the
|
35
|
+
# {#queue} for items (defaults to: 1.0).
|
36
|
+
# @return [Fixnum] the interval in seconds.
|
37
|
+
attr_accessor :send_interval
|
38
|
+
|
39
|
+
# The time span in seconds for which the worker thread will stay alive if
|
40
|
+
# no items are found in the {#queue} (defaults to 3.0).
|
41
|
+
# @return [Fixnum] the interval in seconds.
|
42
|
+
attr_accessor :send_time
|
43
|
+
|
44
|
+
# The worker thread which checks queue items and send data every
|
45
|
+
# (#send_interval) seconds or upon flush.
|
46
|
+
# @return [Thread] the work thread
|
47
|
+
attr_reader :work_thread
|
48
|
+
|
49
|
+
# Calling this method will create a worker thread that checks the {#queue}
|
50
|
+
# every {#send_interval} seconds for a total duration of {#send_time}
|
51
|
+
# seconds for new items. If a worker thread has already been created,
|
52
|
+
# calling this method does nothing.
|
53
|
+
def start
|
54
|
+
@start_notification_processed = false
|
55
|
+
# Maintain one working thread at one time
|
56
|
+
unless @work_thread
|
57
|
+
@lock_work_thread.synchronize do
|
58
|
+
unless @work_thread
|
59
|
+
local_send_interval = [@send_interval, 0.1].max
|
60
|
+
@send_remaining_time = [@send_time, local_send_interval].max
|
61
|
+
@work_thread = Thread.new { run }
|
62
|
+
@work_thread.abort_on_exception = false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def run
|
71
|
+
# save the queue locally
|
72
|
+
local_queue = @queue
|
73
|
+
if local_queue.nil?
|
74
|
+
@work_thread = nil
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
begin
|
79
|
+
# fix up the send interval (can't be lower than 100ms)
|
80
|
+
local_send_interval = [@send_interval, 0.1].max
|
81
|
+
|
82
|
+
while true
|
83
|
+
@start_notification_processed = true
|
84
|
+
while true
|
85
|
+
# get at most @send_buffer_size items from the queue
|
86
|
+
data = []
|
87
|
+
@send_buffer_size.downto(1) do
|
88
|
+
item = local_queue.pop
|
89
|
+
break if not item
|
90
|
+
data.push item
|
91
|
+
end
|
92
|
+
|
93
|
+
# if we didn't get any items from the queue, we're done here
|
94
|
+
break if data.length == 0
|
95
|
+
|
96
|
+
# reset the send time
|
97
|
+
@send_remaining_time = @send_time
|
98
|
+
|
99
|
+
# finally send the data
|
100
|
+
send data
|
101
|
+
end
|
102
|
+
|
103
|
+
# wait at most @send_interval ms (or until we get signalled)
|
104
|
+
result = local_queue.flush_notification.wait local_send_interval
|
105
|
+
if result
|
106
|
+
local_queue.flush_notification.clear
|
107
|
+
next
|
108
|
+
end
|
109
|
+
|
110
|
+
# decrement the remaining time
|
111
|
+
@send_remaining_time -= local_send_interval
|
112
|
+
# If remaining time <=0 and there is no start notification unprocessed,
|
113
|
+
# then stop the working thread
|
114
|
+
if @send_remaining_time <= 0 && @start_notification_processed
|
115
|
+
# Note: there is still a chance some start notification could be
|
116
|
+
# missed, e.g., the start method got triggered between the above and
|
117
|
+
# following line. However the data is not lost as it would be
|
118
|
+
# processed later when next start notification comes after the worker
|
119
|
+
# thread stops. The cost to ensure no notification miss is high where
|
120
|
+
# a lock is required each time the start method calls.
|
121
|
+
@work_thread = nil
|
122
|
+
break
|
123
|
+
end
|
124
|
+
end
|
125
|
+
rescue Exception => e
|
126
|
+
# Make sure work_thread sets to nil when it terminates abnormally
|
127
|
+
@work_thread = nil
|
128
|
+
@logger.error('application_insights') { "Asynchronous sender work thread terminated abnormally: #{e.to_s}" }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'json_serializable'
|
2
|
+
|
3
|
+
module ApplicationInsights::Channel::Contracts
|
4
|
+
class Application
|
5
|
+
include JsonSerializable
|
6
|
+
|
7
|
+
attr_accessor :ver, :build
|
8
|
+
|
9
|
+
attribute_mapping(
|
10
|
+
ver: 'ai.application.ver',
|
11
|
+
build: 'ai.application.build'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'json_serializable'
|
2
|
+
|
3
|
+
module ApplicationInsights::Channel::Contracts
|
4
|
+
class Cloud
|
5
|
+
include JsonSerializable
|
6
|
+
|
7
|
+
attr_accessor :role_name, :role_instance
|
8
|
+
|
9
|
+
attribute_mapping(
|
10
|
+
role_name: 'ai.cloud.role',
|
11
|
+
role_instance: 'ai.cloud.roleInstance'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'json_serializable'
|
2
|
+
|
3
|
+
module ApplicationInsights::Channel::Contracts
|
4
|
+
class Data
|
5
|
+
include JsonSerializable
|
6
|
+
|
7
|
+
attr_accessor :base_type, :base_data
|
8
|
+
|
9
|
+
attribute_mapping(
|
10
|
+
base_type: 'baseType',
|
11
|
+
base_data: 'baseData'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|