application_insights 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +9 -9
- data/LICENSE.txt +7 -18
- data/README.md +42 -7
- data/Rakefile +6 -1
- data/application_insights.gemspec +2 -0
- data/lib/application_insights.rb +1 -0
- data/lib/application_insights/channel/asynchronous_queue.rb +51 -0
- data/lib/application_insights/channel/asynchronous_sender.rb +121 -0
- data/lib/application_insights/channel/contracts/application.rb +3 -2
- data/lib/application_insights/channel/contracts/data.rb +3 -2
- data/lib/application_insights/channel/contracts/data_point.rb +15 -10
- data/lib/application_insights/channel/contracts/device.rb +42 -28
- data/lib/application_insights/channel/contracts/envelope.rb +39 -27
- data/lib/application_insights/channel/contracts/event_data.rb +6 -6
- data/lib/application_insights/channel/contracts/exception_data.rb +9 -8
- data/lib/application_insights/channel/contracts/exception_details.rb +15 -11
- data/lib/application_insights/channel/contracts/internal.rb +6 -4
- data/lib/application_insights/channel/contracts/location.rb +3 -2
- data/lib/application_insights/channel/contracts/message_data.rb +6 -5
- data/lib/application_insights/channel/contracts/metric_data.rb +3 -3
- data/lib/application_insights/channel/contracts/operation.rb +12 -8
- data/lib/application_insights/channel/contracts/page_view_data.rb +12 -10
- data/lib/application_insights/channel/contracts/remote_dependency_data.rb +27 -19
- data/lib/application_insights/channel/contracts/request_data.rb +15 -12
- data/lib/application_insights/channel/contracts/session.rb +9 -6
- data/lib/application_insights/channel/contracts/stack_frame.rb +9 -6
- data/lib/application_insights/channel/contracts/user.rb +12 -8
- data/lib/application_insights/channel/event.rb +64 -0
- data/lib/application_insights/channel/queue_base.rb +24 -10
- data/lib/application_insights/channel/sender_base.rb +38 -9
- data/lib/application_insights/channel/synchronous_queue.rb +16 -5
- data/lib/application_insights/channel/synchronous_sender.rb +4 -2
- data/lib/application_insights/channel/telemetry_channel.rb +26 -7
- data/lib/application_insights/channel/telemetry_context.rb +29 -10
- data/lib/application_insights/telemetry_client.rb +84 -15
- data/lib/application_insights/unhandled_exception.rb +48 -0
- data/lib/application_insights/version.rb +1 -1
- data/test/application_insights/channel/test_asynchronous_queue.rb +68 -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 +10 -9
- data/test/application_insights/channel/test_sender_base.rb +0 -9
- data/test/application_insights/test_telemetry_client.rb +5 -0
- data/test/application_insights/test_unhandled_exception.rb +42 -0
- metadata +44 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NWFiNjNiNjljMTc2ODI1NzQ4M2VhNTlmODU2MTcxZTFlZjliMTA2Yw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
7
|
-
|
6
|
+
NGM3NzEwNDZkYzI1MWEwNjRiNTMwNWMyOGJlYTkwODA5MjM2MmI2Yw==
|
7
|
+
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTU5OTgzY2QzMWMwOTJmYTM3YTZiZWNlYTg4NmQ0NWM4ODkzYjk2ZTI4MTQ4
|
10
|
+
NzJmMDJiNTQxNTA0YzkwNjBmYTEwYTc3ZjBhNmU5YjQxZTRmODA2ZTU4Zjgz
|
11
|
+
ZWJhMzAzZWI2NmYyNzRjMzg0ZDNmZmQwNjZkNmY3MGU2NjYzN2U=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjA1MDU4ZWY2Mjc0MDZiZTYxM2Y0ZTk3MzQ2MjI2NzdjZDU1Y2FkZTY0MGY5
|
14
|
+
ZDBkNDQ1ZGQ4Zjk5M2MwNThmM2VjNjg4ZWNlNjE3ZjMxMjdkMWI3NDRiYmMy
|
15
|
+
YTc5ZDcxYmUwZWM1MzNjMDVhYTU1ZmEwYTFjNDUxOTUxMDYyY2M=
|
data/LICENSE.txt
CHANGED
@@ -1,22 +1,11 @@
|
|
1
|
-
|
1
|
+
AppInsights-Ruby
|
2
|
+
Copyright (c) Microsoft Corporation
|
3
|
+
All rights reserved.
|
2
4
|
|
3
|
-
|
5
|
+
MIT License
|
4
6
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
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:
|
11
8
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
22
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
CHANGED
@@ -27,7 +27,7 @@ Once installed, you can send telemetry to Application Insights. Here are a few s
|
|
27
27
|
>**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.
|
28
28
|
|
29
29
|
|
30
|
-
|
30
|
+
###Sending a simple event telemetry item###
|
31
31
|
```ruby
|
32
32
|
require 'application_insights'
|
33
33
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -36,7 +36,7 @@ tc.track_event 'My event'
|
|
36
36
|
tc.flush
|
37
37
|
```
|
38
38
|
|
39
|
-
|
39
|
+
###Sending an event telemetry item with custom properties and measurements###
|
40
40
|
```ruby
|
41
41
|
require 'application_insights'
|
42
42
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -45,7 +45,7 @@ tc.track_event 'My event', :properties => { 'custom property' => 'some value' },
|
|
45
45
|
tc.flush
|
46
46
|
```
|
47
47
|
|
48
|
-
|
48
|
+
###Sending a trace telemetry item with custom properties###
|
49
49
|
```ruby
|
50
50
|
require 'application_insights'
|
51
51
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -54,7 +54,7 @@ tc.track_trace 'My trace statement', :properties => { 'custom property' => 'some
|
|
54
54
|
tc.flush
|
55
55
|
```
|
56
56
|
|
57
|
-
|
57
|
+
###Sending a metric telemetry item (without and with optional values)###
|
58
58
|
```ruby
|
59
59
|
require 'application_insights'
|
60
60
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -65,7 +65,7 @@ tc.track_metric 'My metric', 42, :kind => ApplicationInsights::Channel::Contract
|
|
65
65
|
tc.flush
|
66
66
|
```
|
67
67
|
|
68
|
-
|
68
|
+
###Sending an exception telemetry item with custom properties and measurements###
|
69
69
|
```ruby
|
70
70
|
require 'application_insights'
|
71
71
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -78,7 +78,7 @@ end
|
|
78
78
|
tc.flush
|
79
79
|
```
|
80
80
|
|
81
|
-
|
81
|
+
###Configuring context for a telemetry client instance###
|
82
82
|
```ruby
|
83
83
|
require 'application_insights'
|
84
84
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -94,7 +94,7 @@ tc.track_trace 'My trace with context'
|
|
94
94
|
tc.flush
|
95
95
|
```
|
96
96
|
|
97
|
-
|
97
|
+
###Configuring synchronous (default) channel properties###
|
98
98
|
```ruby
|
99
99
|
require 'application_insights'
|
100
100
|
tc = ApplicationInsights::TelemetryClient.new
|
@@ -104,5 +104,40 @@ tc.channel.queue.max_queue_length = 10
|
|
104
104
|
tc.channel.sender.send_buffer_size = 5
|
105
105
|
```
|
106
106
|
|
107
|
+
###Configuring an asynchronous channel instead of the synchronous default###
|
108
|
+
```ruby
|
109
|
+
require 'application_insights'
|
110
|
+
sender = ApplicationInsights::Channel::AsynchronousSender.new
|
111
|
+
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
|
112
|
+
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
|
113
|
+
tc = ApplicationInsights::TelemetryClient.new channel
|
114
|
+
# Note: the event will be sent on a separate thread; if the app finishes before
|
115
|
+
# the thread finishes, the data is lost
|
116
|
+
tc.track_event 'My event'
|
117
|
+
```
|
107
118
|
|
119
|
+
###Configuring asynchronous channel properties###
|
120
|
+
```ruby
|
121
|
+
require 'application_insights'
|
122
|
+
sender = ApplicationInsights::Channel::AsynchronousSender.new
|
123
|
+
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
|
124
|
+
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
|
125
|
+
tc = ApplicationInsights::TelemetryClient.new channel
|
126
|
+
# flush telemetry if we have 10 or more telemetry items in our queue
|
127
|
+
tc.channel.queue.max_queue_length = 10
|
128
|
+
# send telemetry to the service in batches of 5
|
129
|
+
tc.channel.sender.send_buffer_size = 5
|
130
|
+
# the background worker thread will be active for 5 seconds before it shuts down. if
|
131
|
+
# during this time items are picked up from the queue, the timer is reset.
|
132
|
+
tc.channel.sender.send_time = 5
|
133
|
+
# the background worker thread will poll the queue every 0.5 seconds for new items
|
134
|
+
tc.channel.sender.send_interval = 0.5
|
135
|
+
```
|
108
136
|
|
137
|
+
###Collecting unhandled exceptions###
|
138
|
+
```ruby
|
139
|
+
require 'application_insights'
|
140
|
+
# setup unhandled exception handler
|
141
|
+
ApplicationInsights::UnhandledException.collect('<YOUR INSTRUMENTATION KEY GOES HERE>')
|
142
|
+
# raise an exception and this would be send to Application Insights Service
|
143
|
+
raise Exception, 'Boom!'
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require 'rake/testtask'
|
3
|
+
require 'yard'
|
3
4
|
|
4
5
|
Rake::TestTask.new do |test|
|
5
6
|
test.libs << 'test'
|
@@ -7,4 +8,8 @@ Rake::TestTask.new do |test|
|
|
7
8
|
test.verbose = true
|
8
9
|
end
|
9
10
|
|
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 ]
|
data/lib/application_insights.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
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}. The queue
|
7
|
+
# will notify the sender that it needs to pick up items when it reaches {#max_queue_length}, or when the consumer
|
8
|
+
# calls {#flush} via the {#flush_notification} event.
|
9
|
+
# @example
|
10
|
+
# require 'application_insights'
|
11
|
+
# require 'thread'
|
12
|
+
# queue = ApplicationInsights::Channel::AsynchronousQueue.new nil
|
13
|
+
# Thread.new do
|
14
|
+
# sleep 1
|
15
|
+
# queue.push 1
|
16
|
+
# queue.flush
|
17
|
+
# end
|
18
|
+
# queue.flush_notification.wait
|
19
|
+
# queue.flush_notification.clear
|
20
|
+
# result = queue.pop
|
21
|
+
class AsynchronousQueue < QueueBase
|
22
|
+
# Initializes a new instance of the class.
|
23
|
+
# @param [SenderBase] sender the sender object that will be used in conjunction with this queue. In addition to
|
24
|
+
# the sender object must support a {AsynchronousSender#start} method which is invoked
|
25
|
+
# each time an item is pushed to the queue as well as use the {#flush_notification} event.
|
26
|
+
def initialize(sender)
|
27
|
+
@flush_notification = Event.new
|
28
|
+
super sender
|
29
|
+
end
|
30
|
+
|
31
|
+
# The flush notification {ApplicationInsights::Channel::Event} that the {#sender} will use to get notified
|
32
|
+
# that a flush is needed.
|
33
|
+
# @return [Event] object that the {#sender} can wait on.
|
34
|
+
attr_reader :flush_notification
|
35
|
+
|
36
|
+
# Adds the passed in item object to the queue and notifies the {#sender} to start an asynchronous send operation
|
37
|
+
# by calling {AsynchronousSender#start}.
|
38
|
+
# @param [Contracts::Envelope] item the telemetry envelope object to send to the service.
|
39
|
+
def push(item)
|
40
|
+
super item
|
41
|
+
@sender.start if @sender
|
42
|
+
end
|
43
|
+
|
44
|
+
# Flushes the current queue by notifying the {#sender} via the {#flush_notification} event.
|
45
|
+
def flush
|
46
|
+
@flush_notification.set
|
47
|
+
@sender.start if @sender
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,121 @@
|
|
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}. The sender object will start a
|
7
|
+
# worker thread that will pull items from the {#queue}. The thread will be created when the client calls {#start} and
|
8
|
+
# will check for queue items every {#send_interval} seconds. The worker thread can also be forced to check the queue
|
9
|
+
# by setting the {AsynchronousQueue#flush_notification} event.
|
10
|
+
#
|
11
|
+
# - If no items are found, the thread will go back to sleep.
|
12
|
+
# - If items are found, the worker thread will send items to the specified service in batches of {#send_buffer_size}.
|
13
|
+
#
|
14
|
+
# If no queue items are found for {#send_time} seconds, the worker thread will shut down (and {#start} will
|
15
|
+
# need to be called again).
|
16
|
+
class AsynchronousSender < SenderBase
|
17
|
+
# Initializes a new instance of the class.
|
18
|
+
# @param [String] service_endpoint_uri the address of the service to send telemetry data to.
|
19
|
+
def initialize(service_endpoint_uri='https://dc.services.visualstudio.com/v2/track')
|
20
|
+
@send_interval = 1.0
|
21
|
+
@send_remaining_time = 0
|
22
|
+
@send_time = 3.0
|
23
|
+
@lock_send_remaining_time = Mutex.new
|
24
|
+
@work_thread = nil
|
25
|
+
super service_endpoint_uri
|
26
|
+
end
|
27
|
+
|
28
|
+
# The time span in seconds at which the the worker thread will check the {#queue} for items (defaults to: 1.0).
|
29
|
+
# @return [Fixnum] the interval in seconds.
|
30
|
+
attr_accessor :send_interval
|
31
|
+
|
32
|
+
# The time span in seconds for which the worker thread will stay alive if no items are found in the {#queue} (defaults to 3.0).
|
33
|
+
# @return [Fixnum] the interval in seconds.
|
34
|
+
attr_accessor :send_time
|
35
|
+
|
36
|
+
# The worker thread which checks queue items and send data every (#send_interval) seconds or upon flush.
|
37
|
+
# @return [Thread] the work thread
|
38
|
+
attr_reader :work_thread
|
39
|
+
|
40
|
+
# Calling this method will create a worker thread that checks the {#queue} every {#send_interval} seconds for
|
41
|
+
# a total duration of {#send_time} seconds for new items. If a worker thread has already been created, calling
|
42
|
+
# this method does nothing.
|
43
|
+
def start
|
44
|
+
@lock_send_remaining_time.synchronize do
|
45
|
+
# only maintain one working thread at one time
|
46
|
+
if !@work_thread
|
47
|
+
local_send_interval = (@send_interval < 0.1) ? 0.1 : @send_interval
|
48
|
+
@send_remaining_time = (@send_time < local_send_interval) ? local_send_interval : @send_time
|
49
|
+
@work_thread = Thread.new do
|
50
|
+
run
|
51
|
+
end
|
52
|
+
@work_thread.abort_on_exception = false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Calling this method will shut down the worker thread that checks the {#queue} for new items. The thread will be
|
58
|
+
# allowed to shut down gracefully.
|
59
|
+
def stop
|
60
|
+
@lock_send_remaining_time.synchronize do
|
61
|
+
@send_remaining_time = 0
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def run
|
68
|
+
# save the queue locally
|
69
|
+
local_queue = @queue
|
70
|
+
if local_queue == nil
|
71
|
+
stop
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
# fix up the send interval (can't be lower than 100ms)
|
76
|
+
local_send_interval = (@send_interval < 0.1) ? 0.1 : @send_interval
|
77
|
+
while TRUE
|
78
|
+
while TRUE
|
79
|
+
# get at most @send_buffer_size items from the queue
|
80
|
+
counter = @send_buffer_size
|
81
|
+
data = []
|
82
|
+
while counter > 0
|
83
|
+
item = local_queue.pop
|
84
|
+
break if not item
|
85
|
+
data.push item
|
86
|
+
counter -= 1
|
87
|
+
end
|
88
|
+
|
89
|
+
# if we didn't get any items from the queue, we're done here
|
90
|
+
break if data.length == 0
|
91
|
+
|
92
|
+
# reset the send time
|
93
|
+
@lock_send_remaining_time.synchronize do
|
94
|
+
@send_remaining_time = @send_time
|
95
|
+
end
|
96
|
+
|
97
|
+
# finally send the data
|
98
|
+
send data
|
99
|
+
end
|
100
|
+
|
101
|
+
# wait at most @send_interval ms (or until we get signalled)
|
102
|
+
result = local_queue.flush_notification.wait local_send_interval
|
103
|
+
if result
|
104
|
+
local_queue.flush_notification.clear
|
105
|
+
next
|
106
|
+
end
|
107
|
+
|
108
|
+
# decrement the remaining time
|
109
|
+
@lock_send_remaining_time.synchronize do
|
110
|
+
@send_remaining_time -= local_send_interval
|
111
|
+
# Check queue as well to avoid missing any 'start' notification occurred during waiting
|
112
|
+
if @send_remaining_time <= 0 && local_queue.empty?
|
113
|
+
@work_thread = nil
|
114
|
+
break
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -17,8 +17,9 @@ module ApplicationInsights
|
|
17
17
|
|
18
18
|
# Gets the ver property.
|
19
19
|
def ver
|
20
|
-
|
21
|
-
|
20
|
+
@values.fetch('ai.application.ver') {
|
21
|
+
@values['ai.application.ver'] = nil
|
22
|
+
}
|
22
23
|
end
|
23
24
|
|
24
25
|
# Sets the ver property.
|
@@ -19,8 +19,9 @@ module ApplicationInsights
|
|
19
19
|
|
20
20
|
# Gets the base_type property.
|
21
21
|
def base_type
|
22
|
-
|
23
|
-
|
22
|
+
@values.fetch('baseType') {
|
23
|
+
@values['baseType'] = nil
|
24
|
+
}
|
24
25
|
end
|
25
26
|
|
26
27
|
# Sets the base_type property.
|
@@ -37,8 +37,9 @@ module ApplicationInsights
|
|
37
37
|
|
38
38
|
# Gets the kind property.
|
39
39
|
def kind
|
40
|
-
|
41
|
-
|
40
|
+
@values.fetch('kind') {
|
41
|
+
@values['kind'] = DataPointType::MEASUREMENT
|
42
|
+
}
|
42
43
|
end
|
43
44
|
|
44
45
|
# Sets the kind property.
|
@@ -62,8 +63,9 @@ module ApplicationInsights
|
|
62
63
|
|
63
64
|
# Gets the count property.
|
64
65
|
def count
|
65
|
-
|
66
|
-
|
66
|
+
@values.fetch('count') {
|
67
|
+
@values['count'] = nil
|
68
|
+
}
|
67
69
|
end
|
68
70
|
|
69
71
|
# Sets the count property.
|
@@ -77,8 +79,9 @@ module ApplicationInsights
|
|
77
79
|
|
78
80
|
# Gets the min property.
|
79
81
|
def min
|
80
|
-
|
81
|
-
|
82
|
+
@values.fetch('min') {
|
83
|
+
@values['min'] = nil
|
84
|
+
}
|
82
85
|
end
|
83
86
|
|
84
87
|
# Sets the min property.
|
@@ -92,8 +95,9 @@ module ApplicationInsights
|
|
92
95
|
|
93
96
|
# Gets the max property.
|
94
97
|
def max
|
95
|
-
|
96
|
-
|
98
|
+
@values.fetch('max') {
|
99
|
+
@values['max'] = nil
|
100
|
+
}
|
97
101
|
end
|
98
102
|
|
99
103
|
# Sets the max property.
|
@@ -107,8 +111,9 @@ module ApplicationInsights
|
|
107
111
|
|
108
112
|
# Gets the std_dev property.
|
109
113
|
def std_dev
|
110
|
-
|
111
|
-
|
114
|
+
@values.fetch('stdDev') {
|
115
|
+
@values['stdDev'] = nil
|
116
|
+
}
|
112
117
|
end
|
113
118
|
|
114
119
|
# Sets the std_dev property.
|