appinsights 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []