zuora_connect 1.5.40a → 1.5.40b

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: 8e915f67ad5993527d65b4e4c115ea8dc6f34894
4
- data.tar.gz: b6b098aa03fb13fbe8a05da49bdf97446f82b15b
3
+ metadata.gz: e18846dd3a100492259458122d7a58e1f62ad595
4
+ data.tar.gz: ea40c59fc3814fef76e4279c76ea9a0fbe651fcb
5
5
  SHA512:
6
- metadata.gz: 697525f9ca8900e9248af96adbfd3829d5dd1ccec432178a0efb38ff0381f6f4dec20dd7e3b28ba26a389bec3d8df7f3df77faa192d96c5ade7b3321156644e4
7
- data.tar.gz: 9457e97af890e84d393e6b18d554601ec5325df5ab4ba18d1398ad596742f2e62ec909299087316569d987bbeb3636f90a601ec70d7862e6d032154816d30418
6
+ metadata.gz: 6432f6f921abfa602136fd176af03fb750cc611538881ca3cb241568103a00e7ad3b3498bf66edae33d5616f85bc376824fa51d1482c3c90ce43669e88c01ceb
7
+ data.tar.gz: f537619bd058bfe29040d7bfbf7ef89e95eea34dc640ac929d95722909b3df632a017d0a0ea2be66889115a39bddfe156403267e74f993a3a8f0764d04b04a27
@@ -2,6 +2,7 @@ module ZuoraConnect
2
2
  class StaticController < ApplicationController
3
3
  before_filter :authenticate_connect_app_request, :except => [:health, :session_error, :invalid_app_instance_error]
4
4
  after_filter :persist_connect_app_session, :except => [:health, :session_error, :invalid_app_instance_error]
5
+
5
6
  def session_error
6
7
  respond_to do |format|
7
8
  format.html
@@ -22,5 +23,6 @@ module ZuoraConnect
22
23
  status: 200
23
24
  }, status: 200
24
25
  end
26
+
25
27
  end
26
28
  end
@@ -24,6 +24,21 @@ module ZuoraConnect
24
24
  self.apartment_switch(nil, true)
25
25
  end
26
26
 
27
+
28
+ # method for writing outbound metrics
29
+
30
+ def telegraf_time(endpoint_name: nil, &block)
31
+
32
+ response_time = Benchmark.realtime(&block)
33
+ p_type = Middleware::get_process_type
34
+
35
+ ZuoraConnect.configuration.telegraf_client.write(ZuoraConnect.configuration.app_name_outbound,
36
+ tags: {endpoint: endpoint_name, instance_id: self.id, process_type: p_type},
37
+ values: {response_time: response_time, caller: block.source_location[0]})
38
+ end
39
+
40
+
41
+
27
42
  def apartment_switch(method = nil, migrate = false)
28
43
  begin
29
44
  Apartment::Tenant.switch!(self.id) if self.persisted?
@@ -744,6 +759,7 @@ module ZuoraConnect
744
759
  super
745
760
  end
746
761
 
762
+
747
763
  method_hook :refresh, :updateOption, :update_logins, :before => :check_oauth_state
748
764
  method_hook :new_session, :refresh, :build_task, :after => :apartment_switch
749
765
  end
@@ -0,0 +1,39 @@
1
+ module Prometheus
2
+ require "zuora_connect/version"
3
+ require "zuora_api/version"
4
+
5
+ app_name = ENV['DEIS_APP'].present? ? "#{ENV['DEIS_APP']}" : "#{Rails.application.class.parent_name}"
6
+ # Create a default Prometheus registry for our metrics.
7
+ prometheus = Prometheus::Client.registry
8
+
9
+ # Create your metrics.
10
+ ZUORA_VERSION = Prometheus::Client::Gauge.new(:zuora_version, 'The current Zuora Gem version.')
11
+ CONNECT_VERSION = Prometheus::Client::Gauge.new(:gem_version, 'The current Connect Gem version.')
12
+ RAILS_VERSION = Prometheus::Client::Gauge.new(:rails_version, 'The current Rails version.')
13
+ RUBY_V = Prometheus::Client::Gauge.new(:ruby_version, 'The current Ruby version.')
14
+
15
+ # Register your metrics with the registry we previously created.
16
+ prometheus.register(ZUORA_VERSION);ZUORA_VERSION.set({version:ZuoraAPI::VERSION,name:app_name},0)
17
+ prometheus.register(CONNECT_VERSION);CONNECT_VERSION.set({version:ZuoraConnect::VERSION,name:app_name},0)
18
+ prometheus.register(RAILS_VERSION);RAILS_VERSION.set({version:Rails.version,name:app_name},0)
19
+ prometheus.register(RUBY_V);RUBY_V.set({version:RUBY_VERSION,name:app_name},0)
20
+
21
+ # Do they have resque jobs?
22
+ if defined? Resque.redis
23
+ REDIS_CONNECTION = Prometheus::Client::Gauge.new(:redis_connection, 'The status of the redis connection, 0 or 1')
24
+ FINISHED_JOBS = Prometheus::Client::Gauge.new(:finished_jobs, 'Done resque jobs')
25
+ WORKERS = Prometheus::Client::Gauge.new(:workers, 'Total resque workers')
26
+ ACTIVE_WORKERS = Prometheus::Client::Gauge.new(:active_workers, 'Active resque workers')
27
+ FAILED_JOBS = Prometheus::Client::Gauge.new(:failed_jobs, 'Failed resque jobs')
28
+ PENDING_JOBS = Prometheus::Client::Gauge.new(:pending_jobs, 'Pending resque jobs')
29
+
30
+ prometheus.register(REDIS_CONNECTION)
31
+ prometheus.register(FINISHED_JOBS)
32
+ prometheus.register(ACTIVE_WORKERS)
33
+ prometheus.register(WORKERS)
34
+ prometheus.register(FAILED_JOBS)
35
+ prometheus.register(PENDING_JOBS)
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,130 @@
1
+ module Middleware
2
+ require 'uri'
3
+
4
+ # Returns the process type if any
5
+ def self.get_process_type
6
+ p_type = nil
7
+ if ENV['HOSTNAME']
8
+ temp = ENV['HOSTNAME'].split(ENV['DEIS_APP'])[1]
9
+ temp = temp.split(/(-[0-9a-zA-Z]{5})$/)[0] # remove the 5 char hash
10
+ p_type = temp[1, temp.rindex("-")-1]
11
+ end
12
+ return p_type
13
+ end
14
+
15
+
16
+ # Write to telegraf
17
+ def self.write_to_telegraf(endpoint_name: nil, method_name: nil, status_code: nil, response_time: nil, db_runtime: nil, view_runtime: nil, content_type: nil)
18
+
19
+ # Getting the process type
20
+ p_type = Middleware::get_process_type
21
+
22
+ # Separately handling 200 and non 200 as influx does not accept nil as a value
23
+ if db_runtime && view_runtime
24
+ # 200 requests
25
+ ZuoraConnect.configuration.telegraf_client.write(ZuoraConnect.configuration.app_name_inbound,
26
+ tags: {endpoint: endpoint_name, "content-type": content_type, method: method_name, status: status_code, process_type: p_type},
27
+ values: {response_time: response_time, db_time: db_runtime, view_time: view_runtime})
28
+ else
29
+ # non 200 requests
30
+ ZuoraConnect.configuration.telegraf_client.write(ZuoraConnect.configuration.app_name_inbound,
31
+ tags: {endpoint: endpoint_name, "content-type": content_type, method: method_name, status: status_code, process_type: p_type},
32
+ values: {response_time: response_time})
33
+ end
34
+
35
+ end
36
+
37
+
38
+ # Object of this class is passed to the ActiveSupport::Notification hook
39
+ class PageRequest
40
+
41
+ # This method is triggered when a non error page is loaded (not 404, 500)
42
+ def call(name, started, finished, unique_id, payload)
43
+
44
+ # If the url contains any css or JavaScript files then do not collect metrics for them
45
+ block_words = ["css", "assets", "jpg", "png", "jpeg", "ico"]
46
+ if block_words.any? { |word| payload[:path].include?(word) }
47
+ return nil
48
+ end
49
+
50
+ # Getting the endpoint and the content_type
51
+ request_path = URI(payload[:headers]['REQUEST_URI']).path.split(".")[0]
52
+ content_type = ((payload[:headers]["action_controller.instance"].instance_variable_get :@_response).instance_variable_get :@header)["Content-Type"]
53
+ content_type = content_type.split(";")[0]
54
+
55
+ response_time = finished-started
56
+
57
+ # Write to telegraf
58
+ Middleware.write_to_telegraf("endpoint_name": request_path, "method_name": payload[:method], "status_code": payload[:status], "response_time": response_time, "db_runtime": payload[:db_runtime], "view_runtime": payload[:view_runtime], "content_type": content_type)
59
+
60
+ end
61
+ end
62
+
63
+
64
+ class MetricsMiddleware
65
+
66
+ require "zuora_connect/version"
67
+ require "zuora_api/version"
68
+ require "telegraf"
69
+
70
+ def initialize(app)
71
+ @app = app
72
+ end
73
+
74
+ def call(env)
75
+ start_time = Time.now
76
+ @status, @headers, @response = @app.call(env)
77
+
78
+ # If the url contains any CSS or JavaScript files then do not collect metrics for them
79
+ block_words = ["css", "assets", "jpg", "png", "jpeg", "ico"]
80
+ if block_words.any? { |word| env['PATH_INFO'].include?(word) }
81
+ return [@status, @headers, @response]
82
+ end
83
+
84
+ end_time = Time.now
85
+ response_time = end_time - start_time
86
+
87
+ #Prometheus Stuff
88
+ if env['PATH_INFO'] == '/connect/internal/metrics'
89
+
90
+ #Do something before each scrape
91
+ if defined? Resque.redis
92
+
93
+ app_name = ENV['DEIS_APP'].present? ? "#{ENV['DEIS_APP']}" : "#{Rails.application.class.parent_name}"
94
+ begin
95
+
96
+ Resque.redis.ping
97
+
98
+ Prometheus::REDIS_CONNECTION.set({connection:'redis',name:app_name},1)
99
+ Prometheus::FINISHED_JOBS.set({type:'resque',name:app_name},Resque.info[:processed])
100
+ Prometheus::PENDING_JOBS.set({type:'resque',name:app_name},Resque.info[:pending])
101
+ Prometheus::ACTIVE_WORKERS.set({type:'resque',name:app_name},Resque.info[:working])
102
+ Prometheus::WORKERS.set({type:'resque',name:app_name},Resque.info[:workers])
103
+ Prometheus::FAILED_JOBS.set({type:'resque',name:app_name},Resque.info[:failed])
104
+
105
+ rescue Redis::CannotConnectError
106
+ Prometheus::REDIS_CONNECTION.set({connection:'redis',name:app_name},0)
107
+ end
108
+
109
+ if ZuoraConnect.configuration.custom_prometheus_update_block != nil
110
+ ZuoraConnect.configuration.custom_prometheus_update_block.call()
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ # Writing to telegraf: Handle 404 and 500 requests
117
+ if @status != 200
118
+ # Getting the endpoint and content_type
119
+ request_path = URI(env['REQUEST_URI']).path.split(".")[0]
120
+ content_type = @headers['Content-Type'].split(';')[0] if @headers['Content-Type']
121
+ Middleware::write_to_telegraf("endpoint_name": request_path, "method_name": env['REQUEST_METHOD'], "status_code": @status, "response_time": response_time, "content_type": content_type)
122
+ end
123
+
124
+ [@status, @headers, @response]
125
+
126
+ end
127
+
128
+ end
129
+
130
+ end
data/lib/zuora_connect.rb CHANGED
@@ -4,9 +4,11 @@ require 'zuora_connect/exceptions'
4
4
  require 'zuora_connect/controllers/helpers'
5
5
  require 'zuora_connect/views/helpers'
6
6
  require 'zuora_connect/railtie'
7
- require 'resque/additions'
7
+ require 'resque/additions'
8
8
  require 'resque/dynamic_queues'
9
9
  require 'resque/self_lookup'
10
+ require 'prometheus/client'
11
+
10
12
 
11
13
  module ZuoraConnect
12
14
  class << self
@@ -1,6 +1,6 @@
1
1
  module ZuoraConnect
2
2
  class Configuration
3
- attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri,:use_s3, :default_locale,:dev_mode_appinstance ,:dev_mode_admin, :dev_mode_user, :dev_mode_pass, :default_time_zone,:delayed_job,:url, :private_key, :dev_mode_logins,:dev_mode_mode, :dev_mode_options, :mode, :timeout,:dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :additional_apartment_models
3
+ attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri,:use_s3, :default_locale,:dev_mode_appinstance ,:dev_mode_admin, :dev_mode_user, :dev_mode_pass, :default_time_zone,:delayed_job,:url, :private_key, :dev_mode_logins,:dev_mode_mode, :dev_mode_options, :mode, :timeout,:dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :additional_apartment_models, :telegraf_endpoint, :enable_metrics_flag, :telegraf_client, :custom_prometheus_update_block, :app_name_inbound, :app_name_outbound
4
4
 
5
5
  def initialize
6
6
  @default_locale = :en
@@ -11,6 +11,15 @@ module ZuoraConnect
11
11
  @use_s3 = false
12
12
  @private_key = ENV["CONNECT_KEY"]
13
13
  @additional_apartment_models = []
14
+ # telegraf_endpoints: select based on which daemonset to use
15
+ @telegraf_endpoint = 'udp://telegraf-ds.deis.svc.cluster.local:8094'
16
+ # @telegraf_endpoint = 'udp://deis-monitor-telegraf.deis.svc.cluster.local:8094'
17
+ @enable_metrics_flag = true
18
+ @telegraf_client = Telegraf::Agent.new @telegraf_endpoint
19
+
20
+ # Setting the app name for telegraf write
21
+ @app_name_inbound = ENV['DEIS_APP'].present? ? "#{ENV['DEIS_APP']}-inbound" : "#{Rails.application.class.parent_name}-inbound"
22
+ @app_name_outbound = ENV['DEIS_APP'].present? ? "#{ENV['DEIS_APP']}-outbound" : "#{Rails.application.class.parent_name}-outbound"
14
23
 
15
24
  # OAuth Settings
16
25
  @oauth_client_id = ""
@@ -30,6 +39,10 @@ module ZuoraConnect
30
39
  @aws_region = "us-west-2"
31
40
  @s3_bucket_name = "rbm-apps"
32
41
  @s3_folder_name = Rails.application.class.parent_name
42
+
43
+ #Prometheus
44
+ @custom_prometheus_update_block = nil
45
+
33
46
  end
34
47
 
35
48
  def private_key
@@ -1,9 +1,12 @@
1
1
  require 'apartment/migrator'
2
+ require 'benchmark'
3
+
2
4
  module ZuoraConnect
3
5
  module Controllers
4
6
  module Helpers
5
7
  extend ActiveSupport::Concern
6
8
 
9
+
7
10
  def authenticate_app_api_request
8
11
  #Skip session for api requests
9
12
  Thread.current[:appinstance] = nil
@@ -36,14 +39,14 @@ module ZuoraConnect
36
39
  else
37
40
  setup_instance_via_dev_mode
38
41
  end
39
- #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
42
+ #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
40
43
  #so data lookup provides a model method that can be overriden per app.
41
44
  if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
42
45
  if @appinstance.new_session_for_ui_requests(:params => params)
43
46
  @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
44
47
  end
45
48
  end
46
- PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
49
+ PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
47
50
  begin
48
51
  I18n.locale = session["#{@appinstance.id}::user::locale"] ? session["#{@appinstance.id}::user::locale"] : @appinstance.locale
49
52
  rescue I18n::InvalidLocale => ex
@@ -112,7 +115,7 @@ module ZuoraConnect
112
115
  else
113
116
  raise ZuoraConnect::Exceptions::AccessDenied.new("Authorization mistmatch. Possible tampering")
114
117
  end
115
- end
118
+ end
116
119
  end
117
120
 
118
121
  def setup_instance_via_session
@@ -1,5 +1,10 @@
1
+ require 'middleware/metrics_middleware'
2
+
1
3
  module ZuoraConnect
2
4
  class Railtie < Rails::Railtie
5
+ require 'prometheus/middleware/exporter'
6
+
7
+
3
8
  config.before_initialize do
4
9
  version = Rails.version
5
10
  if version >= "5.0.0"
@@ -12,6 +17,25 @@ module ZuoraConnect
12
17
  ::Rails.configuration.action_dispatch.x_sendfile_header = nil
13
18
  end
14
19
 
20
+ # Base object not being loaded at this point for some reason
21
+ if ZuoraConnect::Configuration.new.enable_metrics_flag == true
22
+
23
+ initializer "prometheus.configure_rails_initialization" do |app|
24
+ app.middleware.use Prometheus::Middleware::Exporter,(options ={:path => '/connect/internal/metrics'})
25
+ end
26
+
27
+ initializer "zuora_connect.configure_rails_initialization" do |app|
28
+ app.middleware.insert_after Rack::Sendfile, Middleware::MetricsMiddleware
29
+ end
30
+
31
+ # hook to process_action
32
+ ActiveSupport::Notifications.subscribe('process_action.action_controller', Middleware::PageRequest.new)
33
+
34
+
35
+
36
+ end
37
+
38
+
15
39
  initializer(:rails_stdout_logging, before: :initialize_logger) do
16
40
  if Rails.env != 'development' && !ENV['DEIS_APP'].blank?
17
41
  require 'lograge'
@@ -1,3 +1,3 @@
1
1
  module ZuoraConnect
2
- VERSION = "1.5.40a"
2
+ VERSION = "1.5.40b"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.40a
4
+ version: 1.5.40b
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connect Team
@@ -106,6 +106,34 @@ dependencies:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
108
  version: '0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: telegraf
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: 0.4.0
116
+ type: :runtime
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: 0.4.0
123
+ - !ruby/object:Gem::Dependency
124
+ name: prometheus-client
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: 0.8.0
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: 0.8.0
109
137
  - !ruby/object:Gem::Dependency
110
138
  name: railties
111
139
  requirement: !ruby/object:Gem::Requirement
@@ -238,6 +266,7 @@ files:
238
266
  - app/views/zuora_connect/static/session_error.html.erb
239
267
  - config/initializers/apartment.rb
240
268
  - config/initializers/object_method_hooks.rb
269
+ - config/initializers/prometheus.rb
241
270
  - config/initializers/redis.rb
242
271
  - config/initializers/resque.rb
243
272
  - config/initializers/to_bool.rb
@@ -252,6 +281,7 @@ files:
252
281
  - db/migrate/20110503003603_add_catalog_mappings_to_app_instance.rb
253
282
  - db/migrate/20110503003604_catalog_default.rb
254
283
  - db/migrate/20180301052853_add_catalog_attempted_at.rb
284
+ - lib/middleware/metrics_middleware.rb
255
285
  - lib/resque/additions.rb
256
286
  - lib/resque/dynamic_queues.rb
257
287
  - lib/resque/self_lookup.rb