appinsights 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f03d2c25eee7d16cd76e865f2d712a06d4943f9a
4
+ data.tar.gz: e3d979812ef53af3bed0545a22818b73679e2a9f
5
+ SHA512:
6
+ metadata.gz: 23adae4aeaadfa9c3acce91dec880c60c0b33c6ba2e6917ebc804aeb99ca5c6002dbabc8b27ad63958db222c022c839b5d55e68365724682f93a77a28948e7bf
7
+ data.tar.gz: e2f65f4b5c0e5df1c524798735e134a2ee56ef5a9ece5b7e3e4bc3b0cafb581ef5007a0ea23f577a1b6ebe035448833da3209a27b1639bf5653072da0d12df15
@@ -0,0 +1,2 @@
1
+ # appinsights
2
+ Microsoft Application Insights AutoInstaller for Ruby frameworks
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'appinsights'
3
+ s.version = '0.0.1'
4
+ s.date = Time.now.strftime('%Y-%m-%d')
5
+ s.summary = 'Application Insights Auto-Installer'
6
+ s.description = 'Application Insights AutoInstaller for Ruby'
7
+ s.authors = ['Emiliano Mancuso']
8
+ s.email = ['emiliano.mancuso@gmail.com']
9
+ s.homepage = 'http://github.com/citrusbyte/appinsights'
10
+ s.license = 'MIT'
11
+
12
+ s.files = Dir[
13
+ 'README.md',
14
+ 'Rakefile',
15
+ 'lib/**/*.rb',
16
+ '*.gemspec',
17
+ 'test/*.*'
18
+ ]
19
+
20
+ s.add_dependency 'toml-rb', '~> 0.2.1'
21
+ s.add_dependency 'application_insights', '~> 0.5.0'
22
+
23
+ s.add_development_dependency 'rack', '~> 1.6', '>= 1.6.0'
24
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'errors'
2
+ require_relative 'context'
3
+ require_relative 'middlewares'
4
+ require_relative 'config_loader'
5
+
6
+ module AppInsights
7
+ if defined?(Rails::VERSION)
8
+ require_relative 'frameworks/rails'
9
+ else
10
+ puts <<-EOS
11
+ Config file not loaded.
12
+ Use AppInsights::ConfigLoader.new root, filename
13
+ to setup the Context and middlewares.
14
+ EOS
15
+
16
+ # Initialize for other frameworks
17
+ #
18
+ # loader = ConfigLoader.new __FILE__
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ require 'toml'
2
+
3
+ module AppInsights
4
+ class ConfigLoader
5
+ attr_reader :settings, :filename
6
+
7
+ def initialize(root, filename = nil)
8
+ @root = root
9
+ @filename = filename || default_file
10
+ @filename = File.join(@root, @filename) if @filename
11
+
12
+ unless @filename && File.exist?(@filename)
13
+ fail AppInsights::ConfigFileNotFound
14
+ end
15
+
16
+ @settings = TOML.load_file @filename
17
+
18
+ AppInsights::Context.configure @settings['ai']
19
+ AppInsights::Middlewares.configure @settings['middleware']
20
+ end
21
+
22
+ private
23
+
24
+ def default_file
25
+ default_paths.compact.find { |path| File.exist? File.join(@root, path) }
26
+ end
27
+
28
+ def default_paths
29
+ @default_paths ||= [
30
+ './config/application_insights.toml',
31
+ './application_insights.toml',
32
+ # ENV['AI_CONFIG_PATH']
33
+ ]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ require 'application_insights'
2
+
3
+ module AppInsights
4
+ class Context
5
+ class << self
6
+ def configure(config = {})
7
+ @context = telemetry_client.context
8
+
9
+ contracts.each do |contract|
10
+ instance = configure_contract(contract.capitalize, config)
11
+ @context.send :"#{contract}=", instance
12
+ end
13
+
14
+ @context.instrumentation_key = config['instrumentation_key']
15
+ @context.properties = extract_custom_properties config
16
+
17
+ @context
18
+ end
19
+
20
+ def telemetry_client
21
+ @client ||= ApplicationInsights::TelemetryClient.new
22
+ end
23
+
24
+ private
25
+
26
+ def configure_contract(contract, config)
27
+ const = ApplicationInsights::Channel::Contracts.const_get contract
28
+
29
+ const.new config[contract.downcase]
30
+ rescue NameError
31
+ nil
32
+ end
33
+
34
+ # Custom properties are defined at [ai] level of the config file.
35
+ def extract_custom_properties(config)
36
+ config.reject { |k, v| k.to_s == 'instrumentation_key' || v.is_a?(Hash) }
37
+ end
38
+
39
+ def contracts
40
+ %w(user device session location operation application)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,4 @@
1
+ module AppInsights
2
+ class UnknownMiddleware < StandardError; end
3
+ class ConfigFileNotFound < StandardError; end
4
+ end
@@ -0,0 +1,11 @@
1
+ module AppInsights
2
+ class Railtie < Rails::Railtie
3
+ initializer 'ai_agent.start_plugin' do |_app|
4
+ AppInsights::ConfigLoader.new Rails.root
5
+
6
+ AppInsights::Middlewares.enabled.each do |middleware, args|
7
+ config.app_middleware.use middleware, *args.values
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require_relative 'middlewares/exception_handling'
2
+
3
+ module AppInsights
4
+ class Middlewares
5
+ class << self
6
+ def configure(settings = {})
7
+ @settings = settings || {}
8
+ @enabled_middlewares = constantize_middlewares
9
+ end
10
+
11
+ def enabled
12
+ @enabled_middlewares || []
13
+ end
14
+
15
+ def settings
16
+ @settings || {}
17
+ end
18
+
19
+ private
20
+
21
+ def constantize_middlewares
22
+ constants = @settings.map do |middleware|
23
+ begin
24
+ if middleware['enabled']
25
+ c = const_get middleware['name']
26
+ args = middleware['initialize'] || {}
27
+
28
+ [c, args]
29
+ end
30
+ rescue NameError => e
31
+ # FIXME: Log, ignore or fail?
32
+ raise AppInsights::UnknownMiddleware, e.message
33
+ end
34
+ end
35
+
36
+ constants.compact.uniq
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ require 'application_insights'
2
+
3
+ module AppInsights
4
+ class ExceptionHandling
5
+ def initialize(app)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ @app.call env
11
+ rescue Exception => exception
12
+ tc = AppInsights::Context.telemetry_client
13
+ tc.track_exception exception
14
+
15
+ raise exception
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ task :default => :test
2
+
3
+ desc 'Run tests'
4
+ task :test do
5
+ require File.expand_path("./test/helper", File.dirname(__FILE__))
6
+
7
+ Dir["test/**/*_test.rb"].each { |file| load file }
8
+ end
@@ -0,0 +1,56 @@
1
+ require_relative 'helper'
2
+ require 'application_insights'
3
+
4
+ describe AppInsights::ConfigLoader do
5
+ before do
6
+ AppInsights::Context.tap do |klass|
7
+ klass.instance_variable_set :@context, nil
8
+ klass.instance_variable_set :@client, nil
9
+ end
10
+
11
+ AppInsights::Middlewares.tap do |klass|
12
+ klass.instance_variable_set :@settings, nil
13
+ klass.instance_variable_set :@enabled_middlewares, nil
14
+ end
15
+ end
16
+
17
+ describe 'initialize' do
18
+ it 'fails when there is no configuration file' do
19
+ assert_raises AppInsights::ConfigFileNotFound do
20
+ AppInsights::ConfigLoader.new '.'
21
+ end
22
+ end
23
+
24
+ it 'loads the config file from the default path' do
25
+ loader = AppInsights::ConfigLoader.new './test'
26
+
27
+ deny loader.settings.empty?
28
+ end
29
+
30
+ it 'loads the config file from the given filename' do
31
+ loader = AppInsights::ConfigLoader.new './test/config', 'non_default_file.toml'
32
+
33
+ deny loader.settings.empty?
34
+ end
35
+
36
+ it 'autoconfigure the Context and middlewares' do
37
+ tc = AppInsights::Context.telemetry_client
38
+ settings = AppInsights::Middlewares.settings
39
+ middlewares = AppInsights::Middlewares.enabled
40
+
41
+ deny tc.context.instrumentation_key
42
+ assert settings.empty?
43
+ assert middlewares.empty?
44
+
45
+ AppInsights::ConfigLoader.new './test'
46
+
47
+ tc = AppInsights::Context.telemetry_client
48
+ settings = AppInsights::Middlewares.settings
49
+ middlewares = AppInsights::Middlewares.enabled
50
+
51
+ assert tc.context.instrumentation_key
52
+ deny settings.empty?
53
+ deny middlewares.empty?
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'helper'
2
+
3
+ describe AppInsights::Context do
4
+ before do
5
+ @configs = {
6
+ 'instrumentation_key' => 'a_key',
7
+ 'custom' => 4,
8
+ 'properties' => 'belong to the context',
9
+ 'application' => {
10
+ 'ver' => '0.0.1'
11
+ },
12
+ 'device' => {
13
+ 'id' => 'asdfghjkl1',
14
+ 'os' => 'OSX'
15
+ }
16
+ }
17
+ end
18
+
19
+ describe 'configure' do
20
+ it 'returns a ApplicationInsights::Channel::TelemetryContext object' do
21
+ context = AppInsights::Context.configure
22
+
23
+ assert_equal ApplicationInsights::Channel::TelemetryContext, context.class
24
+ end
25
+
26
+ it 'accepts a hash to set Context values' do
27
+ context = AppInsights::Context.configure @configs
28
+
29
+ assert_equal 'a_key', context.instrumentation_key
30
+ assert_equal '0.0.1', context.application.ver
31
+ end
32
+ end
33
+
34
+ describe 'telemetry_client' do
35
+ before do
36
+ AppInsights::Context.configure @configs
37
+
38
+ @client = AppInsights::Context.telemetry_client
39
+ end
40
+
41
+ it 'returns an instance of ApplicationInsights::TelemetryClient' do
42
+ assert_equal ApplicationInsights::TelemetryClient, @client.class
43
+ end
44
+
45
+ it 'sets the context to the Telemetry Client' do
46
+ assert_equal 'a_key', @client.context.instrumentation_key
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
2
+
3
+ require 'minitest/autorun'
4
+ require 'appinsights'
5
+
6
+ def deny(condition, message = 'Expected condition to be unsatisfied')
7
+ assert !condition, message
8
+ end
@@ -0,0 +1,63 @@
1
+ require_relative 'helper'
2
+
3
+ describe AppInsights::Middlewares do
4
+ before do
5
+ @configs = [
6
+ {
7
+ 'name' => 'AppInsights::ExceptionHandling',
8
+ 'enabled' => true
9
+ },
10
+ {
11
+ 'name' => 'ApplicationInsights::Rack::TrackRequest',
12
+ 'enabled' => false
13
+ }
14
+ ]
15
+ end
16
+
17
+ after do
18
+ AppInsights::Middlewares.tap do |klass|
19
+ klass.instance_variable_set :@settings, nil
20
+ klass.instance_variable_set :@enabled_middlewares, nil
21
+ end
22
+ end
23
+
24
+ describe 'enabled' do
25
+ it 'returns the middlewares enabled' do
26
+ AppInsights::Middlewares.configure @configs
27
+
28
+ enabled = AppInsights::Middlewares.enabled
29
+ expected = [[AppInsights::ExceptionHandling, {}]]
30
+
31
+ deny enabled.empty?
32
+ assert_equal expected, enabled
33
+ end
34
+
35
+ it 'returns an empty Array if it was not configured' do
36
+ assert AppInsights::Middlewares.enabled.empty?
37
+ end
38
+ end
39
+
40
+ describe 'settings' do
41
+ it 'returns the settings loaded' do
42
+ AppInsights::Middlewares.configure @configs
43
+
44
+ settings = AppInsights::Middlewares.settings
45
+
46
+ deny settings.empty?
47
+ assert_equal @configs, settings
48
+ end
49
+
50
+ it 'returns an empty Hash if it was not configured' do
51
+ assert AppInsights::Middlewares.settings.empty?
52
+ end
53
+ end
54
+
55
+ describe 'configure' do
56
+ it 'accepts one or zero params' do
57
+ AppInsights::Middlewares.configure
58
+
59
+ assert_equal({}, AppInsights::Middlewares.settings)
60
+ assert_equal([], AppInsights::Middlewares.enabled)
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appinsights
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Emiliano Mancuso
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: toml-rb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: application_insights
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.6.0
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '1.6'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.6.0
61
+ description: Application Insights AutoInstaller for Ruby
62
+ email:
63
+ - emiliano.mancuso@gmail.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - README.md
69
+ - appinsights.gemspec
70
+ - lib/appinsights.rb
71
+ - lib/config_loader.rb
72
+ - lib/context.rb
73
+ - lib/errors.rb
74
+ - lib/frameworks/rails.rb
75
+ - lib/middlewares.rb
76
+ - lib/middlewares/exception_handling.rb
77
+ - rakefile
78
+ - test/config_loader_test.rb
79
+ - test/context_test.rb
80
+ - test/helper.rb
81
+ - test/middlewares_test.rb
82
+ homepage: http://github.com/citrusbyte/appinsights
83
+ licenses:
84
+ - MIT
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.4.5
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Application Insights Auto-Installer
106
+ test_files: []