zuora_connect 1.5.40d → 1.5.40e

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e00ff173a2094215c2333b04afdc4bef45391f40
4
- data.tar.gz: b0d443fe6d3f688e31c8bf68ea7ac233301d4421
3
+ metadata.gz: 3e03cc9adf835227924f1f8edfe54365a64477b0
4
+ data.tar.gz: 8090964dd258ed93961a17c6d1362403ed23aea5
5
5
  SHA512:
6
- metadata.gz: 4bf28a84c95743029118cec66b542afb503f3364e28ff195bba51c2a45be0076087db63a997353ebe48b2757f9dcb1743d4b77a917345470fc929f6def7a32fb
7
- data.tar.gz: 31676bb71346262a4001b35386dbf2dee2a3ff796806b0792164e5f6a6368193c8a3c5705e55a0f090fd6ec82871a7ba168921e5d55313394a2a6dc14bf7f8a0
6
+ metadata.gz: 290894fb06bad82d629ed05a9f95095f3b994363e743692ef00300d4cad1f813ed7d06de31eb74cb808cdd148cc557a031833ee81bfb6d95a1a11ca63050a5aa
7
+ data.tar.gz: acdb498de14c477e3cbbdc23ff0dba8b4ddb395d2ce2a733454e2b62ccb2c33e6605a25047228393e865221b1cdf29be0bba994506cd774896ac222578e9472e
@@ -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
@@ -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,13 @@ module ZuoraConnect
11
11
  @use_s3 = false
12
12
  @private_key = ENV["CONNECT_KEY"]
13
13
  @additional_apartment_models = []
14
+ @telegraf_endpoint = 'udp://telegraf-ds.deis.svc.cluster.local:8094'
15
+ @enable_metrics_flag = true
16
+ @telegraf_client = Telegraf::Agent.new @telegraf_endpoint
17
+
18
+ # Setting the app name for telegraf write
19
+ @app_name_inbound = ENV['DEIS_APP'].present? ? "#{ENV['DEIS_APP']}-inbound" : "#{Rails.application.class.parent_name}-inbound"
20
+ @app_name_outbound = ENV['DEIS_APP'].present? ? "#{ENV['DEIS_APP']}-outbound" : "#{Rails.application.class.parent_name}-outbound"
14
21
 
15
22
  # OAuth Settings
16
23
  @oauth_client_id = ""
@@ -30,6 +37,10 @@ module ZuoraConnect
30
37
  @aws_region = "us-west-2"
31
38
  @s3_bucket_name = "rbm-apps"
32
39
  @s3_folder_name = Rails.application.class.parent_name
40
+
41
+ #Prometheus
42
+ @custom_prometheus_update_block = nil
43
+
33
44
  end
34
45
 
35
46
  def private_key
@@ -1,9 +1,16 @@
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
+ # Method to write outbound metrics to telegraf
10
+ def write_morse(msg)
11
+ puts "msg:",msg
12
+ end
13
+
7
14
  def authenticate_app_api_request
8
15
  #Skip session for api requests
9
16
  Thread.current[:appinstance] = nil
@@ -36,14 +43,14 @@ module ZuoraConnect
36
43
  else
37
44
  setup_instance_via_dev_mode
38
45
  end
39
- #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
46
+ #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
40
47
  #so data lookup provides a model method that can be overriden per app.
41
48
  if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
42
49
  if @appinstance.new_session_for_ui_requests(:params => params)
43
50
  @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
44
51
  end
45
52
  end
46
- PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
53
+ PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
47
54
  begin
48
55
  I18n.locale = session["#{@appinstance.id}::user::locale"] ? session["#{@appinstance.id}::user::locale"] : @appinstance.locale
49
56
  rescue I18n::InvalidLocale => ex
@@ -112,7 +119,7 @@ module ZuoraConnect
112
119
  else
113
120
  raise ZuoraConnect::Exceptions::AccessDenied.new("Authorization mistmatch. Possible tampering")
114
121
  end
115
- end
122
+ end
116
123
  end
117
124
 
118
125
  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.40d"
2
+ VERSION = "1.5.40e"
3
3
  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
@@ -35,4 +37,10 @@ module ZuoraConnect
35
37
 
36
38
  return configuration
37
39
  end
40
+
41
+
42
+
43
+
44
+
45
+
38
46
  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.40d
4
+ version: 1.5.40e
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