Added documentattion for channel classes
Other changes - Hooked in Yard into Rake - Small cahnges to README.md for it to look better in the generated docs - Added additional development dependencies to gemfile
This commit is contained in:
Родитель
1cc4573634
Коммит
60af91bfd2
22
README.md
22
README.md
|
@ -27,7 +27,7 @@ Once installed, you can send telemetry to Application Insights. Here are a few s
|
|||
>**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.
|
||||
|
||||
|
||||
**Sending a simple event telemetry item**
|
||||
###Sending a simple event telemetry item###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -36,7 +36,7 @@ tc.track_event 'My event'
|
|||
tc.flush
|
||||
```
|
||||
|
||||
**Sending an event telemetry item with custom properties and measurements**
|
||||
###Sending an event telemetry item with custom properties and measurements###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -45,7 +45,7 @@ tc.track_event 'My event', :properties => { 'custom property' => 'some value' },
|
|||
tc.flush
|
||||
```
|
||||
|
||||
**Sending a trace telemetry item with custom properties**
|
||||
###Sending a trace telemetry item with custom properties###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -54,7 +54,7 @@ tc.track_trace 'My trace statement', :properties => { 'custom property' => 'some
|
|||
tc.flush
|
||||
```
|
||||
|
||||
**Sending a metric telemetry item (without and with optional values)**
|
||||
###Sending a metric telemetry item (without and with optional values)###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -65,7 +65,7 @@ tc.track_metric 'My metric', 42, :kind => ApplicationInsights::Channel::Contract
|
|||
tc.flush
|
||||
```
|
||||
|
||||
**Sending an exception telemetry item with custom properties and measurements**
|
||||
###Sending an exception telemetry item with custom properties and measurements###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -78,7 +78,7 @@ end
|
|||
tc.flush
|
||||
```
|
||||
|
||||
**Configuring context for a telemetry client instance**
|
||||
###Configuring context for a telemetry client instance###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -94,7 +94,7 @@ tc.track_trace 'My trace with context'
|
|||
tc.flush
|
||||
```
|
||||
|
||||
**Configuring synchronous (default) channel properties**
|
||||
###Configuring synchronous (default) channel properties###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
tc = ApplicationInsights::TelemetryClient.new
|
||||
|
@ -104,24 +104,24 @@ tc.channel.queue.max_queue_length = 10
|
|||
tc.channel.sender.send_buffer_size = 5
|
||||
```
|
||||
|
||||
**Configuring an asynchronous channel instead of the synchronous default**
|
||||
###Configuring an asynchronous channel instead of the synchronous default###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
sender = ApplicationInsights::Channel::AsynchronousSender.new
|
||||
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
|
||||
channel = ApplicationInsights::Channel::TelemetryChannel nil, queue
|
||||
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
|
||||
tc = ApplicationInsights::TelemetryClient.new 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**
|
||||
###Configuring asynchronous channel properties###
|
||||
```ruby
|
||||
require 'application_insights'
|
||||
sender = ApplicationInsights::Channel::AsynchronousSender.new
|
||||
queue = ApplicationInsights::Channel::AsynchronousQueue.new sender
|
||||
channel = ApplicationInsights::Channel::TelemetryChannel nil, queue
|
||||
channel = ApplicationInsights::Channel::TelemetryChannel.new nil, queue
|
||||
tc = ApplicationInsights::TelemetryClient.new channel
|
||||
# flush telemetry if we have 10 or more telemetry items in our queue
|
||||
tc.channel.queue.max_queue_length = 10
|
||||
|
|
7
Rakefile
7
Rakefile
|
@ -1,5 +1,6 @@
|
|||
require "bundler/gem_tasks"
|
||||
require 'rake/testtask'
|
||||
require 'yard'
|
||||
|
||||
Rake::TestTask.new do |test|
|
||||
test.libs << 'test'
|
||||
|
@ -7,4 +8,8 @@ Rake::TestTask.new do |test|
|
|||
test.verbose = true
|
||||
end
|
||||
|
||||
task :default => [ :test, :build ]
|
||||
YARD::Rake::YardocTask.new do |task|
|
||||
task.files = ['lib/**/*.rb', '-', 'LICENSE.txt', 'README.md']
|
||||
end
|
||||
|
||||
task :default => [ :test, :build, :yard ]
|
|
@ -22,4 +22,6 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_development_dependency 'bundler', '~> 1.7'
|
||||
spec.add_development_dependency 'rake', '~> 10.0'
|
||||
spec.add_development_dependency 'yard', '~> 0.8.7.6'
|
||||
spec.add_development_dependency 'redcarpet', '~> 3.2.2'
|
||||
end
|
||||
|
|
|
@ -6,6 +6,18 @@ module ApplicationInsights
|
|||
# An asynchronous queue for use in conjunction with the {AsynchronousSender}. The queue
|
||||
# will notify the sender that it needs to pick up items when it reaches {#max_queue_length}, or when the consumer
|
||||
# calls {#flush} via the {#flush_notification} event.
|
||||
# @example
|
||||
# require 'application_insights'
|
||||
# require 'thread'
|
||||
# queue = ApplicationInsights::Channel::AsynchronousQueue.new nil
|
||||
# Thread.new do
|
||||
# sleep 1
|
||||
# queue.push 1
|
||||
# queue.flush
|
||||
# end
|
||||
# queue.flush_notification.wait
|
||||
# queue.flush_notification.clear
|
||||
# result = queue.pop
|
||||
class AsynchronousQueue < QueueBase
|
||||
# Initializes a new instance of the class.
|
||||
# @param [SenderBase] sender the sender object that will be used in conjunction with this queue. In addition to
|
||||
|
@ -26,13 +38,13 @@ module ApplicationInsights
|
|||
# @param [Contracts::Envelope] item the telemetry envelope object to send to the service.
|
||||
def push(item)
|
||||
super item
|
||||
@sender.start
|
||||
@sender.start if @sender
|
||||
end
|
||||
|
||||
# Flushes the current queue by notifying the {#sender} via the {#flush_notification} event.
|
||||
def flush
|
||||
@flush_notification.set
|
||||
@sender.start
|
||||
@sender.start if @sender
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,17 @@ module ApplicationInsights
|
|||
#
|
||||
# An object of this type managers an internal flag that can be set to true via the {#set} method and reset via the
|
||||
# {#clear} method. Calling the {#wait} method will block until the flag is set to true.
|
||||
# @example
|
||||
# require 'application_insights'
|
||||
# require 'thread'
|
||||
# event = ApplicationInsights::Channel::Event.new
|
||||
# Thread.new do
|
||||
# sleep 1
|
||||
# event.set
|
||||
# end
|
||||
# puts 'Main screen turn on.'
|
||||
# result = event.wait
|
||||
# puts 'All your base are belong to us.'
|
||||
class Event
|
||||
# Initializes a new instance of the class.
|
||||
def initialize
|
||||
|
|
|
@ -2,24 +2,30 @@ require 'thread'
|
|||
|
||||
module ApplicationInsights
|
||||
module Channel
|
||||
# The base class for all queues.
|
||||
# The base class for all types of queues for use in conjunction with an implementation of {SenderBase}. The queue
|
||||
# will notify the sender that it needs to pick up items when it reaches {#max_queue_length}, or when the consumer
|
||||
# calls {#flush}.
|
||||
class QueueBase
|
||||
# Initializes a new instance of the queue class.
|
||||
# Initializes a new instance of the class.
|
||||
# @param [SenderBase] sender the sender object that will be used in conjunction with this queue.
|
||||
def initialize(sender)
|
||||
raise ArgumentError, 'Sender was required but not provided' unless sender
|
||||
@queue = Queue.new
|
||||
@max_queue_length = 500
|
||||
@sender = sender
|
||||
@sender.queue = self
|
||||
@sender.queue = self if sender
|
||||
end
|
||||
|
||||
# Gets or sets the maximum number of items that will be held by the queue before we force a send.
|
||||
# The maximum number of items that will be held by the queue before the queue will call the {#flush} method.
|
||||
# @return [Fixnum] the maximum queue size. (defaults to: 500)
|
||||
attr_accessor :max_queue_length
|
||||
|
||||
# Gets the sender associated with this queue
|
||||
# The sender that is associated with this queue that this queue will use to send data to the service.
|
||||
# @return [SenderBase] the sender object.
|
||||
attr_reader :sender
|
||||
|
||||
# Adds a single item to the queue.
|
||||
# Adds the passed in item object to the queue and calls {#flush} if the size of the queue is larger
|
||||
# than {#max_queue_length}. This method does nothing if the passed in item is nil.
|
||||
# @param [Contracts::Envelope] item the telemetry envelope object to send to the service.
|
||||
def push(item)
|
||||
unless item
|
||||
return
|
||||
|
@ -31,7 +37,8 @@ module ApplicationInsights
|
|||
end
|
||||
end
|
||||
|
||||
# Gets a single item from the queue. If no item is available, return nil.
|
||||
# Pops a single item from the queue and returns it. If the queue is empty, this method will return nil.
|
||||
# @return [Contracts::Envelope] a telemetry envelope object or nil if the queue is empty.
|
||||
def pop
|
||||
begin
|
||||
return @queue.pop(TRUE)
|
||||
|
@ -40,7 +47,8 @@ module ApplicationInsights
|
|||
end
|
||||
end
|
||||
|
||||
# Flushes the current queue to the passed in sender.
|
||||
# Flushes the current queue by notifying the {#sender}. This method needs to be overridden by a concrete
|
||||
# implementations of the queue class.
|
||||
def flush
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,9 +3,13 @@ require 'net/http'
|
|||
|
||||
module ApplicationInsights
|
||||
module Channel
|
||||
# The base class for all of our senders.
|
||||
# The base class for all types of senders for use in conjunction with an implementation of {QueueBase}. The queue
|
||||
# will notify the sender that it needs to pick up items. The concrete sender implementation will listen to these
|
||||
# notifications and will pull items from the queue using {QueueBase#pop} getting at most {#send_buffer_size} items.
|
||||
# it will then call {#send} using the list of items pulled from the queue.
|
||||
class SenderBase
|
||||
# Initializes a new instance of the sender class.
|
||||
# Initializes a new instance of the class.
|
||||
# @param [String] service_endpoint_uri the address of the service to send telemetry data to.
|
||||
def initialize(service_endpoint_uri)
|
||||
raise ArgumentError, 'Service endpoint URI was required but not provided' unless service_endpoint_uri
|
||||
@service_endpoint_uri = service_endpoint_uri
|
||||
|
@ -13,16 +17,23 @@ module ApplicationInsights
|
|||
@send_buffer_size = 100
|
||||
end
|
||||
|
||||
# Gets the service endpoint URI property. This is where we send data to.
|
||||
# The service endpoint URI where this sender will send data to.
|
||||
# @return [String] the service endpoint URI.
|
||||
attr_accessor :service_endpoint_uri
|
||||
|
||||
# The queue that we will be draining
|
||||
# The queue that this sender is draining. While {SenderBase} doesn't implement any means of doing so, derivations
|
||||
# of this class do.
|
||||
# @return [QueueBase] the queue instance that this sender is draining.
|
||||
attr_accessor :queue
|
||||
|
||||
# Gets or sets the buffer size for a single batch of telemetry. This is the maximum number of items in a single service request we are going to send.
|
||||
# The buffer size for a single batch of telemetry. This is the maximum number of items in a single service
|
||||
# request that this sender is going to send.
|
||||
# @return [Fixnum] the maximum number of items in a telemetry batch.
|
||||
attr_accessor :send_buffer_size
|
||||
|
||||
# Sends the data to send list to the service immediately.
|
||||
# Immediately sends the data passed in to {#service_endpoint_uri}. If the service request fails, the passed in items
|
||||
# are pushed back to the {#queue}.
|
||||
# @param [Array<Contracts::Envelope>] data_to_send an array of {Contracts::Envelope} objects to send to the service.
|
||||
def send(data_to_send)
|
||||
uri = URI(@service_endpoint_uri)
|
||||
request = Net::HTTP::Post.new(uri.path, { 'Accept' => 'application/json', 'Content-Type' => 'application/json; charset=utf-8' })
|
||||
|
|
|
@ -2,25 +2,36 @@ require_relative 'queue_base'
|
|||
|
||||
module ApplicationInsights
|
||||
module Channel
|
||||
# A synchronous queue for use in conjunction with the SynchronousSender. The queue will flush either when it reaches max_queue_length or when someone calls flush().
|
||||
# A synchronous queue for use in conjunction with the {SynchronousSender}. The queue
|
||||
# will call {SenderBase#send} when it reaches {#max_queue_length}, or when the consumer
|
||||
# calls {#flush}.
|
||||
# @example
|
||||
# require 'application_insights'
|
||||
# require 'thread'
|
||||
# queue = ApplicationInsights::Channel::SynchronousQueue.new nil
|
||||
# queue.max_queue_length = 1
|
||||
# queue.push 1
|
||||
class SynchronousQueue < QueueBase
|
||||
# Initializes a new instance of the synchronous queue class.
|
||||
# Initializes a new instance of the class.
|
||||
# @param [SenderBase] sender the sender object that will be used in conjunction with this queue.
|
||||
def initialize(sender)
|
||||
super sender
|
||||
end
|
||||
|
||||
# Flushes the current queue to the passed in sender.
|
||||
# Flushes the current queue by by calling {#sender}'s {SenderBase#send} method.
|
||||
def flush
|
||||
local_sender = @sender
|
||||
return unless local_sender
|
||||
while TRUE
|
||||
# get at most send_buffer_size items and send them
|
||||
data = []
|
||||
while data.length < @sender.send_buffer_size
|
||||
while data.length < local_sender.send_buffer_size
|
||||
item = pop()
|
||||
break if not item
|
||||
data.push item
|
||||
end
|
||||
break if data.length == 0
|
||||
@sender.send(data)
|
||||
local_sender.send(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,9 +2,11 @@ require_relative 'sender_base'
|
|||
|
||||
module ApplicationInsights
|
||||
module Channel
|
||||
# A synchronous sender that works in conjunction with SynchronousQueue.
|
||||
# A synchronous sender that works in conjunction with the {SynchronousQueue}. The queue will call {#send} on the
|
||||
# current instance with the data to send.
|
||||
class SynchronousSender < SenderBase
|
||||
# Initializes a new instance of the synchronous sender class.
|
||||
# Initializes a new instance of the class.
|
||||
# @param [String] service_endpoint_uri the address of the service to send telemetry data to.
|
||||
def initialize(service_endpoint_uri='https://dc.services.visualstudio.com/v2/track')
|
||||
super service_endpoint_uri
|
||||
end
|
||||
|
|
|
@ -9,31 +9,48 @@ require_relative 'contracts/internal'
|
|||
|
||||
module ApplicationInsights
|
||||
module Channel
|
||||
# The telemetry channel is responsible for constructing an envelope an sending it.
|
||||
# The telemetry channel is responsible for constructing a {Contracts::Envelope} object from the passed in
|
||||
# data and specified telemetry context.
|
||||
# @example
|
||||
# require 'application_insights'
|
||||
# channel = ApplicationInsights::Channel::TelemetryChannel.new
|
||||
# event = ApplicationInsights::Channel::Contracts::EventData.new :name => 'My event'
|
||||
# channel.write event
|
||||
class TelemetryChannel
|
||||
# Initializes a new instance of the telemetry channel class.
|
||||
# Initializes a new instance of the class.
|
||||
# @param [TelemetryContext] context the telemetry context to use when sending telemetry data.
|
||||
# @param [QueueBase] queue the queue to enqueue the resulting {Contracts::Envelope} to.
|
||||
def initialize(context=nil, queue=nil)
|
||||
@context = context || TelemetryContext.new
|
||||
@queue = queue || SynchronousQueue.new(SynchronousSender.new)
|
||||
end
|
||||
|
||||
# Gets the context associated with this channel.
|
||||
# The context associated with this channel. All {Contracts::Envelope} objects created by this channel will use
|
||||
# this value if it's present or if none is specified as part of the {#write} call.
|
||||
# @return [TelemetryContext] the context instance (defaults to: TelemetryContext.new)
|
||||
attr_reader :context
|
||||
|
||||
# Gets the queue associated with this channel.
|
||||
# The queue associated with this channel. All {Contracts::Envelope} objects created by this channel will be
|
||||
# pushed to this queue.
|
||||
# @return [QueueBase] the queue instance (defaults to: SynchronousQueue.new)
|
||||
attr_reader :queue
|
||||
|
||||
# Gets the sender associated with this channel.
|
||||
# The sender associated with this channel. This instance will be used to transmit telemetry to the service.
|
||||
# @return [SenderBase] the sender instance (defaults to: SynchronousSender.new)
|
||||
def sender
|
||||
@queue.sender
|
||||
end
|
||||
|
||||
# Flushes the current queue.
|
||||
# Flushes the enqueued data by calling {QueueBase#flush}.
|
||||
def flush
|
||||
@queue.flush
|
||||
end
|
||||
|
||||
# Writes the passed in data to the sending queue.
|
||||
# Enqueues the passed in data to the {#queue}. If the caller specifies a context as well, it will take precedence
|
||||
# over the instance in {#context}.
|
||||
# @param [Object] data the telemetry data to send. This will be wrapped in an {Contracts::Envelope} before being
|
||||
# enqueued to the {#queue}.
|
||||
# @param [TelemetryContext] context the override context to use when constructing the {Contracts::Envelope}.
|
||||
def write(data, context=nil)
|
||||
local_context = context || @context
|
||||
raise ArgumentError, 'Context was required but not provided' unless local_context
|
||||
|
|
|
@ -7,9 +7,20 @@ require_relative 'contracts/location'
|
|||
|
||||
module ApplicationInsights
|
||||
module Channel
|
||||
# Represents a context for sending telemetry to the Application Insights service.
|
||||
# Represents the context for sending telemetry to the Application Insights service.
|
||||
# @example
|
||||
# require 'application_insights'
|
||||
# context = ApplicationInsights::Channel::TelemetryContext.new
|
||||
# context.instrumentation_key = '<YOUR INSTRUMENTATION KEY GOES HERE>'
|
||||
# context.application.id = 'My application'
|
||||
# context.application.ver = '1.2.3'
|
||||
# context.device.id = 'My current device'
|
||||
# context.device.oem_name = 'Asus'
|
||||
# context.device.model = 'X31A'
|
||||
# context.device.type = "Other"
|
||||
# context.user.id = 'santa@northpole.net'
|
||||
class TelemetryContext
|
||||
# Initializes a new instance of the TelemetryContext class.
|
||||
# Initializes a new instance of the class.
|
||||
def initialize
|
||||
@instrumentation_key = nil
|
||||
@application = Contracts::Application.new
|
||||
|
@ -21,28 +32,36 @@ module ApplicationInsights
|
|||
@properties = {}
|
||||
end
|
||||
|
||||
# Gets or sets the instrumentation key.
|
||||
# The instrumentation key that is used to identify which Application Insights application this data is for.
|
||||
# @return [String] the instrumentation key.
|
||||
attr_accessor :instrumentation_key
|
||||
|
||||
# Gets or sets the application context.
|
||||
# The application context. This contains properties of the application you are running.
|
||||
# @return [Contracts::Application] the context object.
|
||||
attr_accessor :application
|
||||
|
||||
# Gets or sets the device context.
|
||||
# The device context. This contains properties of the device you are running on.
|
||||
# @return [Contracts::Device] the context object.
|
||||
attr_accessor :device
|
||||
|
||||
# Gets or sets the user context.
|
||||
# The user context. This contains properties of the user you are generating telemetry for.
|
||||
# @return [Contracts::User] the context object.
|
||||
attr_accessor :user
|
||||
|
||||
# Gets or sets the session context.
|
||||
# The session context. This contains properties of the session you are generating telemetry for.
|
||||
# @return [Contracts::Session] the context object.
|
||||
attr_accessor :session
|
||||
|
||||
# Gets or sets the operation context.
|
||||
# The operation context. This contains properties of the operation you are generating telemetry for.
|
||||
# @return [Contracts::Operation] the context object.
|
||||
attr_accessor :operation
|
||||
|
||||
# Gets or sets the location context.
|
||||
# The location context. This contains properties of the location you are generating telemetry from.
|
||||
# @return [Contracts::Location] the context object.
|
||||
attr_accessor :location
|
||||
|
||||
# Gets a dictionary of application-defined property values.
|
||||
# The property context. This contains free-form properties that you can add to your telemetry.
|
||||
# @return [Hash<String, String>] the context object.
|
||||
attr_reader :properties
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче