zuora_connect 2.0.60a → 2.0.60f
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 +4 -4
- data/app/controllers/zuora_connect/static_controller.rb +52 -6
- data/app/models/zuora_connect/app_instance_base.rb +9 -5
- data/config/initializers/postgresql_adapter.rb +34 -1
- data/config/initializers/prometheus.rb +78 -23
- data/config/initializers/resque.rb +14 -0
- data/config/initializers/unicorn.rb +29 -1
- data/config/routes.rb +1 -0
- data/lib/middleware/json_parse_errors.rb +13 -2
- data/lib/middleware/metrics_middleware.rb +45 -31
- data/lib/zuora_connect/controllers/helpers.rb +1 -0
- data/lib/zuora_connect/railtie.rb +9 -5
- data/lib/zuora_connect/version.rb +1 -1
- metadata +27 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c0b307a59b8fdea6b65f97152dfeb29ce391030160c744aa04b3cb38f87691c
|
4
|
+
data.tar.gz: 7eeed93e89cee77af7521b36daf9465e53b7e0ce4b3e97edaf10e2882426029a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b93072f75b28ade9243d6ebf16dfd7f884744420a6d620f25747067f05c0c0ef6c261eb4d567b41395ff19106dfe4045f769278c760b317ae4799269e849fec1
|
7
|
+
data.tar.gz: b68884827084f3c53ce8bf0cd827bbe311fa6be686e3aad61293375d173876ded63eee6f94391fda51f060f17aff3dc98d728119951bd2f0dc4921ceed2ca759
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module ZuoraConnect
|
2
2
|
class StaticController < ApplicationController
|
3
|
-
before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app, :provision]
|
4
|
-
before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app, :provision]
|
5
|
-
after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app, :provision]
|
3
|
+
before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app, :provision, :instance_user]
|
4
|
+
before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app, :provision, :instance_user]
|
5
|
+
after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app, :provision, :instance_user]
|
6
6
|
|
7
7
|
skip_before_action :verify_authenticity_token, :only => [:initialize_app, :provision]
|
8
|
-
http_basic_authenticate_with name: ENV['PROVISION_USER'], password: ENV['PROVISION_SECRET'], :only => [:provision]
|
8
|
+
http_basic_authenticate_with name: ENV['PROVISION_USER'], password: ENV['PROVISION_SECRET'], :only => [:provision, :instance_user]
|
9
9
|
|
10
10
|
def metrics
|
11
11
|
type = params[:type].present? ? params[:type] : "versions"
|
@@ -14,11 +14,11 @@ module ZuoraConnect
|
|
14
14
|
|
15
15
|
def health
|
16
16
|
if params[:error].present?
|
17
|
-
begin
|
17
|
+
begin
|
18
18
|
raise ZuoraConnect::Exceptions::Error.new('This is an error')
|
19
19
|
rescue => ex
|
20
20
|
case params[:error]
|
21
|
-
when 'Log'
|
21
|
+
when 'Log'
|
22
22
|
Rails.logger.error("Error in Health", ex)
|
23
23
|
when 'Exception'
|
24
24
|
raise
|
@@ -77,6 +77,52 @@ module ZuoraConnect
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
def instance_user
|
81
|
+
ZuoraConnect::AppInstance.read_master_db do
|
82
|
+
ZuoraConnect.logger.with_fields = {} if ZuoraConnect.logger.is_a?(Ougai::Logger)
|
83
|
+
Rails.logger.with_fields = {} if Rails.logger.is_a?(Ougai::Logger)
|
84
|
+
|
85
|
+
if defined?(ElasticAPM) && ElasticAPM.running? && ElasticAPM.respond_to?(:set_label)
|
86
|
+
ElasticAPM.set_label(:trace_id, request.uuid)
|
87
|
+
end
|
88
|
+
|
89
|
+
unless params[:id].present?
|
90
|
+
render json: {
|
91
|
+
status: 400,
|
92
|
+
message: 'No app instance id provided'
|
93
|
+
}, status: :bad_request
|
94
|
+
return
|
95
|
+
end
|
96
|
+
|
97
|
+
@appinstance = ZuoraConnect::AppInstance.find(params[:id]).new_session
|
98
|
+
end
|
99
|
+
|
100
|
+
zuora_client = @appinstance.send(ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION).client
|
101
|
+
client_describe, = zuora_client.rest_call(
|
102
|
+
url: zuora_client.rest_endpoint('genesis/user/info').gsub('v1/', ''),
|
103
|
+
session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic
|
104
|
+
)
|
105
|
+
|
106
|
+
render json: {
|
107
|
+
status: 200,
|
108
|
+
message: 'Success',
|
109
|
+
user_id: client_describe['coreUserId'],
|
110
|
+
username: client_describe['username'],
|
111
|
+
email: client_describe['workEmail']
|
112
|
+
}, status: 200
|
113
|
+
rescue ActiveRecord::RecordNotFound
|
114
|
+
render json: {
|
115
|
+
status: 400,
|
116
|
+
message: 'No app instance found'
|
117
|
+
}, status: :bad_request
|
118
|
+
rescue StandardError => e
|
119
|
+
Rails.logger.error('Error occurred getting user details', e)
|
120
|
+
render json: {
|
121
|
+
status: 500,
|
122
|
+
message: 'Failed to get user details'
|
123
|
+
}, status: 500
|
124
|
+
end
|
125
|
+
|
80
126
|
private
|
81
127
|
|
82
128
|
def clear_connect_app_session
|
@@ -338,6 +338,10 @@ module ZuoraConnect
|
|
338
338
|
raise
|
339
339
|
end
|
340
340
|
|
341
|
+
def aws_secrets
|
342
|
+
(Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
|
343
|
+
end
|
344
|
+
|
341
345
|
#### START KMS ENCRYPTION Methods ####
|
342
346
|
def zuora_logins=(val)
|
343
347
|
write_attribute(:zuora_logins, kms_encrypt(val.to_json))
|
@@ -350,7 +354,7 @@ module ZuoraConnect
|
|
350
354
|
|
351
355
|
def kms_decrypt(value)
|
352
356
|
kms_tries ||= 0
|
353
|
-
kms_client = Aws::KMS::Client.new({region:
|
357
|
+
kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
|
354
358
|
resp = kms_client.decrypt({ciphertext_blob: [value].pack("H*") })
|
355
359
|
return resp.plaintext
|
356
360
|
rescue *AWS_AUTH_ERRORS => ex
|
@@ -365,7 +369,7 @@ module ZuoraConnect
|
|
365
369
|
|
366
370
|
def kms_encrypt(value)
|
367
371
|
kms_tries ||= 0
|
368
|
-
kms_client = Aws::KMS::Client.new({region:
|
372
|
+
kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if {|k,v| v.blank? })
|
369
373
|
|
370
374
|
resp = kms_client.encrypt({key_id: kms_key, plaintext: value})
|
371
375
|
return resp.ciphertext_blob.unpack('H*').first
|
@@ -380,12 +384,12 @@ module ZuoraConnect
|
|
380
384
|
end
|
381
385
|
|
382
386
|
def kms_key
|
383
|
-
return ENV['AWS_KMS_ARN'] ||
|
387
|
+
return ENV['AWS_KMS_ARN'] || aws_secrets['AWS_KMS_ARN']
|
384
388
|
end
|
385
389
|
|
386
390
|
def aws_auth_client
|
387
391
|
if Rails.env.to_s == 'development'
|
388
|
-
return Aws::Credentials.new(
|
392
|
+
return Aws::Credentials.new(aws_secrets['AWS_ACCESS_KEY_ID'], aws_secrets['AWS_SECRET_ACCESS_KEY'])
|
389
393
|
else
|
390
394
|
return nil
|
391
395
|
end
|
@@ -402,7 +406,7 @@ module ZuoraConnect
|
|
402
406
|
end
|
403
407
|
|
404
408
|
def self.write_to_telegraf(*args)
|
405
|
-
if ZuoraConnect.configuration.enable_metrics
|
409
|
+
if ZuoraConnect.configuration.enable_metrics && !defined?(Prometheus)
|
406
410
|
@@telegraf_host = ZuoraConnect::Telegraf.new() if @@telegraf_host == nil
|
407
411
|
unicorn_stats = self.unicorn_listener_stats() if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
|
408
412
|
@@telegraf_host.write(direction: 'Raindrops', tags: {}, values: unicorn_stats) unless unicorn_stats.blank?
|
@@ -2,7 +2,33 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
class PostgreSQLAdapter < AbstractAdapter
|
4
4
|
private
|
5
|
-
def
|
5
|
+
def load_additional_types_latest(oids = nil)
|
6
|
+
initializer = OID::TypeMapInitializer.new(type_map)
|
7
|
+
if supports_ranges?
|
8
|
+
query = <<-SQL
|
9
|
+
SELECT DISTINCT on (t.typname) t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
10
|
+
FROM pg_type as t
|
11
|
+
LEFT JOIN pg_range as r ON oid = rngtypid
|
12
|
+
SQL
|
13
|
+
else
|
14
|
+
query = <<-SQL
|
15
|
+
SELECT DISTINCT on (t.typname) t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
16
|
+
FROM pg_type as t
|
17
|
+
SQL
|
18
|
+
end
|
19
|
+
|
20
|
+
if oids
|
21
|
+
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
22
|
+
else
|
23
|
+
query += initializer.query_conditions_for_initial_load
|
24
|
+
end
|
25
|
+
|
26
|
+
execute_and_clear(query, "SCHEMA", []) do |records|
|
27
|
+
initializer.run(records)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_additional_types_deprecated(type_map, oids = nil)
|
6
32
|
initializer = OID::TypeMapInitializer.new(type_map)
|
7
33
|
if supports_ranges?
|
8
34
|
query = <<-SQL
|
@@ -27,6 +53,13 @@ module ActiveRecord
|
|
27
53
|
initializer.run(records)
|
28
54
|
end
|
29
55
|
end
|
56
|
+
|
57
|
+
rails_version = Rails.version.split('.').map { |x| x.to_i }
|
58
|
+
if (rails_version <=> [5, 2, 0]) >= 1
|
59
|
+
alias :load_additional_types :load_additional_types_latest
|
60
|
+
else
|
61
|
+
alias :load_additional_types :load_additional_types_deprecated
|
62
|
+
end
|
30
63
|
end
|
31
64
|
end
|
32
65
|
end
|
@@ -3,38 +3,93 @@ if defined? Prometheus
|
|
3
3
|
require "zuora_connect/version"
|
4
4
|
require "zuora_api/version"
|
5
5
|
|
6
|
+
resque_path = "#{ENV['RESQUE_EXPORTER_PATH'] || Rails.root.join('tmp/resque_exporter')}/*.prom"
|
7
|
+
prometheus_path = Rails.root.join("tmp/prometheus")
|
8
|
+
|
9
|
+
Dir[resque_path, "#{prometheus_path}/*.bin"].each do |file_path|
|
10
|
+
File.unlink(file_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'prometheus/client/data_stores/direct_file_store'
|
14
|
+
Prometheus::Client.config.data_store = Prometheus::Client::DataStores::DirectFileStore.new(
|
15
|
+
dir: prometheus_path
|
16
|
+
)
|
17
|
+
|
18
|
+
class ResqueExporter
|
19
|
+
require 'prometheus/client/formats/text'
|
20
|
+
require 'fileutils'
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@lock = Monitor.new
|
24
|
+
@registry = Prometheus::Client.registry
|
25
|
+
@path = ENV['RESQUE_EXPORTER_PATH'] || Rails.root.join('tmp/resque_exporter')
|
26
|
+
FileUtils.mkdir_p(@path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def export
|
30
|
+
filename = File.join(@path, 'resque_export.prom')
|
31
|
+
@lock.synchronize do
|
32
|
+
File.open(filename, 'w+') do |file|
|
33
|
+
file.write(Prometheus::Client::Formats::Text.marshal(@registry))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
most_recent_aggregation = {}
|
40
|
+
sum_aggregation = {}
|
41
|
+
if defined?(Unicorn)
|
42
|
+
most_recent_aggregation[:aggregation] = :most_recent
|
43
|
+
sum_aggregation[:aggregation] = :sum
|
44
|
+
end
|
45
|
+
|
6
46
|
# Create a default Prometheus registry for our metrics.
|
7
47
|
prometheus = Prometheus::Client.registry
|
8
48
|
|
9
49
|
# Create your metrics.
|
10
|
-
ZUORA_VERSION =
|
11
|
-
CONNECT_VERSION =
|
12
|
-
RAILS_VERSION =
|
13
|
-
RUBY_V =
|
50
|
+
ZUORA_VERSION = prometheus.gauge(:zuora_version, docstring: 'The current Zuora Gem version.', labels: %i(version name), preset_labels: { version: ZuoraAPI::VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
|
51
|
+
CONNECT_VERSION = prometheus.gauge(:gem_version, docstring: 'The current Connect Gem version.', labels: %i(version name), preset_labels: { version: ZuoraConnect::VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
|
52
|
+
RAILS_VERSION = prometheus.gauge(:rails_version, docstring: 'The current Rails version.', labels: %i(version name), preset_labels: { version: Rails.version, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
|
53
|
+
RUBY_V = prometheus.gauge(:ruby_version, docstring: 'The current Ruby version.', labels: %i(version name), preset_labels: { version: RUBY_VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
|
14
54
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
prometheus.register(RUBY_V);RUBY_V.set({version: RUBY_VERSION, name: ZuoraConnect::Telegraf.app_name},0)
|
55
|
+
ZUORA_VERSION.set(0)
|
56
|
+
CONNECT_VERSION.set(0)
|
57
|
+
RAILS_VERSION.set(0)
|
58
|
+
RUBY_V.set(0)
|
20
59
|
|
21
60
|
# Do they have resque jobs?
|
22
61
|
if defined? Resque.redis
|
23
|
-
REDIS_CONNECTION =
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
62
|
+
REDIS_CONNECTION = prometheus.gauge(:redis_connection, docstring: 'The status of the redis connection, 0 or 1', labels: %i(connection name), preset_labels: {connection:'redis', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
|
63
|
+
JOBS_FINISHED = prometheus.gauge(:jobs_finished, docstring: 'Done resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
|
64
|
+
WORKERS_TOTAL = prometheus.gauge(:workers_total, docstring: 'Total resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
|
65
|
+
WORKERS_ACTIVE = prometheus.gauge(:workers_active, docstring: 'Active resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
|
66
|
+
JOBS_FAILED = prometheus.gauge(:jobs_failed, docstring: 'Failed resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
|
67
|
+
JOBS_PENDING = prometheus.gauge(:jobs_pending, docstring: 'Pending resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
|
37
68
|
end
|
38
69
|
|
70
|
+
if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
|
71
|
+
UNICORN_KILLS = prometheus.gauge(
|
72
|
+
:unicorn_kills,
|
73
|
+
docstring: 'Unicorn Kills',
|
74
|
+
labels: %i(type name),
|
75
|
+
preset_labels: {type:'Unicorn-Killer', name: ZuoraConnect::Telegraf.app_name},
|
76
|
+
store_settings: sum_aggregation
|
77
|
+
)
|
78
|
+
|
79
|
+
ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, _|
|
80
|
+
gauge_name = "unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_')
|
81
|
+
gauge = prometheus.gauge(
|
82
|
+
gauge_name.to_sym,
|
83
|
+
docstring: 'Unicorn Stats',
|
84
|
+
labels: %i(type name),
|
85
|
+
preset_labels: { type: 'unicorn', name: ZuoraConnect::Telegraf.app_name },
|
86
|
+
store_settings: most_recent_aggregation
|
87
|
+
)
|
88
|
+
Prometheus.const_set(
|
89
|
+
gauge_name.upcase,
|
90
|
+
gauge
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
39
94
|
end
|
40
95
|
end
|
@@ -5,6 +5,20 @@ if defined?(Resque::Worker)
|
|
5
5
|
Resque::Job.send(:include, Resque::SelfLookup)
|
6
6
|
end
|
7
7
|
|
8
|
+
if defined?(Resque::Job) && defined?(Prometheus)
|
9
|
+
module ResquePrometheusExtensions
|
10
|
+
EXPORTER = Prometheus::ResqueExporter.new
|
11
|
+
def perform
|
12
|
+
super
|
13
|
+
EXPORTER.export
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Resque::Job
|
18
|
+
prepend ResquePrometheusExtensions
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
8
22
|
Resque.module_eval do
|
9
23
|
# Returns a hash, mapping queue names to queue sizes
|
10
24
|
def queue_sizes
|
@@ -3,7 +3,35 @@ if defined?(Unicorn::WorkerKiller)
|
|
3
3
|
self.singleton_class.send(:alias_method, :kill_self_old, :kill_self)
|
4
4
|
def self.kill_self(logger, start_time)
|
5
5
|
self.kill_self_old(logger, start_time)
|
6
|
-
|
6
|
+
if defined?(Prometheus)
|
7
|
+
Prometheus::UNICORN_KILLS.set(1)
|
8
|
+
else
|
9
|
+
ZuoraConnect::AppInstance.write_to_telegraf(direction: 'Unicorn-Killer', tags: {app_instance: 0}, values: {kill: 1})
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if defined?(Unicorn::HttpServer) && defined?(Prometheus)
|
16
|
+
module HttpServerExtensions
|
17
|
+
def kill_worker(signal, wpid)
|
18
|
+
Prometheus::UNICORN_KILLS.increment
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module WorkerExtensions
|
24
|
+
def soft_kill(sig)
|
25
|
+
Prometheus::UNICORN_KILLS.increment
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Unicorn::HttpServer
|
31
|
+
prepend HttpServerExtensions
|
32
|
+
end
|
33
|
+
|
34
|
+
class Unicorn::Worker
|
35
|
+
prepend WorkerExtensions
|
36
|
+
end
|
9
37
|
end
|
data/config/routes.rb
CHANGED
@@ -7,7 +7,7 @@ module ZuoraConnect
|
|
7
7
|
def call(env)
|
8
8
|
begin
|
9
9
|
@app.call(env)
|
10
|
-
rescue
|
10
|
+
rescue DynamicRailsError => error
|
11
11
|
if env['HTTP_ACCEPT'] =~ /application\/json/ || env['CONTENT_TYPE'] =~ /application\/json/
|
12
12
|
return [
|
13
13
|
400, { "Content-Type" => "application/json" },
|
@@ -18,5 +18,16 @@ module ZuoraConnect
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
# Note(hartley): remove once the minimum supported version of Rails is 5.2
|
23
|
+
class DynamicRailsError < StandardError
|
24
|
+
def self.===(exception)
|
25
|
+
if Rails.version >= "5.2"
|
26
|
+
exception.is_a?(ActionDispatch::Http::Parameters::ParseError)
|
27
|
+
else
|
28
|
+
exception.is_a?(ActionDispatch::ParamsParser::ParseError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
21
32
|
end
|
22
|
-
end
|
33
|
+
end
|
@@ -64,6 +64,22 @@ module ZuoraConnect
|
|
64
64
|
#Remove bad headers
|
65
65
|
@bad_headers.each { |header| env.delete(header) }
|
66
66
|
|
67
|
+
if defined?(Prometheus) && env['PATH_INFO'] == '/connect/internal/metrics'
|
68
|
+
# Prometheus Stuff
|
69
|
+
metrics = ZuoraConnect::AppInstance.get_metrics('stats')
|
70
|
+
redis_up = metrics.present? && metrics.dig(:Resque, :Workers_Total).present? ? 1 : 0
|
71
|
+
Prometheus::REDIS_CONNECTION.set(redis_up)
|
72
|
+
|
73
|
+
process_prometheus_metric(metrics: metrics)
|
74
|
+
|
75
|
+
if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
|
76
|
+
ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, value|
|
77
|
+
gauge = Prometheus.const_get("unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_').upcase)
|
78
|
+
gauge.set(value) if gauge.present?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
67
83
|
#Thread.current[:appinstance] = nil
|
68
84
|
start_time = Time.now
|
69
85
|
begin
|
@@ -77,35 +93,6 @@ module ZuoraConnect
|
|
77
93
|
ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: 'request-inbound-assets', tags: tags, values: values)
|
78
94
|
end
|
79
95
|
|
80
|
-
if defined? Prometheus
|
81
|
-
#Prometheus Stuff
|
82
|
-
if env['PATH_INFO'] == '/connect/internal/metrics'
|
83
|
-
|
84
|
-
#Do something before each scrape
|
85
|
-
if defined? Resque.redis
|
86
|
-
begin
|
87
|
-
|
88
|
-
Resque.redis.ping
|
89
|
-
|
90
|
-
Prometheus::REDIS_CONNECTION.set({connection:'redis',name: ZuoraConnect::Telegraf.app_name},1)
|
91
|
-
Prometheus::FINISHED_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:processed])
|
92
|
-
Prometheus::PENDING_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:pending])
|
93
|
-
Prometheus::ACTIVE_WORKERS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:working])
|
94
|
-
Prometheus::WORKERS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:workers])
|
95
|
-
Prometheus::FAILED_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:failed])
|
96
|
-
|
97
|
-
rescue Redis::CannotConnectError
|
98
|
-
Prometheus::REDIS_CONNECTION.set({connection:'redis',name: ZuoraConnect::Telegraf.app_name},0)
|
99
|
-
end
|
100
|
-
|
101
|
-
if ZuoraConnect.configuration.custom_prometheus_update_block != nil
|
102
|
-
ZuoraConnect.configuration.custom_prometheus_update_block.call()
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
96
|
# Uncomment following block of code for handling engine requests/requests without controller
|
110
97
|
# else
|
111
98
|
# # Handling requests which do not have controllers (engines)
|
@@ -119,10 +106,10 @@ module ZuoraConnect
|
|
119
106
|
content_type = @headers['Content-Type'].split(';')[0] if @headers['Content-Type']
|
120
107
|
content_type = content_type.gsub('text/javascript', 'application/javascript')
|
121
108
|
tags = {status: @status, content_type: content_type}
|
122
|
-
|
109
|
+
|
123
110
|
tags = tags.merge({controller: 'ActionController'})
|
124
111
|
tags = tags.merge({action: 'RoutingError' }) if @status == 404
|
125
|
-
|
112
|
+
|
126
113
|
values = {response_time: ((Time.now - start_time)*1000).round(2) }
|
127
114
|
|
128
115
|
ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
|
@@ -133,5 +120,32 @@ module ZuoraConnect
|
|
133
120
|
[@status, @headers, @response]
|
134
121
|
end
|
135
122
|
end
|
123
|
+
|
124
|
+
def process_prometheus_metric(type: 'none', metrics: {})
|
125
|
+
return if metrics.blank?
|
126
|
+
|
127
|
+
prometheus = Prometheus::Client.registry
|
128
|
+
most_recent_aggregation = {}
|
129
|
+
if Prometheus::Client.config.data_store.is_a?(Prometheus::Client::DataStores::DirectFileStore)
|
130
|
+
most_recent_aggregation[:aggregation] = :most_recent
|
131
|
+
end
|
132
|
+
metrics.each do |key, value|
|
133
|
+
next if %w[app_name url].include?(key.to_s)
|
134
|
+
|
135
|
+
if value.is_a?(Hash)
|
136
|
+
process_prometheus_metric(type: key.to_s, metrics: value)
|
137
|
+
else
|
138
|
+
gauge_name = key.to_s.downcase.gsub(/[^a-z0-9_]/, '_')
|
139
|
+
gauge = prometheus.get(gauge_name.to_sym) || prometheus.gauge(
|
140
|
+
gauge_name.to_sym,
|
141
|
+
docstring: "#{key} metric",
|
142
|
+
labels: %i(type name),
|
143
|
+
preset_labels: { type: type, name: ZuoraConnect::Telegraf.app_name },
|
144
|
+
store_settings: most_recent_aggregation
|
145
|
+
)
|
146
|
+
gauge.set(value)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
136
150
|
end
|
137
151
|
end
|
@@ -411,6 +411,7 @@ module ZuoraConnect
|
|
411
411
|
if defined?(@appinstance) && !@appinstance['zuora_logins'].nil?
|
412
412
|
#Add user/update
|
413
413
|
begin
|
414
|
+
ZuoraConnect::ZuoraUser.reset_table_name
|
414
415
|
@zuora_user = ZuoraConnect::ZuoraUser.where(:zuora_user_id => zuora_user_id).first
|
415
416
|
rescue ActiveRecord::StatementInvalid => ex
|
416
417
|
if ex.message.include?("PG::UndefinedTable") && ex.message.include?("zuora_users")
|
@@ -28,11 +28,6 @@ module ZuoraConnect
|
|
28
28
|
::Rails.configuration.action_dispatch.x_sendfile_header = nil
|
29
29
|
end
|
30
30
|
|
31
|
-
if defined? Prometheus
|
32
|
-
initializer "prometheus.configure_rails_initialization" do |app|
|
33
|
-
app.middleware.use Prometheus::Middleware::Exporter,(options ={:path => '/connect/internal/metrics'})
|
34
|
-
end
|
35
|
-
end
|
36
31
|
initializer "zuora_connect.configure_rails_initialization" do |app|
|
37
32
|
app.middleware.insert_after Rack::Sendfile, ZuoraConnect::MetricsMiddleware
|
38
33
|
app.middleware.insert_after ActionDispatch::RequestId, ZuoraConnect::RequestIdMiddleware
|
@@ -40,6 +35,15 @@ module ZuoraConnect
|
|
40
35
|
app.config.middleware.use ZuoraConnect::JsonParseErrors
|
41
36
|
end
|
42
37
|
|
38
|
+
if defined? Prometheus
|
39
|
+
require 'rack'
|
40
|
+
require 'prometheus/middleware/exporter'
|
41
|
+
initializer "prometheus.configure_rails_initialization" do |app|
|
42
|
+
app.middleware.insert_after ZuoraConnect::MetricsMiddleware, Prometheus::Middleware::Exporter, path: '/connect/internal/metrics'
|
43
|
+
app.config.middleware.use Rack::Deflater, if: ->(env, *) { env['PATH_INFO'] == '/connect/internal/metrics' }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
43
47
|
# hook to process_action
|
44
48
|
ActiveSupport::Notifications.subscribe('process_action.action_controller', ZuoraConnect::PageRequest.new)
|
45
49
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zuora_connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.60f
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Connect Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apartment
|
@@ -438,44 +438,44 @@ signing_key:
|
|
438
438
|
specification_version: 4
|
439
439
|
summary: Summary of Connect.
|
440
440
|
test_files:
|
441
|
-
- test/integration/navigation_test.rb
|
442
|
-
- test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
|
443
441
|
- test/fixtures/zuora_connect/app_instances.yml
|
444
|
-
- test/lib/generators/zuora_connect/datatable_generator_test.rb
|
445
442
|
- test/models/zuora_connect/app_instance_test.rb
|
443
|
+
- test/integration/navigation_test.rb
|
444
|
+
- test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
|
446
445
|
- test/zuora_connect_test.rb
|
447
|
-
- test/
|
448
|
-
- test/dummy/config.ru
|
449
|
-
- test/dummy/public/422.html
|
450
|
-
- test/dummy/public/404.html
|
446
|
+
- test/lib/generators/zuora_connect/datatable_generator_test.rb
|
451
447
|
- test/dummy/public/500.html
|
448
|
+
- test/dummy/public/404.html
|
452
449
|
- test/dummy/public/favicon.ico
|
453
|
-
- test/dummy/
|
454
|
-
- test/dummy/
|
455
|
-
- test/dummy/
|
456
|
-
- test/dummy/app/assets/javascripts/application.js
|
457
|
-
- test/dummy/app/assets/stylesheets/application.css
|
458
|
-
- test/dummy/README.rdoc
|
459
|
-
- test/dummy/bin/rails
|
460
|
-
- test/dummy/bin/rake
|
461
|
-
- test/dummy/bin/bundle
|
462
|
-
- test/dummy/bin/setup
|
450
|
+
- test/dummy/public/422.html
|
451
|
+
- test/dummy/Rakefile
|
452
|
+
- test/dummy/config.ru
|
463
453
|
- test/dummy/config/secrets.yml
|
464
454
|
- test/dummy/config/boot.rb
|
465
|
-
- test/dummy/config/
|
466
|
-
- test/dummy/config/initializers/filter_parameter_logging.rb
|
455
|
+
- test/dummy/config/application.rb
|
467
456
|
- test/dummy/config/initializers/session_store.rb
|
468
|
-
- test/dummy/config/initializers/inflections.rb
|
469
|
-
- test/dummy/config/initializers/cookies_serializer.rb
|
470
457
|
- test/dummy/config/initializers/assets.rb
|
471
458
|
- test/dummy/config/initializers/wrap_parameters.rb
|
459
|
+
- test/dummy/config/initializers/filter_parameter_logging.rb
|
472
460
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
473
|
-
- test/dummy/config/
|
474
|
-
- test/dummy/config/
|
475
|
-
- test/dummy/config/
|
461
|
+
- test/dummy/config/initializers/mime_types.rb
|
462
|
+
- test/dummy/config/initializers/inflections.rb
|
463
|
+
- test/dummy/config/initializers/cookies_serializer.rb
|
476
464
|
- test/dummy/config/routes.rb
|
465
|
+
- test/dummy/config/database.yml
|
466
|
+
- test/dummy/config/environments/test.rb
|
477
467
|
- test/dummy/config/environments/production.rb
|
478
468
|
- test/dummy/config/environments/development.rb
|
479
|
-
- test/dummy/config/
|
469
|
+
- test/dummy/config/environment.rb
|
480
470
|
- test/dummy/config/locales/en.yml
|
471
|
+
- test/dummy/README.rdoc
|
472
|
+
- test/dummy/bin/rake
|
473
|
+
- test/dummy/bin/setup
|
474
|
+
- test/dummy/bin/rails
|
475
|
+
- test/dummy/bin/bundle
|
476
|
+
- test/dummy/app/views/layouts/application.html.erb
|
477
|
+
- test/dummy/app/assets/javascripts/application.js
|
478
|
+
- test/dummy/app/assets/stylesheets/application.css
|
479
|
+
- test/dummy/app/helpers/application_helper.rb
|
480
|
+
- test/dummy/app/controllers/application_controller.rb
|
481
481
|
- test/test_helper.rb
|