alacrity-rails 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: 6d1deb83151619090305c93c971b07df5b0d2145
4
+ data.tar.gz: ba981ea6ea88638b648bfcc5a9707b32ae1b500c
5
+ SHA512:
6
+ metadata.gz: df2ef698abaf8b5ecabd244df82f438593134f95226bea65cf109fecb2b6013ac831d81b48ffdbdc45529bb6147fc951511be5644953089d4719cd1ad3d9eee4
7
+ data.tar.gz: 66861c9368055e355c1ff16239771226f05215b7af098c23c2c528efdca48e9805895df8109adce30d711ffd9603ddee639d7878c955f191e1112e9d6598990a
data/LICENSE ADDED
@@ -0,0 +1 @@
1
+ Copyright 2016 Alacrity, LLC
@@ -0,0 +1,34 @@
1
+ # Overview
2
+
3
+ ## Alacrity Rails
4
+
5
+ The alacrity-rails gem collects runtime data from your Ruby on Rails app.
6
+
7
+ ## Compatibility
8
+
9
+ The alacrity-rails gem officially supports Ruby 2.0+.
10
+
11
+ It will work automatically with Rails 4 and up.
12
+
13
+ ## Installation
14
+
15
+ 1. Sign up for an account on https://www.alacrityapp.com
16
+ 2. Add the `alacrity-rails` gem to your `Gemfile`
17
+
18
+ ```
19
+ gem 'alacrity-rails', group: :production
20
+ ```
21
+
22
+ 3. Set the ALACRITY_API_TOKEN in your app's environment
23
+ 4. Deploy with the gem installed
24
+ 5. You'll begin seeing data on https://alacrityapp.com shortly after your site receives traffic.
25
+
26
+ ## Server Configuration Overrides
27
+
28
+ ### ALACRITY_API_TOKEN
29
+
30
+ You can find this on the settings page for your app on https://alacrityapp.com
31
+
32
+ ### ALACRITY_ENVIRONMENT
33
+
34
+ By default Alacrity will use `Rails.env` to determine the server environment. You can override this to any string value (like `staging`).
@@ -0,0 +1,12 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+
4
+ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
5
+ require "appraisal/task"
6
+ Appraisal::Task.new
7
+ task default: :appraisal
8
+ else
9
+ require "rspec/core/rake_task"
10
+ RSpec::Core::RakeTask.new
11
+ task default: :spec
12
+ end
@@ -0,0 +1,22 @@
1
+ if defined?(Rake)
2
+ require 'rake'
3
+ Dir[File.join(File.dirname(__FILE__), 'tasks', '**/*.rake')].each { |rake| load rake }
4
+ end
5
+
6
+ module AlacrityRails
7
+ autoload :Config, 'alacrity-rails/config'
8
+ autoload :ConnectionTester, 'alacrity-rails/connection_tester'
9
+ autoload :Client, 'alacrity-rails/client'
10
+ autoload :Middleware, 'alacrity-rails/middleware'
11
+ autoload :ServerConfig, 'alacrity-rails/server_config'
12
+ autoload :VERSION, 'alacrity-rails/version'
13
+
14
+ module Transaction
15
+ autoload :Base, 'alacrity-rails/transaction/base'
16
+ autoload :ConnectionTest, 'alacrity-rails/transaction/connection_test'
17
+ autoload :ServerStartup, 'alacrity-rails/transaction/server_startup'
18
+ autoload :WebTransaction, 'alacrity-rails/transaction/web_transaction'
19
+ end
20
+ end
21
+
22
+ require 'alacrity-rails/railtie'
@@ -0,0 +1,50 @@
1
+ module AlacrityRails
2
+ class Client
3
+
4
+ def self.open_transaction(env)
5
+ new_transaction!(env)
6
+ end
7
+
8
+ def self.store_request_metrics(started_at, ended_at, data)
9
+ transaction.store_request_metrics(started_at, ended_at, data)
10
+ end
11
+
12
+ def self.store_database_metrics(started_at, ended_at, data)
13
+ transaction.store_database_metrics(started_at, ended_at, data)
14
+ end
15
+
16
+ def self.close_transaction!
17
+ this_transaction = transaction
18
+ Thread.new { transmit(this_transaction) }
19
+ ensure
20
+ cleanup
21
+ end
22
+
23
+ def self.log_server_startup
24
+ Thread.new {
25
+ transmit(AlacrityRails::Transaction::ServerStartup.new)
26
+ }
27
+ end
28
+
29
+ def self.transaction
30
+ Thread.current[:alacrity_transaction]
31
+ end
32
+
33
+ def self.cleanup
34
+ Thread.current[:alacrity_transaction] = nil
35
+ end
36
+
37
+ def self.transmit(transactable)
38
+ Net::HTTP.start(*transactable.net_http_start_arguments) do |http|
39
+ http.request(transactable.post_request)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def self.new_transaction!(env)
46
+ Thread.current[:alacrity_transaction] = Transaction::WebTransaction.new(env)
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module AlacrityRails::Config
2
+ extend self
3
+
4
+ def self.api_token
5
+ @api_token ||= ENV['ALACRITY_API_TOKEN']
6
+ end
7
+ attr_writer :api_token
8
+
9
+ def self.enabled?
10
+ api_token.present?
11
+ end
12
+
13
+ def self.collector_host
14
+ @collector_host ||= ENV['ALACRITY_COLLECTOR_HOST'] || 'https://collector-api.alacrityapp.com'
15
+ end
16
+ end
@@ -0,0 +1,55 @@
1
+ module AlacrityRails
2
+ class ConnectionTester
3
+ def self.run; new.run end
4
+
5
+ def run
6
+ if Config.api_token.blank?
7
+ puts missing_api_token_message
8
+ else
9
+ response = Client.transmit(Transaction::ConnectionTest.new)
10
+
11
+ if response.code == '200'
12
+ puts success_message
13
+ else
14
+ puts bad_response_message(JSON.parse(response.body)['message'])
15
+ end
16
+ end
17
+
18
+ puts assistance_message
19
+ end
20
+
21
+ private
22
+
23
+ def missing_api_token_message
24
+ %<
25
+ Your API token could not be found in the configuration. You can find it on https://alacrityapp.com.
26
+
27
+ Then add it to your server's environment as `ALACRITY_API_TOKEN`
28
+
29
+ OR
30
+
31
+ Set it manually with an initializer (config/alacrity.rb)
32
+ AlacrityRails::Config.api_token = 'your token'>
33
+ end
34
+
35
+ def bad_response_message(server_message)
36
+ %<
37
+ Oh no! Its seems like we have a problem!
38
+
39
+ #{server_message}>
40
+ end
41
+
42
+ def success_message
43
+ %<
44
+ Everything looks good!
45
+
46
+ You should see data on https://alacrityapp.com shortly after your app receives traffic.>
47
+ end
48
+
49
+ def assistance_message
50
+ %<
51
+ If you need assistance or have any questions, send an email to support@alacrityapp.com or tweet @alacrityapp and we'll help you out!
52
+ >
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,10 @@
1
+ module AlacrityRails
2
+ class Middleware < Struct.new(:app)
3
+ def call(env)
4
+ Client.open_transaction(env)
5
+ response = app.call(env)
6
+ Client.close_transaction!
7
+ response
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ module AlacrityRails
2
+ class Railtie < ::Rails::Railtie
3
+ initializer 'alacrity' do |config|
4
+ if Config.enabled?
5
+ Client.log_server_startup
6
+
7
+ config.middleware.insert_before 0, AlacrityRails::Middleware
8
+ end
9
+
10
+ ActiveSupport::Notifications.subscribe 'sql.active_record' do |name, started, finished, unique_id, data|
11
+ AlacrityRails::Client.store_database_metrics(started, finished, data)
12
+ end
13
+
14
+ ActiveSupport::Notifications.subscribe 'process_action.action_controller' do |name, started, finished, unique_id, data|
15
+ AlacrityRails::Client.store_request_metrics(started, finished, data)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module AlacrityRails::ServerConfig
2
+ extend self
3
+
4
+ def rails_version
5
+ @rails_version ||= Rails.version
6
+ end
7
+
8
+ def environment
9
+ @environment ||= ENV['ALACRITY_ENVIRONMENT'] || Rails.env
10
+ end
11
+
12
+ def client_identifier
13
+ @client_identifier ||= "alacrity-rails-#{AlacrityRails::VERSION}"
14
+ end
15
+
16
+ def as_json
17
+ {
18
+ client_identifier: client_identifier,
19
+ command: File.split($0).last,
20
+ environment: environment,
21
+ rails_version: rails_version,
22
+ ruby_version: RUBY_VERSION
23
+ }
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ module AlacrityRails::Transaction
2
+ class Base
3
+ def post_request
4
+ Net::HTTP::Post.new(endpoint, {
5
+ "Authorization" => authorization_header_value,
6
+ "Content-Type" => "application/json"
7
+ }).tap { |request| request.body = to_json }
8
+ end
9
+
10
+ def self.net_http_start_arguments
11
+ @net_http_start_arguments ||= [endpoint.host, endpoint.port, use_ssl: endpoint.scheme == 'https']
12
+ end
13
+ def net_http_start_arguments; self.class.net_http_start_arguments end
14
+
15
+ def self.endpoint
16
+ raise 'Must implement'
17
+ end
18
+ def endpoint; self.class.endpoint end
19
+
20
+ def self.authorization_header_value
21
+ @authorization_header_value ||= ActionController::HttpAuthentication::Token.encode_credentials(AlacrityRails::Config.api_token)
22
+ end
23
+ def authorization_header_value; self.class.authorization_header_value end
24
+
25
+ def to_json
26
+ @to_json ||= super.to_json
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ module AlacrityRails::Transaction
2
+ class ConnectionTest < Base
3
+ def self.endpoint
4
+ @endpoint ||= URI("#{AlacrityRails::Config.collector_host}/v1/connection-test")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module AlacrityRails::Transaction
2
+ class ServerStartup < Base
3
+ def as_json(*args)
4
+ AlacrityRails::ServerConfig.as_json
5
+ end
6
+
7
+ def self.endpoint
8
+ @endpoint ||= URI("#{AlacrityRails::Config.collector_host}/v1/server-startups")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,55 @@
1
+ module AlacrityRails::Transaction
2
+ class WebTransaction < Base
3
+ attr_accessor :url, :middleware_started_at, :controller, :action, :format,
4
+ :method, :status, :view_runtime, :db_runtime, :framework_elapsed
5
+
6
+ def initialize(env={})
7
+ self.middleware_started_at = Time.now
8
+ self.url = ["#{env['rack.url_scheme']}://", env['HTTP_HOST'], env['REQUEST_PATH']].compact.join
9
+ end
10
+
11
+ def store_database_metrics(started_at, finished_at, data)
12
+ sql_queries << {
13
+ statement_elapsed: ((finished_at - started_at) * 1000).to_i,
14
+ name: data[:name],
15
+ sql: data[:sql]
16
+ }
17
+ end
18
+
19
+ def store_request_metrics(started_at, finished_at, data)
20
+ self.framework_elapsed = ((finished_at - started_at) * 1000).to_i
21
+ self.controller = data[:controller]
22
+ self.action = data[:action]
23
+ self.format = data[:format]
24
+ self.method = data[:method]
25
+ self.status = data[:status]
26
+ self.view_runtime = data[:view_runtime].try(:to_i)
27
+ self.db_runtime = data[:db_runtime].try(:to_i)
28
+ end
29
+
30
+ def as_json(*args)
31
+ {
32
+ environment: AlacrityRails::ServerConfig.environment,
33
+ url: url,
34
+ controller: controller,
35
+ action: action,
36
+ middleware_elapsed: ((Time.now - middleware_started_at) * 1000).to_i,
37
+ framework_elapsed: framework_elapsed,
38
+ format: format,
39
+ method: method,
40
+ status: status,
41
+ view_runtime: view_runtime,
42
+ db_runtime: db_runtime,
43
+ sql_queries: sql_queries
44
+ }
45
+ end
46
+
47
+ def self.endpoint
48
+ @endpoint ||= URI("#{AlacrityRails::Config.collector_host}/v1/web-transactions")
49
+ end
50
+
51
+ def sql_queries
52
+ @sql_queries ||= []
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module AlacrityRails
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,8 @@
1
+ namespace :alacrity do
2
+
3
+ desc "Verifies your app's ability to communicate with Alacrity"
4
+ task :test_connection => :environment do
5
+ AlacrityRails::ConnectionTester.run
6
+ end
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alacrity-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alacrity, LLC
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ description: Rails Agent for the Alacrity Application Health Platform
28
+ email:
29
+ - support@alacrityapp.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.markdown
36
+ - Rakefile
37
+ - lib/alacrity-rails.rb
38
+ - lib/alacrity-rails/client.rb
39
+ - lib/alacrity-rails/config.rb
40
+ - lib/alacrity-rails/connection_tester.rb
41
+ - lib/alacrity-rails/middleware.rb
42
+ - lib/alacrity-rails/railtie.rb
43
+ - lib/alacrity-rails/server_config.rb
44
+ - lib/alacrity-rails/transaction/base.rb
45
+ - lib/alacrity-rails/transaction/connection_test.rb
46
+ - lib/alacrity-rails/transaction/server_startup.rb
47
+ - lib/alacrity-rails/transaction/web_transaction.rb
48
+ - lib/alacrity-rails/version.rb
49
+ - lib/tasks/test_connection.rake
50
+ homepage: https://www.alacrityapp.com
51
+ licenses:
52
+ - GPL
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 2.5.1
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Rails Agent for the Alacrity Application Health Platform
74
+ test_files: []