application_insights 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +6 -14
- data/.travis.yml +21 -9
- data/CONTRIBUTING.md +30 -0
- data/Gemfile +4 -4
- data/LICENSE.txt +11 -11
- data/README.md +13 -14
- data/Rakefile +14 -14
- data/application_insights.gemspec +28 -29
- data/lib/application_insights.rb +9 -9
- data/lib/application_insights/channel/asynchronous_queue.rb +58 -51
- data/lib/application_insights/channel/asynchronous_sender.rb +132 -123
- data/lib/application_insights/channel/contracts/application.rb +14 -53
- data/lib/application_insights/channel/contracts/cloud.rb +14 -0
- data/lib/application_insights/channel/contracts/data.rb +14 -48
- data/lib/application_insights/channel/contracts/data_point.rb +24 -130
- data/lib/application_insights/channel/contracts/data_point_type.rb +7 -16
- data/lib/application_insights/channel/contracts/dependency_kind.rb +9 -19
- data/lib/application_insights/channel/contracts/dependency_source_type.rb +9 -19
- data/lib/application_insights/channel/contracts/device.rb +28 -257
- data/lib/application_insights/channel/contracts/envelope.rb +40 -266
- data/lib/application_insights/channel/contracts/event_data.rb +28 -77
- data/lib/application_insights/channel/contracts/exception_data.rb +37 -140
- data/lib/application_insights/channel/contracts/exception_details.rb +28 -129
- data/lib/application_insights/channel/contracts/internal.rb +14 -53
- data/lib/application_insights/channel/contracts/json_serializable.rb +59 -59
- data/lib/application_insights/channel/contracts/location.rb +16 -36
- data/lib/application_insights/channel/contracts/message_data.rb +24 -77
- data/lib/application_insights/channel/contracts/metric_data.rb +27 -60
- data/lib/application_insights/channel/contracts/operation.rb +19 -121
- data/lib/application_insights/channel/contracts/page_view_data.rb +30 -111
- data/lib/application_insights/channel/contracts/remote_dependency_data.rb +56 -260
- data/lib/application_insights/channel/contracts/request_data.rb +36 -176
- data/lib/application_insights/channel/contracts/session.rb +15 -70
- data/lib/application_insights/channel/contracts/severity_level.rb +13 -25
- data/lib/application_insights/channel/contracts/stack_frame.rb +17 -94
- data/lib/application_insights/channel/contracts/user.rb +19 -104
- data/lib/application_insights/channel/event.rb +68 -64
- data/lib/application_insights/channel/queue_base.rb +65 -62
- data/lib/application_insights/channel/sender_base.rb +79 -72
- data/lib/application_insights/channel/synchronous_queue.rb +45 -39
- data/lib/application_insights/channel/synchronous_sender.rb +17 -15
- data/lib/application_insights/channel/telemetry_channel.rb +120 -102
- data/lib/application_insights/channel/telemetry_context.rb +85 -68
- data/lib/application_insights/rack/track_request.rb +87 -84
- data/lib/application_insights/telemetry_client.rb +229 -217
- data/lib/application_insights/unhandled_exception.rb +49 -47
- data/lib/application_insights/version.rb +3 -3
- data/test/application_insights.rb +8 -9
- data/test/application_insights/channel/contracts/test_application.rb +44 -44
- data/test/application_insights/channel/contracts/test_cloud.rb +44 -0
- data/test/application_insights/channel/contracts/test_data.rb +44 -44
- data/test/application_insights/channel/contracts/test_data_point.rb +109 -109
- data/test/application_insights/channel/contracts/test_device.rb +200 -200
- data/test/application_insights/channel/contracts/test_envelope.rb +209 -209
- data/test/application_insights/channel/contracts/test_event_data.rb +62 -62
- data/test/application_insights/channel/contracts/test_exception_data.rb +111 -111
- data/test/application_insights/channel/contracts/test_exception_details.rb +106 -106
- data/test/application_insights/channel/contracts/test_internal.rb +44 -44
- data/test/application_insights/channel/contracts/test_location.rb +70 -31
- data/test/application_insights/channel/contracts/test_message_data.rb +66 -66
- data/test/application_insights/channel/contracts/test_metric_data.rb +50 -50
- data/test/application_insights/channel/contracts/test_operation.rb +109 -96
- data/test/application_insights/channel/contracts/test_page_view_data.rb +88 -88
- data/test/application_insights/channel/contracts/test_remote_dependency_data.rb +209 -209
- data/test/application_insights/channel/contracts/test_request_data.rb +153 -153
- data/test/application_insights/channel/contracts/test_session.rb +57 -57
- data/test/application_insights/channel/contracts/test_stack_frame.rb +83 -83
- data/test/application_insights/channel/contracts/test_user.rb +96 -83
- data/test/application_insights/channel/test_asynchronous_queue.rb +47 -47
- data/test/application_insights/channel/test_asynchronous_sender.rb +80 -80
- data/test/application_insights/channel/test_event.rb +52 -52
- data/test/application_insights/channel/test_queue_base.rb +88 -88
- data/test/application_insights/channel/test_sender_base.rb +87 -87
- data/test/application_insights/channel/test_synchronous_queue.rb +27 -27
- data/test/application_insights/channel/test_synchronous_sender.rb +10 -10
- data/test/application_insights/channel/test_telemetry_channel.rb +126 -102
- data/test/application_insights/channel/test_telemetry_context.rb +82 -74
- data/test/application_insights/mock_sender.rb +37 -37
- data/test/application_insights/rack/test_track_request.rb +142 -139
- data/test/application_insights/test_telemetry_client.rb +133 -123
- data/test/application_insights/test_unhandled_exception.rb +23 -24
- metadata +23 -33
@@ -1,15 +1,17 @@
|
|
1
|
-
require_relative 'sender_base'
|
2
|
-
|
3
|
-
module ApplicationInsights
|
4
|
-
module Channel
|
5
|
-
# A synchronous sender that works in conjunction with the {SynchronousQueue}.
|
6
|
-
# current instance with the data to send.
|
7
|
-
class SynchronousSender < SenderBase
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
1
|
+
require_relative 'sender_base'
|
2
|
+
|
3
|
+
module ApplicationInsights
|
4
|
+
module Channel
|
5
|
+
# A synchronous sender that works in conjunction with the {SynchronousQueue}.
|
6
|
+
# The queue will call {#send} on the current instance with the data to send.
|
7
|
+
class SynchronousSender < SenderBase
|
8
|
+
SERVICE_ENDPOINT_URI = 'https://dc.services.visualstudio.com/v2/track'
|
9
|
+
# Initializes a new instance of the class.
|
10
|
+
# @param [String] service_endpoint_uri the address of the service to send
|
11
|
+
# telemetry data to.
|
12
|
+
def initialize(service_endpoint_uri = SERVICE_ENDPOINT_URI)
|
13
|
+
super service_endpoint_uri
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,102 +1,120 @@
|
|
1
|
-
require 'time'
|
2
|
-
require_relative 'asynchronous_queue'
|
3
|
-
require_relative 'asynchronous_sender'
|
4
|
-
require_relative 'telemetry_context'
|
5
|
-
require_relative 'synchronous_queue'
|
6
|
-
require_relative 'synchronous_sender'
|
7
|
-
require_relative 'contracts/envelope'
|
8
|
-
require_relative 'contracts/data'
|
9
|
-
require_relative 'contracts/internal'
|
10
|
-
require_relative '../../application_insights/version'
|
11
|
-
|
12
|
-
module ApplicationInsights
|
13
|
-
module Channel
|
14
|
-
# The telemetry channel is responsible for constructing a
|
15
|
-
# data and specified
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# channel.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# @return [
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
1
|
+
require 'time'
|
2
|
+
require_relative 'asynchronous_queue'
|
3
|
+
require_relative 'asynchronous_sender'
|
4
|
+
require_relative 'telemetry_context'
|
5
|
+
require_relative 'synchronous_queue'
|
6
|
+
require_relative 'synchronous_sender'
|
7
|
+
require_relative 'contracts/envelope'
|
8
|
+
require_relative 'contracts/data'
|
9
|
+
require_relative 'contracts/internal'
|
10
|
+
require_relative '../../application_insights/version'
|
11
|
+
|
12
|
+
module ApplicationInsights
|
13
|
+
module Channel
|
14
|
+
# The telemetry channel is responsible for constructing a
|
15
|
+
# {Contracts::Envelope} object from the passed in data and specified
|
16
|
+
# telemetry context.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# require 'application_insights'
|
20
|
+
# channel = ApplicationInsights::Channel::TelemetryChannel.new
|
21
|
+
# event = ApplicationInsights::Channel::Contracts::EventData.new name: 'My event'
|
22
|
+
# channel.write event
|
23
|
+
class TelemetryChannel
|
24
|
+
# Initializes a new instance of the class.
|
25
|
+
# @param [TelemetryContext] context the telemetry context to use when
|
26
|
+
# sending telemetry data.
|
27
|
+
# @param [QueueBase] queue the queue to enqueue the resulting
|
28
|
+
# {Contracts::Envelope} to.
|
29
|
+
def initialize(context=nil, queue=nil)
|
30
|
+
@context = context || TelemetryContext.new
|
31
|
+
@queue = queue || SynchronousQueue.new(SynchronousSender.new)
|
32
|
+
end
|
33
|
+
|
34
|
+
# The context associated with this channel. All {Contracts::Envelope}
|
35
|
+
# objects created by this channel will use this value if it's present or if
|
36
|
+
# none is specified as part of the {#write} call.
|
37
|
+
# @return [TelemetryContext] the context instance
|
38
|
+
# (defaults to: TelemetryContext.new)
|
39
|
+
attr_reader :context
|
40
|
+
|
41
|
+
# The queue associated with this channel. All {Contracts::Envelope} objects
|
42
|
+
# created by this channel will be pushed to this queue.
|
43
|
+
# @return [QueueBase] the queue instance (defaults to: SynchronousQueue.new)
|
44
|
+
attr_reader :queue
|
45
|
+
|
46
|
+
# The sender associated with this channel. This instance will be used to
|
47
|
+
# transmit telemetry to the service.
|
48
|
+
# @return [SenderBase] the sender instance (defaults to: SynchronousSender.new)
|
49
|
+
def sender
|
50
|
+
@queue.sender
|
51
|
+
end
|
52
|
+
|
53
|
+
# Flushes the enqueued data by calling {QueueBase#flush}.
|
54
|
+
def flush
|
55
|
+
@queue.flush
|
56
|
+
end
|
57
|
+
|
58
|
+
# Enqueues the passed in data to the {#queue}. If the caller specifies a
|
59
|
+
# context as well, it will take precedence over the instance in {#context}.
|
60
|
+
# @param [Object] data the telemetry data to send. This will be wrapped in
|
61
|
+
# an {Contracts::Envelope} before being enqueued to the {#queue}.
|
62
|
+
# @param [TelemetryContext] context the override context to use when
|
63
|
+
# constructing the {Contracts::Envelope}.
|
64
|
+
def write(data, context=nil)
|
65
|
+
local_context = context || @context
|
66
|
+
raise ArgumentError, 'Context was required but not provided' unless local_context
|
67
|
+
data_type = data.class.name.gsub(/^.*::/, '')
|
68
|
+
set_properties data, local_context
|
69
|
+
data_attributes = {
|
70
|
+
:base_type => data_type,
|
71
|
+
:base_data => data
|
72
|
+
}
|
73
|
+
envelope_attributes = {
|
74
|
+
:name => 'Microsoft.ApplicationInsights.' + data_type[0..-5],
|
75
|
+
:time => Time.now.iso8601(7),
|
76
|
+
:i_key => local_context.instrumentation_key,
|
77
|
+
:tags => get_tags(local_context),
|
78
|
+
:data => Contracts::Data.new(data_attributes)
|
79
|
+
}
|
80
|
+
envelope = Contracts::Envelope.new envelope_attributes
|
81
|
+
@queue.push(envelope)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def get_tags(context)
|
87
|
+
hash = {}
|
88
|
+
internal_context_attributes = {
|
89
|
+
:sdk_version => 'rb:' + ApplicationInsights::VERSION
|
90
|
+
}
|
91
|
+
internal_context = Contracts::Internal.new internal_context_attributes
|
92
|
+
|
93
|
+
[internal_context,
|
94
|
+
context.application,
|
95
|
+
context.cloud,
|
96
|
+
context.device,
|
97
|
+
context.user,
|
98
|
+
context.session,
|
99
|
+
context.location,
|
100
|
+
context.operation].each { |c| hash.merge!(c.to_h) if c }
|
101
|
+
|
102
|
+
hash.delete_if { |k, v| v.nil? }
|
103
|
+
|
104
|
+
hash
|
105
|
+
end
|
106
|
+
|
107
|
+
def set_properties(data, context)
|
108
|
+
if context.properties
|
109
|
+
properties = data.properties || {}
|
110
|
+
context.properties.each do |key, value|
|
111
|
+
unless properties.key?(key)
|
112
|
+
properties[key] = value
|
113
|
+
end
|
114
|
+
end
|
115
|
+
data.properties = properties
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -1,68 +1,85 @@
|
|
1
|
-
require_relative 'contracts/application'
|
2
|
-
require_relative 'contracts/
|
3
|
-
require_relative 'contracts/
|
4
|
-
require_relative 'contracts/
|
5
|
-
require_relative 'contracts/
|
6
|
-
require_relative 'contracts/
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# context
|
17
|
-
# context.
|
18
|
-
# context.
|
19
|
-
# context.
|
20
|
-
# context.device.
|
21
|
-
# context.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# The
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
#
|
56
|
-
# @return [Contracts::
|
57
|
-
attr_accessor :
|
58
|
-
|
59
|
-
# The
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
1
|
+
require_relative 'contracts/application'
|
2
|
+
require_relative 'contracts/cloud'
|
3
|
+
require_relative 'contracts/device'
|
4
|
+
require_relative 'contracts/user'
|
5
|
+
require_relative 'contracts/session'
|
6
|
+
require_relative 'contracts/operation'
|
7
|
+
require_relative 'contracts/location'
|
8
|
+
|
9
|
+
module ApplicationInsights
|
10
|
+
module Channel
|
11
|
+
# Represents the context for sending telemetry to the
|
12
|
+
# Application Insights service.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# require 'application_insights'
|
16
|
+
# context = ApplicationInsights::Channel::TelemetryContext.new
|
17
|
+
# context.instrumentation_key = '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
18
|
+
# context.application.id = 'My application'
|
19
|
+
# context.application.ver = '1.2.3'
|
20
|
+
# context.device.id = 'My current device'
|
21
|
+
# context.device.oem_name = 'Asus'
|
22
|
+
# context.device.model = 'X31A'
|
23
|
+
# context.device.type = "Other"
|
24
|
+
# context.user.id = 'santa@northpole.net'
|
25
|
+
class TelemetryContext
|
26
|
+
# Initializes a new instance of the class.
|
27
|
+
def initialize
|
28
|
+
@instrumentation_key = nil
|
29
|
+
@application = Contracts::Application.new
|
30
|
+
@cloud = Contracts::Cloud.new
|
31
|
+
@device = Contracts::Device.new
|
32
|
+
@user = Contracts::User.new
|
33
|
+
@session = Contracts::Session.new
|
34
|
+
@operation = Contracts::Operation.new
|
35
|
+
@location = Contracts::Location.new
|
36
|
+
@properties = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
# The instrumentation key that is used to identify which
|
40
|
+
# Application Insights application this data is for.
|
41
|
+
# @return [String] the instrumentation key.
|
42
|
+
attr_accessor :instrumentation_key
|
43
|
+
|
44
|
+
# The application context. This contains properties of the
|
45
|
+
# application you are running.
|
46
|
+
# @return [Contracts::Application] the context object.
|
47
|
+
attr_accessor :application
|
48
|
+
|
49
|
+
# The cloud context. This contains properties of the
|
50
|
+
# cloud role you are generating telemetry for.
|
51
|
+
# @return [Contracts::Cloud] the context object.
|
52
|
+
attr_accessor :cloud
|
53
|
+
|
54
|
+
# The device context. This contains properties of the
|
55
|
+
# device you are running on.
|
56
|
+
# @return [Contracts::Device] the context object.
|
57
|
+
attr_accessor :device
|
58
|
+
|
59
|
+
# The user context. This contains properties of the
|
60
|
+
# user you are generating telemetry for.
|
61
|
+
# @return [Contracts::User] the context object.
|
62
|
+
attr_accessor :user
|
63
|
+
|
64
|
+
# The session context. This contains properties of the
|
65
|
+
# session you are generating telemetry for.
|
66
|
+
# @return [Contracts::Session] the context object.
|
67
|
+
attr_accessor :session
|
68
|
+
|
69
|
+
# The operation context. This contains properties of the
|
70
|
+
# operation you are generating telemetry for.
|
71
|
+
# @return [Contracts::Operation] the context object.
|
72
|
+
attr_accessor :operation
|
73
|
+
|
74
|
+
# The location context. This contains properties of the
|
75
|
+
# location you are generating telemetry from.
|
76
|
+
# @return [Contracts::Location] the context object.
|
77
|
+
attr_accessor :location
|
78
|
+
|
79
|
+
# The property context. This contains free-form properties
|
80
|
+
# that you can add to your telemetry.
|
81
|
+
# @return [Hash<String, String>] the context object.
|
82
|
+
attr_accessor :properties
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,84 +1,87 @@
|
|
1
|
-
require 'rack'
|
2
|
-
require_relative '../channel/contracts/request_data'
|
3
|
-
require_relative '../telemetry_client'
|
4
|
-
|
5
|
-
module ApplicationInsights
|
6
|
-
module Rack
|
7
|
-
# Track every request and sends the request data to Application Insights.
|
8
|
-
class TrackRequest
|
9
|
-
# Initializes a new instance of the class.
|
10
|
-
# @param [Object] app the inner rack application.
|
11
|
-
# @param [String] instrumentation_key to identify which Application Insights
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
sender
|
38
|
-
|
39
|
-
queue
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
1
|
+
require 'rack'
|
2
|
+
require_relative '../channel/contracts/request_data'
|
3
|
+
require_relative '../telemetry_client'
|
4
|
+
|
5
|
+
module ApplicationInsights
|
6
|
+
module Rack
|
7
|
+
# Track every request and sends the request data to Application Insights.
|
8
|
+
class TrackRequest
|
9
|
+
# Initializes a new instance of the class.
|
10
|
+
# @param [Object] app the inner rack application.
|
11
|
+
# @param [String] instrumentation_key to identify which Application Insights
|
12
|
+
# application this data is for.
|
13
|
+
# @param [Fixnum] buffer_size the buffer size and the buffered requests would
|
14
|
+
# send to Application Insights when buffer is full.
|
15
|
+
# @param [Fixnum] send_interval the frequency (in seconds) to check buffer
|
16
|
+
# and send buffered requests to Application Insights if any.
|
17
|
+
def initialize(app, instrumentation_key, buffer_size = 500, send_interval = 60)
|
18
|
+
@app = app
|
19
|
+
@instrumentation_key = instrumentation_key
|
20
|
+
@buffer_size = buffer_size
|
21
|
+
@send_interval = send_interval
|
22
|
+
end
|
23
|
+
|
24
|
+
# Track requests and send data to Application Insights asynchronously.
|
25
|
+
# @param [Hash] env the rack environment.
|
26
|
+
def call(env)
|
27
|
+
start = Time.now
|
28
|
+
begin
|
29
|
+
status, headers, response = @app.call(env)
|
30
|
+
rescue Exception => ex
|
31
|
+
status = 500
|
32
|
+
exception = ex
|
33
|
+
end
|
34
|
+
stop = Time.now
|
35
|
+
|
36
|
+
unless @client
|
37
|
+
sender = @sender || Channel::AsynchronousSender.new
|
38
|
+
sender.send_interval = @send_interval
|
39
|
+
queue = Channel::AsynchronousQueue.new sender
|
40
|
+
queue.max_queue_length = @buffer_size
|
41
|
+
channel = Channel::TelemetryChannel.new nil, queue
|
42
|
+
|
43
|
+
@client = TelemetryClient.new @instrumentation_key, channel
|
44
|
+
end
|
45
|
+
|
46
|
+
request = ::Rack::Request.new env
|
47
|
+
id = rand(16**32).to_s(16)
|
48
|
+
start_time = start.iso8601(7)
|
49
|
+
duration = format_request_duration(stop - start)
|
50
|
+
success = status.to_i < 400
|
51
|
+
options = {
|
52
|
+
:name => "#{request.request_method} #{request.path}",
|
53
|
+
:http_method => request.request_method,
|
54
|
+
:url => request.url
|
55
|
+
}
|
56
|
+
|
57
|
+
@client.track_request id, start_time, duration, status, success, options
|
58
|
+
|
59
|
+
if exception
|
60
|
+
@client.track_exception exception, handled_at: 'Unhandled'
|
61
|
+
raise exception
|
62
|
+
end
|
63
|
+
|
64
|
+
[status, headers, response]
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def sender=(sender)
|
70
|
+
@sender = sender if sender.is_a? Channel::AsynchronousSender
|
71
|
+
end
|
72
|
+
|
73
|
+
def client
|
74
|
+
@client
|
75
|
+
end
|
76
|
+
|
77
|
+
def format_request_duration(duration_seconds)
|
78
|
+
if duration_seconds >= 86400
|
79
|
+
# just return 1 day when it takes more than 1 day which should not happen for requests.
|
80
|
+
return "%02d.%02d:%02d:%02d.%07d" % [1, 0, 0, 0, 0]
|
81
|
+
end
|
82
|
+
|
83
|
+
Time.at(duration_seconds).gmtime.strftime("00.%H:%M:%S.%7N")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|