application_insights 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eec95e24b4930002c21840002367106145b2752a
4
- data.tar.gz: e38cde81727c4a511aaf4b4626c32cd9c3fb5826
3
+ metadata.gz: 34054217c68c9151aca2ca20c8fd90eb395b16bd
4
+ data.tar.gz: f710e913094d5f367301f1625b05cad33833670d
5
5
  SHA512:
6
- metadata.gz: 9c55af8a02ca69adefe4396d6b01f4e4ceeddb68e401b9e903db49054f179ab2dd45f171c81cc80b01c2c45b46d80d0eaa4e719d006e2cb6662976f8eabf48e7
7
- data.tar.gz: 0452d3daa3574d705c26576ea93ca8086ef105559e4ae0f094567ec58be6daee28e5a202cd090bdf7ed51197435a3fad97d5e28039dcc09cbb39eeabfad00042
6
+ metadata.gz: 0e654c167f8964cf88f4a800cc250611435e674a6e52e36431929489f4f4c2381342fe4a1066f87b304f9b00e594b7f54cb0df4d516c490862f2f21ab6b1bd1e
7
+ data.tar.gz: c8f9fecc51ab2db7de24997122df63166f9b840a7cb84696eb9672e5d7db7ea5a8787ee6d9192d15168a1ef85fd3a86ae92f41d3556caca036750f6f5b465f3f
@@ -0,0 +1,11 @@
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.5
6
+ * Add some basic logging when failed to send telemetry to the server
7
+ * Add timestamp as an optional parameter to the TelemetryChannel::write() method
8
+
9
+ ## Version 0.5.4
10
+
11
+ Changelog started after this release.
@@ -122,9 +122,10 @@ module ApplicationInsights
122
122
  break
123
123
  end
124
124
  end
125
- rescue
125
+ rescue Exception => e
126
126
  # Make sure work_thread sets to nil when it terminates abnormally
127
127
  @work_thread = nil
128
+ @logger.error('application_insights') { "Asynchronous sender work thread terminated abnormally: #{e.to_s}" }
128
129
  end
129
130
  end
130
131
  end
@@ -3,6 +3,7 @@ require 'net/http'
3
3
  require 'openssl'
4
4
  require 'stringio'
5
5
  require 'zlib'
6
+ require 'logger'
6
7
 
7
8
  module ApplicationInsights
8
9
  module Channel
@@ -20,6 +21,7 @@ module ApplicationInsights
20
21
  @service_endpoint_uri = service_endpoint_uri
21
22
  @queue = nil
22
23
  @send_buffer_size = 100
24
+ @logger = Logger.new(STDOUT)
23
25
  end
24
26
 
25
27
  # The service endpoint URI where this sender will send data to.
@@ -36,6 +38,9 @@ module ApplicationInsights
36
38
  # @return [Fixnum] the maximum number of items in a telemetry batch.
37
39
  attr_accessor :send_buffer_size
38
40
 
41
+ # The logger for the sender.
42
+ attr_accessor :logger
43
+
39
44
  # Immediately sends the data passed in to {#service_endpoint_uri}. If the
40
45
  # service request fails, the passed in items are pushed back to the {#queue}.
41
46
  # @param [Array<Contracts::Envelope>] data_to_send an array of
@@ -63,6 +68,10 @@ module ApplicationInsights
63
68
 
64
69
  response = http.request(request)
65
70
  http.finish if http.started?
71
+
72
+ if !response.kind_of? Net::HTTPSuccess
73
+ @logger.warn('application_insights') { "Failed to send data: #{response.message}" }
74
+ end
66
75
  end
67
76
 
68
77
  private
@@ -61,9 +61,20 @@ module ApplicationInsights
61
61
  # an {Contracts::Envelope} before being enqueued to the {#queue}.
62
62
  # @param [TelemetryContext] context the override context to use when
63
63
  # constructing the {Contracts::Envelope}.
64
- def write(data, context=nil)
64
+ # @param [Time|String] time the timestamp of the telemetry used to construct the
65
+ # {Contracts::Envelope}.
66
+ def write(data, context=nil, time=nil)
65
67
  local_context = context || @context
66
68
  raise ArgumentError, 'Context was required but not provided' unless local_context
69
+
70
+ if time && time.is_a?(String)
71
+ local_time = time
72
+ elsif time && time.is_a?(Time)
73
+ local_time = time.iso8601(7)
74
+ else
75
+ local_time = Time.now.iso8601(7)
76
+ end
77
+
67
78
  data_type = data.class.name.gsub(/^.*::/, '')
68
79
  set_properties data, local_context
69
80
  data_attributes = {
@@ -72,7 +83,7 @@ module ApplicationInsights
72
83
  }
73
84
  envelope_attributes = {
74
85
  :name => 'Microsoft.ApplicationInsights.' + data_type[0..-5],
75
- :time => Time.now.iso8601(7),
86
+ :time => local_time,
76
87
  :i_key => local_context.instrumentation_key,
77
88
  :tags => get_tags(local_context),
78
89
  :data => Contracts::Data.new(data_attributes)
@@ -217,7 +217,7 @@ module ApplicationInsights
217
217
  :measurements => options[:measurements] || {}
218
218
  )
219
219
 
220
- self.channel.write(data, self.context)
220
+ self.channel.write(data, self.context, start_time)
221
221
  end
222
222
 
223
223
  # Flushes data in the queue. Data in the queue will be sent either immediately
@@ -1,3 +1,3 @@
1
1
  module ApplicationInsights
2
- VERSION = '0.5.4'
2
+ VERSION = '0.5.5'
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require_relative '../../../lib/application_insights/channel/queue_base'
2
2
  require_relative '../../../lib/application_insights/channel/sender_base'
3
+ require_relative '../test_logger'
3
4
  require 'socket'
4
5
  require 'test/unit'
5
6
  require 'thread'
@@ -38,20 +39,26 @@ class TestSenderBase < Test::Unit::TestCase
38
39
 
39
40
  def test_send_works_as_expected_with_400_code
40
41
  thread, port = execute_server '400 BadRequest'
42
+ test_logger = TestLogger.new
41
43
  sender = SenderBase.new 'http://localhost:' + port.to_s + '/track'
44
+ sender.logger = test_logger
42
45
  sender.queue = []
43
46
  sender.send([1, 2])
44
47
  thread.join
45
48
  assert_equal [], sender.queue
49
+ assert_true test_logger.messages.include?('BadRequest')
46
50
  end
47
51
 
48
52
  def test_send_works_as_expected_with_500_code
49
53
  thread, port = execute_server '500 InternalServerError'
54
+ test_logger = TestLogger.new
50
55
  sender = SenderBase.new 'http://localhost:' + port.to_s + '/track'
56
+ sender.logger = test_logger
51
57
  sender.queue = []
52
58
  sender.send([1, 2])
53
59
  thread.join
54
60
  assert_equal [], sender.queue
61
+ assert_true test_logger.messages.include?('InternalServerError')
55
62
  end
56
63
 
57
64
  def execute_server(code)
@@ -3,6 +3,7 @@ require_relative '../../../lib/application_insights/channel/telemetry_context'
3
3
  require_relative '../../../lib/application_insights/channel/synchronous_queue'
4
4
  require_relative '../../../lib/application_insights/channel/synchronous_sender'
5
5
  require 'test/unit'
6
+ require 'time'
6
7
 
7
8
  include ApplicationInsights::Channel
8
9
 
@@ -72,6 +73,46 @@ class TestTelemetryChannel < Test::Unit::TestCase
72
73
  assert_same expected, actual.data.base_data
73
74
  end
74
75
 
76
+ def test_write_custom_timestamp
77
+ queue = MockTelemetryChannelQueue.new SynchronousSender.new
78
+ context = TelemetryContext.new
79
+ context.instrumentation_key = 'instrumentation key'
80
+ channel = TelemetryChannel.new context, queue
81
+ data = MockTelemetryItemData.new
82
+ timestamp = (Time.now - 5).iso8601(7)
83
+
84
+ channel.write data
85
+ actual = queue.queue[0]
86
+ assert_not_equal timestamp, actual.time
87
+
88
+ channel.write data, nil, timestamp
89
+ actual = queue.queue[1]
90
+ assert_equal timestamp, actual.time
91
+ end
92
+
93
+ def test_write_custom_timestamp_accept_string_time_type
94
+ queue = MockTelemetryChannelQueue.new SynchronousSender.new
95
+ context = TelemetryContext.new
96
+ context.instrumentation_key = 'instrumentation key'
97
+ channel = TelemetryChannel.new context, queue
98
+ data = MockTelemetryItemData.new
99
+
100
+ timestamp_string = (Time.now - 5).iso8601(7)
101
+ channel.write data, nil, timestamp_string
102
+ actual = queue.queue[0]
103
+ assert_equal timestamp_string, actual.time
104
+
105
+ timestamp_time = Time.now - 5
106
+ channel.write data, nil, timestamp_time
107
+ actual = queue.queue[1]
108
+ assert_equal timestamp_time.iso8601(7), actual.time
109
+
110
+ timestamp_invalid = {:invalid => "invalid timestamp"}
111
+ channel.write data, nil, timestamp_invalid
112
+ actual = queue.queue[2]
113
+ assert_not_equal timestamp_invalid, actual.time
114
+ end
115
+
75
116
  def test_get_tags_works_as_expected
76
117
  queue = MockTelemetryChannelQueue.new SynchronousSender.new
77
118
  context = TelemetryContext.new
@@ -0,0 +1,10 @@
1
+ class TestLogger < Logger
2
+ def initialize
3
+ @strio = StringIO.new
4
+ super(@strio)
5
+ end
6
+
7
+ def messages
8
+ @strio.string
9
+ end
10
+ end
@@ -4,6 +4,7 @@ require_relative '../../lib/application_insights/channel/synchronous_queue'
4
4
  require_relative '../../lib/application_insights/channel/telemetry_channel'
5
5
  require 'json'
6
6
  require 'test/unit'
7
+ require 'time'
7
8
 
8
9
  include ApplicationInsights
9
10
 
@@ -60,7 +61,7 @@ class TestTelemetryClient < Test::Unit::TestCase
60
61
  assert_equal expected, actual
61
62
  end
62
63
 
63
- def test_track_event_view_works_as_expected
64
+ def test_track_event_works_as_expected
64
65
  client, sender = self.create_client
65
66
  client.track_event 'test'
66
67
  client.flush
@@ -70,7 +71,7 @@ class TestTelemetryClient < Test::Unit::TestCase
70
71
  assert_equal expected, actual
71
72
  end
72
73
 
73
- def test_track_metric_view_works_as_expected
74
+ def test_track_metric_works_as_expected
74
75
  client, sender = self.create_client
75
76
  client.track_metric 'test', 42
76
77
  client.flush
@@ -90,22 +91,26 @@ class TestTelemetryClient < Test::Unit::TestCase
90
91
  assert_equal expected, actual
91
92
  end
92
93
 
93
- def test_track_request_view_works_as_expected
94
+ def test_track_request_works_as_expected
95
+ start_time = Time.now.iso8601
94
96
  client, sender = self.create_client
95
- client.track_request 'test', '2015-01-24T23:10:22.7411910-08:00', '0:00:00:02.0000000','200', true
97
+ client.track_request 'test', start_time, '0:00:00:02.0000000','200', true
96
98
  client.flush
97
- expected = '[{"ver":1,"name":"Microsoft.ApplicationInsights.Request","time":"TIME_PLACEHOLDER","sampleRate":100.0,"tags":{"ai.internal.sdkVersion":"rb:__version__"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"test","startTime":"2015-01-24T23:10:22.7411910-08:00","duration":"0:00:00:02.0000000","responseCode":"200","success":true}}}]'.gsub!(/__version__/, ApplicationInsights::VERSION)
98
- sender.data_to_send[0].time = 'TIME_PLACEHOLDER'
99
+ expected = '[{"ver":1,"name":"Microsoft.ApplicationInsights.Request","time":"__time__","sampleRate":100.0,"tags":{"ai.internal.sdkVersion":"rb:__version__"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"test","startTime":"__time__","duration":"0:00:00:02.0000000","responseCode":"200","success":true}}}]'
100
+ .gsub!(/__version__/, ApplicationInsights::VERSION)
101
+ .gsub!(/__time__/, start_time)
99
102
  actual = sender.data_to_send.to_json
100
103
  assert_equal expected, actual
101
104
  end
102
105
 
103
- def test_track_request_view_works_as_expected_when_request_is_failed
106
+ def test_track_request_works_as_expected_when_request_is_failed
107
+ start_time = Time.now.iso8601
104
108
  client, sender = self.create_client
105
- client.track_request 'test', '2015-01-24T23:10:22.7411910-08:00', '0:00:00:02.0000000','200', false
109
+ client.track_request 'test', start_time, '0:00:00:02.0000000','200', false
106
110
  client.flush
107
- expected = '[{"ver":1,"name":"Microsoft.ApplicationInsights.Request","time":"TIME_PLACEHOLDER","sampleRate":100.0,"tags":{"ai.internal.sdkVersion":"rb:__version__"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"test","startTime":"2015-01-24T23:10:22.7411910-08:00","duration":"0:00:00:02.0000000","responseCode":"200","success":false}}}]'.gsub!(/__version__/, ApplicationInsights::VERSION)
108
- sender.data_to_send[0].time = 'TIME_PLACEHOLDER'
111
+ expected = '[{"ver":1,"name":"Microsoft.ApplicationInsights.Request","time":"__time__","sampleRate":100.0,"tags":{"ai.internal.sdkVersion":"rb:__version__"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"test","startTime":"__time__","duration":"0:00:00:02.0000000","responseCode":"200","success":false}}}]'
112
+ .gsub!(/__version__/, ApplicationInsights::VERSION)
113
+ .gsub!(/__time__/, start_time)
109
114
  actual = sender.data_to_send.to_json
110
115
  assert_equal expected, actual
111
116
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: application_insights
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Microsoft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-24 00:00:00.000000000 Z
11
+ date: 2018-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -90,6 +90,7 @@ extra_rdoc_files: []
90
90
  files:
91
91
  - ".gitignore"
92
92
  - ".travis.yml"
93
+ - CHANGELOG.md
93
94
  - CONTRIBUTING.md
94
95
  - Gemfile
95
96
  - LICENSE.txt
@@ -167,6 +168,7 @@ files:
167
168
  - test/application_insights/channel/test_telemetry_context.rb
168
169
  - test/application_insights/mock_sender.rb
169
170
  - test/application_insights/rack/test_track_request.rb
171
+ - test/application_insights/test_logger.rb
170
172
  - test/application_insights/test_telemetry_client.rb
171
173
  - test/application_insights/test_unhandled_exception.rb
172
174
  homepage: https://github.com/Microsoft/AppInsights-Ruby
@@ -226,6 +228,7 @@ test_files:
226
228
  - test/application_insights/channel/test_telemetry_context.rb
227
229
  - test/application_insights/mock_sender.rb
228
230
  - test/application_insights/rack/test_track_request.rb
231
+ - test/application_insights/test_logger.rb
229
232
  - test/application_insights/test_telemetry_client.rb
230
233
  - test/application_insights/test_unhandled_exception.rb
231
234
  has_rdoc: