zuora_connect 2.0.60t → 3.0.0.pre.a

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
  SHA256:
3
- metadata.gz: d7eee2d7cabce6128892afac88428f3c7f77a3318e244bd3becdf521716d0a25
4
- data.tar.gz: 12c07009df449c54d70bec094e16594f0a3ecdb251c59ffed230d64787939cfb
3
+ metadata.gz: e63c10c8405375ad7cb2c28073c6181ed055266fb8d61e3ac5725e8f5b8ca8d5
4
+ data.tar.gz: c5124fe3590fd14c0acdad0cfe6e567997195eaa728245f620bfff5bbda285fe
5
5
  SHA512:
6
- metadata.gz: a45196b2a77449c349e1e1fe4b9853d08e35da763327e2f74134cee20f4ee4af9311a4298b048b937d1d4f5056e047f0db503f57b3b36f2335a963fe4e1f3336
7
- data.tar.gz: d3d14ec18ce3da9ad27776cf2c79ed3b7f9aafa88c331f3a0efa9a2075258cf438e3dd469c50ba1e4d0e46d339ec0ba895632535ab9644dd8cf4a29513d77f7d
6
+ metadata.gz: 1beb3e3c0531b3035051711670de269814122c20269086ffd31257b02dc4e6ff8c515ac812abc436360ebc9f1506e3ae8e15e859d6098913e08f2dfed67e1284
7
+ data.tar.gz: bff9fca90e302be4fe97b3cac4ac54bb8dc6c841ad6762939f9b0b2c6c7e66417bb108105d6d8372965ae9090d813c97cff8a4a4a6b513665beed63c9229f0e4
@@ -1,16 +1,12 @@
1
1
  module ZuoraConnect
2
2
  class StaticController < ApplicationController
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]
3
+ before_action :authenticate_connect_app_request, :except => [:health, :initialize_app, :provision, :instance_user]
4
+ before_action :clear_connect_app_session, :only => [:health, :initialize_app, :provision, :instance_user]
5
+ after_action :persist_connect_app_session, :except => [:health, :initialize_app, :provision, :instance_user]
6
6
 
7
7
  skip_before_action :verify_authenticity_token, :only => [:initialize_app, :provision]
8
8
  http_basic_authenticate_with name: ENV['PROVISION_USER'], password: ENV['PROVISION_SECRET'], :only => [:provision, :instance_user]
9
9
 
10
- def metrics
11
- type = params[:type].present? ? params[:type] : "versions"
12
- render json: ZuoraConnect::AppInstance.get_metrics(type).to_json, status: 200
13
- end
14
10
 
15
11
  def health
16
12
  if params[:error].present?
@@ -12,7 +12,6 @@ module ZuoraConnect
12
12
 
13
13
  self.table_name = "zuora_connect_app_instances"
14
14
  attr_accessor :options, :mode, :logins, :task_data, :last_refresh, :username, :password, :s3_client, :api_version, :drop_message, :new_session_message, :connect_user, :logitems, :user_timezone
15
- @@telegraf_host = nil
16
15
  REFRESH_TIMEOUT = 2.minute #Used to determine how long to wait on current refresh call before executing another
17
16
  INSTANCE_REFRESH_WINDOW = 1.hours #Used to set how how long till app starts attempting to refresh cached task connect data
18
17
  INSTANCE_REDIS_CACHE_PERIOD = 24.hours #Used to determine how long to cached task data will live for
@@ -25,6 +24,8 @@ module ZuoraConnect
25
24
  CATALOG_LOOKUP_CACHE_TIME_KEY = 'CatalogCachedAt'
26
25
  CATALOG_LOOKUP_TTL = 60.seconds
27
26
  CATALOG_LOOKUP_CACHE_RESULT_KEY = 'CatalogCache'
27
+ TIMEZONE_LOG_RATE_LIMIT_KEY = 'TimezoneLoggedAt'
28
+ TIMEZONE_LOG_PERIOD = 4.hours
28
29
  IGNORED_LOCALS = ['fr', 'ja', 'es', 'zh', 'de']
29
30
  INTERNAL_HOSTS = []
30
31
  LOGIN_TENANT_DESTINATION = 'target_login'
@@ -33,7 +34,7 @@ module ZuoraConnect
33
34
  Aws::Errors::MissingCredentialsError,
34
35
  Aws::S3::Errors::AccessDenied,
35
36
  Aws::SES::Errors::AccessDenied,
36
- Aws::KMS::Errors::AccessDeniedException
37
+ Aws::KMS::Errors::AccessDeniedException
37
38
  ].freeze
38
39
  AWS_AUTH_ERRORS_MSG = "AWS Auth Errors".freeze
39
40
 
@@ -245,48 +246,7 @@ module ZuoraConnect
245
246
  ZuoraConnect.logger.error(ex) if !IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
246
247
  end
247
248
 
248
- begin
249
- sql = <<-eos
250
- SELECT zuora_users.zuora_identity_response
251
- FROM "#{self.id}".zuora_users
252
- ORDER BY zuora_users.updated_at DESC
253
- LIMIT 1;
254
- eos
255
- user = ActiveRecord::Base.connection.execute(sql).to_a.first
256
-
257
- if user.present?
258
- zuora_identity_response = JSON.parse(user.fetch('zuora_identity_response', '{}'))
259
- self.user_timezone = zuora_identity_response.values.first&.dig('timeZone')
260
- end
261
- rescue => ex
262
- Rails.logger.error('Failed to get users while setting app instance timezone', ex)
263
- end
264
-
265
- if self.user_timezone.present?
266
- # connect instance which has a custom timezone
267
- if !self.auto_deployed? && (
268
- ActiveSupport::TimeZone[self.task_data.dig('user_settings', 'timezone') || '']&.utc_offset !=
269
- ActiveSupport::TimeZone[self.user_timezone]&.utc_offset
270
- )
271
- if self.environment == 'Production'
272
- ZuoraConnect.logger.error(
273
- "Instance and user timezones are different. User has '#{self.user_timezone}' and " \
274
- "instance has '#{self.task_data.dig('user_settings', 'timezone')}'",
275
- app_instance_id: self.id
276
- )
277
- end
278
- self.user_timezone = nil
279
- Time.zone = self.timezone
280
- else
281
- begin
282
- Time.zone = self.user_timezone
283
- rescue ArgumentError
284
- Time.zone = self.timezone
285
- end
286
- end
287
- else
288
- Time.zone = self.timezone
289
- end
249
+ self.set_timezone
290
250
 
291
251
  if self.task_data.present?
292
252
  tenants = self.task_data.fetch('tenant_ids', [])
@@ -302,7 +262,7 @@ module ZuoraConnect
302
262
  end
303
263
 
304
264
  params = {
305
- name: self.task_data.dig('name'),
265
+ name: self.task_data.dig('name'),
306
266
  zuora_entity_ids: (self.task_data.dig(LOGIN_TENANT_DESTINATION,'entities') || []).map{|e| e['id']}.uniq,
307
267
  zuora_tenant_ids: tenants.map(&:to_s).uniq,
308
268
  organizations: organizations
@@ -311,7 +271,7 @@ module ZuoraConnect
311
271
  client = self.send(LOGIN_TENANT_DESTINATION).client
312
272
  if defined?(client.rest_domain)
313
273
  ZuoraConnect::RequestIdMiddleware.zuora_rest_domain = client.rest_domain
314
- params.merge!({zuora_domain: client.rest_domain, environment: client.environment })
274
+ params.merge!({zuora_domain: client.rest_domain, environment: client.environment })
315
275
  end
316
276
  end
317
277
  params = params.reject{|k,v| !self.attributes.keys.member?(k.to_s) || self[k] == v}
@@ -319,16 +279,80 @@ module ZuoraConnect
319
279
  end
320
280
  end
321
281
 
282
+ def set_timezone(timezone: self.timezone, type: :default)
283
+ if timezone.blank?
284
+ timezone = self.timezone
285
+ end
286
+
287
+ if type == :default
288
+ Time.zone = timezone
289
+ elsif type == :user
290
+ begin
291
+ sql = <<-eos
292
+ SELECT zuora_users.zuora_identity_response
293
+ FROM "#{self.id}".zuora_users
294
+ ORDER BY zuora_users.updated_at DESC
295
+ LIMIT 1;
296
+ eos
297
+ user = ActiveRecord::Base.connection.execute(sql).to_a.first
298
+
299
+ if user.present?
300
+ zuora_identity_response = JSON.parse(user.fetch('zuora_identity_response', '{}'))
301
+ self.user_timezone = zuora_identity_response.values.first&.dig('timeZone')
302
+ else
303
+ if (Redis.current.hget(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id).to_i + TIMEZONE_LOG_PERIOD.to_i) <= Time.now.to_i
304
+ Rails.logger.error('Cannot find any user to set the timezone', app_instance_id: self.id)
305
+ Redis.current.hset(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id, Time.now.to_i)
306
+ end
307
+ end
308
+ rescue => ex
309
+ Rails.logger.error('There is an error while getting timezone users', ex)
310
+ end
311
+
312
+ if self.user_timezone.present?
313
+ # connect instance which has a custom timezone
314
+ if !self.auto_deployed? && (
315
+ ActiveSupport::TimeZone[self.task_data.dig('user_settings', 'timezone') || '']&.utc_offset !=
316
+ ActiveSupport::TimeZone[self.user_timezone]&.utc_offset
317
+ )
318
+ if self.environment == 'Production' &&
319
+ (Redis.current.hget(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id).to_i + TIMEZONE_LOG_PERIOD.to_i) <= Time.now.to_i
320
+ ZuoraConnect.logger.error(
321
+ "Instance and user timezones are different. User has '#{self.user_timezone}' and " \
322
+ "instance has '#{self.task_data.dig('user_settings', 'timezone')}'",
323
+ app_instance_id: self.id
324
+ )
325
+ Redis.current.hset(TIMEZONE_LOG_RATE_LIMIT_KEY, self.id, Time.now.to_i)
326
+ end
327
+ self.user_timezone = nil
328
+ Time.zone = timezone
329
+ else
330
+ begin
331
+ Time.zone = self.user_timezone
332
+ rescue ArgumentError
333
+ Rails.logger.error('Malformed user timezone', app_instance_id: self.id)
334
+ Time.zone = timezone
335
+ end
336
+ end
337
+ else
338
+ Time.zone = timezone
339
+ end
340
+ end
341
+ rescue => e
342
+ Rails.logger.error('Malformed timezone used', e, app_instance_id: self.id)
343
+ Time.zone = self.timezone
344
+ end
345
+
322
346
  def auto_deployed?
323
347
  self.id >= 25000000
324
348
  end
325
349
 
326
- def refresh(session: {})
350
+ def refresh(session: {})
327
351
  refresh_count ||= 0
328
352
  skip_connect ||= false
329
353
  begin
330
354
  #Check how app was deployed
331
- if self.id < 25000000 && !skip_connect
355
+ if self.id < 25000000 && !skip_connect
332
356
  self.check_oauth_state
333
357
  response = HTTParty.get(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json",:body => {:access_token => self.access_token})
334
358
 
@@ -339,7 +363,7 @@ module ZuoraConnect
339
363
  raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("JSON parse error", response.body, response.code)
340
364
  end
341
365
 
342
- self.build_task(task_data: parsed_json, session: session)
366
+ self.build_task(task_data: parsed_json, session: session)
343
367
  if self.kms_key.present? && self.kms_key.match(/^arn:aws:.*/)
344
368
  begin
345
369
  self.zuora_logins = self.strip_cache_data(object: parsed_json.dup, keys: ['applications', 'tokens', 'user_settings'])
@@ -349,7 +373,7 @@ module ZuoraConnect
349
373
  rescue => ex
350
374
  Rails.logger.error(AWS_AUTH_ERRORS_MSG, ex)
351
375
  end
352
- end
376
+ end
353
377
  else
354
378
  raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
355
379
  end
@@ -455,82 +479,6 @@ module ZuoraConnect
455
479
  end
456
480
  Thread.current[:appinstance] = self
457
481
  end
458
-
459
- def self.write_to_telegraf(*args)
460
- if ZuoraConnect.configuration.enable_metrics && !defined?(Prometheus)
461
- @@telegraf_host = ZuoraConnect::Telegraf.new() if @@telegraf_host == nil
462
- unicorn_stats = self.unicorn_listener_stats() if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
463
- @@telegraf_host.write(direction: 'Raindrops', tags: {}, values: unicorn_stats) unless unicorn_stats.blank?
464
- return @@telegraf_host.write(*args)
465
- end
466
- end
467
-
468
- def self.unicorn_listener_stats ()
469
- stats_hash = {}
470
- stats_hash["total_active"] = 0
471
- stats_hash["total_queued"] = 0
472
-
473
- begin
474
- tmp = Unicorn.listener_names
475
- unix = tmp.grep(%r{\A/})
476
- tcp = tmp.grep(/\A.+:\d+\z/)
477
- tcp = nil if tcp.empty?
478
- unix = nil if unix.empty?
479
-
480
-
481
- Raindrops::Linux.tcp_listener_stats(tcp).each do |addr,stats|
482
- stats_hash["active_#{addr}"] = stats.active
483
- stats_hash["queued_#{addr}"] = stats.queued
484
- stats_hash["total_active"] = stats.active + stats_hash["total_active"]
485
- stats_hash["total_queued"] = stats.queued + stats_hash["total_queued"]
486
- end if tcp
487
-
488
- Raindrops::Linux.unix_listener_stats(unix).each do |addr,stats|
489
- stats_hash["active_#{addr}"] = stats.active
490
- stats_hash["queued_#{addr}"] = stats.queued
491
- stats_hash["total_active"] = stats.active + stats_hash["total_active"]
492
- stats_hash["total_queued"] = stats.queued + stats_hash["total_queued"]
493
- end if unix
494
- rescue IOError => ex
495
- rescue => ex
496
- ZuoraConnect.logger.error(ex)
497
- end
498
- return stats_hash
499
- end
500
-
501
- def self.get_metrics(type)
502
- @data = {}
503
-
504
- if type == "versions"
505
- @data = {
506
- app_name: ZuoraConnect::Telegraf.app_name,
507
- url: "dummy",
508
- Version_Gem: ZuoraConnect::VERSION,
509
- Version_Zuora: ZuoraAPI::VERSION ,
510
- Version_Ruby: RUBY_VERSION,
511
- Version_Rails: Rails.version,
512
- hold: 1
513
- }
514
- elsif type == "stats"
515
- begin
516
- Resque.redis.ping
517
- @resque = Resque.info
518
- @data = {
519
- app_name: ZuoraConnect::Telegraf.app_name,
520
- url: "dummy",
521
- Resque:{
522
- Jobs_Finished: @resque[:processed] ,
523
- Jobs_Failed: @resque[:failed],
524
- Jobs_Pending: @resque[:pending],
525
- Workers_Active: @resque[:working],
526
- Workers_Total: @resque[:workers]
527
- }
528
- }
529
- rescue
530
- end
531
- end
532
- return @data
533
- end
534
482
  #### END Task Methods ####
535
483
 
536
484
  #### START Task Methods ####
@@ -573,7 +521,7 @@ module ZuoraConnect
573
521
  end
574
522
  rescue ZuoraConnect::Exceptions::MissMatch => ex
575
523
  raise
576
- rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
524
+ rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
577
525
  raise
578
526
  rescue => ex
579
527
  ZuoraConnect.logger.error("Build Task Error", ex)
@@ -629,10 +577,10 @@ module ZuoraConnect
629
577
  self.refresh if !defined?(self.target_login)
630
578
 
631
579
  response = HTTParty.get("#{ZuoraConnect.configuration.url}/api/#{self.api_version}/tenants/search?hostname=#{self.target_login.client.hostname}&node_id=#{self.zuora_entity_ids.first}")
632
-
580
+
633
581
  if response.success?
634
582
  parsed_json = JSON.parse(response.body)
635
-
583
+
636
584
  #Set Org
637
585
  if self.id >= 25000000 && parsed_json['organization'].present?
638
586
  login_cache = self.zuora_logins
@@ -654,7 +602,7 @@ module ZuoraConnect
654
602
  end
655
603
  end
656
604
  self.save(:validate => false)
657
-
605
+
658
606
  return parsed_json
659
607
  end
660
608
  rescue *(ZuoraAPI::Login::CONNECTION_EXCEPTIONS + ZuoraAPI::Login::CONNECTION_READ_EXCEPTIONS) => ex
@@ -708,7 +656,7 @@ module ZuoraConnect
708
656
  end
709
657
 
710
658
  def refresh_oauth
711
- refresh_oauth_count ||= 0
659
+ refresh_oauth_count ||= 0
712
660
  response = HTTParty.post("#{ZuoraConnect.configuration.url}/oauth/token", body: {
713
661
  :grant_type => "refresh_token",
714
662
  :redirect_uri => ZuoraConnect.configuration.oauth_client_redirect_uri,
@@ -1344,7 +1292,7 @@ module ZuoraConnect
1344
1292
 
1345
1293
  def self.without_sticking
1346
1294
  if self.connection.respond_to?(:without_sticking)
1347
- self.connection.without_sticking do
1295
+ self.connection.without_sticking do
1348
1296
  yield
1349
1297
  end
1350
1298
  else
@@ -49,10 +49,10 @@ if defined? Prometheus
49
49
  prometheus = Prometheus::Client.registry
50
50
 
51
51
  # Create your metrics.
52
- 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)
53
- 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)
54
- 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)
55
- 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)
52
+ ZUORA_VERSION = prometheus.gauge(:zuora_version, docstring: 'The current Zuora Gem version.', labels: %i(version name), preset_labels: { version: ZuoraAPI::VERSION, name: ZuoraObservability::Env.app_name }, store_settings: most_recent_aggregation)
53
+ CONNECT_VERSION = prometheus.gauge(:gem_version, docstring: 'The current Connect Gem version.', labels: %i(version name), preset_labels: { version: ZuoraConnect::VERSION, name: ZuoraObservability::Env.app_name }, store_settings: most_recent_aggregation)
54
+ RAILS_VERSION = prometheus.gauge(:rails_version, docstring: 'The current Rails version.', labels: %i(version name), preset_labels: { version: Rails.version, name: ZuoraObservability::Env.app_name }, store_settings: most_recent_aggregation)
55
+ RUBY_V = prometheus.gauge(:ruby_version, docstring: 'The current Ruby version.', labels: %i(version name), preset_labels: { version: RUBY_VERSION, name: ZuoraObservability::Env.app_name }, store_settings: most_recent_aggregation)
56
56
 
57
57
  ZUORA_VERSION.set(0)
58
58
  CONNECT_VERSION.set(0)
@@ -61,12 +61,12 @@ if defined? Prometheus
61
61
 
62
62
  # Do they have resque jobs?
63
63
  if defined? Resque.redis
64
- 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)
65
- 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)
66
- 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)
67
- 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)
68
- 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)
69
- 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)
64
+ 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: ZuoraObservability::Env.app_name}, store_settings: most_recent_aggregation)
65
+ JOBS_FINISHED = prometheus.gauge(:jobs_finished, docstring: 'Done resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraObservability::Env.app_name}, store_settings: most_recent_aggregation)
66
+ WORKERS_TOTAL = prometheus.gauge(:workers_total, docstring: 'Total resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraObservability::Env.app_name}, store_settings: most_recent_aggregation)
67
+ WORKERS_ACTIVE = prometheus.gauge(:workers_active, docstring: 'Active resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraObservability::Env.app_name}, store_settings: most_recent_aggregation)
68
+ JOBS_FAILED = prometheus.gauge(:jobs_failed, docstring: 'Failed resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraObservability::Env.app_name}, store_settings: most_recent_aggregation)
69
+ JOBS_PENDING = prometheus.gauge(:jobs_pending, docstring: 'Pending resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraObservability::Env.app_name}, store_settings: most_recent_aggregation)
70
70
  end
71
71
 
72
72
  if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
@@ -74,17 +74,17 @@ if defined? Prometheus
74
74
  :unicorn_kills,
75
75
  docstring: 'Unicorn Kills',
76
76
  labels: %i(type name),
77
- preset_labels: {type:'Unicorn-Killer', name: ZuoraConnect::Telegraf.app_name},
77
+ preset_labels: {type:'Unicorn-Killer', name: ZuoraObservability::Env.app_name},
78
78
  store_settings: sum_aggregation
79
79
  )
80
80
 
81
- ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, _|
81
+ ZuoraObservability::Metrics.unicorn_listener.each do |key, _|
82
82
  gauge_name = "unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_')
83
83
  gauge = prometheus.gauge(
84
84
  gauge_name.to_sym,
85
85
  docstring: 'Unicorn Stats',
86
86
  labels: %i(type name),
87
- preset_labels: { type: 'unicorn', name: ZuoraConnect::Telegraf.app_name },
87
+ preset_labels: { type: 'unicorn', name: ZuoraObservability::Env.app_name },
88
88
  store_settings: most_recent_aggregation
89
89
  )
90
90
  Prometheus.const_set(
@@ -12,21 +12,21 @@ class RedisFlash
12
12
  end
13
13
 
14
14
  if defined?(Redis.current)
15
- Redis.current = Redis.new(:id => "#{ZuoraConnect::Telegraf.full_process_name(process_name: 'Redis')}", :url => redis_url, :timeout => 6, :reconnect_attempts => 2)
15
+ Redis.current = Redis.new(:id => "#{ZuoraObservability::Env.full_process_name(process_name: 'Redis')}", :url => redis_url, :timeout => 6, :reconnect_attempts => 2)
16
16
  browser_urls['Redis'] = { "url" => redis_url }
17
17
  if defined?(Resque.redis)
18
18
  if resque_url != redis_url
19
- Resque.redis = Redis.new(:id => "#{ZuoraConnect::Telegraf.full_process_name(process_name: 'Resque')}", :url => resque_url, :timeout => 6, :reconnect_attempts => 2)
19
+ Resque.redis = Redis.new(:id => "#{ZuoraObservability::Env.full_process_name(process_name: 'Resque')}", :url => resque_url, :timeout => 6, :reconnect_attempts => 2)
20
20
  browser_urls['Resque'] = { "url" => resque_url }
21
21
  else
22
22
  Resque.redis = Redis.current
23
23
  end
24
24
  end
25
25
  if defined?(flash_url.present?)
26
- RedisFlash.current = Redis.new(:id => "#{ZuoraConnect::Telegraf.full_process_name(process_name: 'Flash')}", :url => flash_url, :timeout => 6, :reconnect_attempts => 2)
26
+ RedisFlash.current = Redis.new(:id => "#{ZuoraObservability::Env.full_process_name(process_name: 'Flash')}", :url => flash_url, :timeout => 6, :reconnect_attempts => 2)
27
27
  browser_urls['Flash'] = { "url" => flash_url }
28
28
  end
29
29
  end
30
30
  if defined?(RedisBrowser)
31
31
  RedisBrowser.configure("connections" => browser_urls)
32
- end
32
+ end
@@ -36,13 +36,13 @@ Resque.module_eval do
36
36
  end
37
37
 
38
38
  if defined?(Resque.logger)
39
- Resque.logger = ZuoraConnect.custom_logger(name: "Resque", type: 'Monologger', level: MonoLogger::INFO)
40
- Resque::Scheduler.logger = ZuoraConnect.custom_logger(name: "ResqueScheduler") if defined?(Resque::Scheduler)
39
+ Resque.logger = ZuoraObservability::Logger.custom_logger(name: "Resque", type: 'Monologger', level: MonoLogger::INFO)
40
+ Resque::Scheduler.logger = ZuoraObservability::Logger.custom_logger(name: "ResqueScheduler") if defined?(Resque::Scheduler)
41
41
  end
42
42
  if defined?(Delayed::Worker.logger)
43
- Delayed::Worker.logger = ZuoraConnect.custom_logger(name: "DelayedJob", type: 'Monologger', level: MonoLogger::INFO)
43
+ Delayed::Worker.logger = ZuoraObservability::Logger.custom_logger(name: "DelayedJob", type: 'Monologger', level: MonoLogger::INFO)
44
44
  end
45
45
 
46
- Makara::Logging::Logger.logger = ZuoraConnect.custom_logger(name: "Makara") if defined?(Makara)
47
- ElasticAPM.agent.config.logger = ZuoraConnect.custom_logger(name: "ElasticAPM", level: MonoLogger::WARN) if defined?(ElasticAPM) && ElasticAPM.running?
48
- ActionMailer::Base.logger = ZuoraConnect.custom_logger(name: "ActionMailer", type: 'Monologger') if defined?(ActionMailer)
46
+ Makara::Logging::Logger.logger = ZuoraObservability::Logger.custom_logger(name: "Makara") if defined?(Makara)
47
+ ElasticAPM.agent.config.logger = ZuoraObservability::Logger.custom_logger(name: "ElasticAPM", level: MonoLogger::WARN) if defined?(ElasticAPM) && ElasticAPM.running?
48
+ ActionMailer::Base.logger = ZuoraObservability::Logger.custom_logger(name: "ActionMailer", type: 'Monologger') if defined?(ActionMailer)
@@ -6,7 +6,7 @@ if defined?(Unicorn::WorkerKiller)
6
6
  if defined?(Prometheus)
7
7
  Prometheus::UNICORN_KILLS.set(1)
8
8
  else
9
- ZuoraConnect::AppInstance.write_to_telegraf(direction: 'Unicorn-Killer', tags: {app_instance: 0}, values: {kill: 1})
9
+ ZuoraObservability::Metrics.write_to_telegraf(direction: 'Unicorn-Killer', tags: {app_instance: 0}, values: {kill: 1})
10
10
  end
11
11
  end
12
12
  end
@@ -34,4 +34,4 @@ if defined?(Unicorn::HttpServer) && defined?(Prometheus)
34
34
  class Unicorn::Worker
35
35
  prepend WorkerExtensions
36
36
  end
37
- end
37
+ end
@@ -1,6 +1,5 @@
1
1
  ZuoraConnect::Engine.routes.draw do
2
2
  get '/health' => 'static#health'
3
- get '/internal/data' => 'static#metrics'
4
3
  post '/initialize_app' => 'static#initialize_app'
5
4
 
6
5
  if ENV['PROVISION_USER'].present? && ENV['PROVISION_SECRET'].present?
@@ -68,12 +68,12 @@ class HttpLogger
68
68
  log_request_body(request)
69
69
  log_request_headers(request)
70
70
  if defined?(response) && response
71
- tags = tags.merge({status: response.code.to_i})
71
+ tags = tags.merge({status: response.code.to_i})
72
72
  log_response_code(response)
73
73
  log_response_headers(response)
74
74
  log_response_body(response.body)
75
75
  end
76
- ZuoraConnect::AppInstance.write_to_telegraf(direction: :outbound, tags: tags, values: values)
76
+ ZuoraObservability::Metrics.write_to_telegraf(direction: :outbound, tags: tags, values: values)
77
77
  end
78
78
  end
79
79
 
@@ -95,7 +95,7 @@ class HttpLogger
95
95
  end
96
96
 
97
97
  HTTP_METHODS_WITH_BODY = Set.new(%w(POST PUT GET PATCH))
98
-
98
+
99
99
  def log_request_body(request)
100
100
  if self.class.log_request_body
101
101
  if HTTP_METHODS_WITH_BODY.include?(request.method)
@@ -149,8 +149,8 @@ class HttpLogger
149
149
  def truncate_body(body)
150
150
  if collapse_body_limit && collapse_body_limit > 0 && body && body.size >= collapse_body_limit
151
151
  body_piece_size = collapse_body_limit / 2
152
- body[0..body_piece_size] +
153
- "\n\n<some data truncated>\n\n" +
152
+ body[0..body_piece_size] +
153
+ "\n\n<some data truncated>\n\n" +
154
154
  body[(body.size - body_piece_size)..body.size]
155
155
  else
156
156
  body
@@ -203,7 +203,7 @@ class Net::HTTP
203
203
 
204
204
  def request(request, body = nil, &block)
205
205
  HttpLogger.perform(self, request, body) do
206
- request_without_logging(request, body, &block)
206
+ request_without_logging(request, body, &block)
207
207
  end
208
208
  end
209
209
  end
@@ -215,4 +215,4 @@ if defined?(Rails)
215
215
  HttpLogger.logger = ZuoraConnect.logger unless HttpLogger.logger
216
216
  end
217
217
  end
218
- end
218
+ end
@@ -17,7 +17,7 @@ module ZuoraConnect
17
17
  # payloads with 500 requests do not have status as it is not set by the controller
18
18
  # https://github.com/rails/rails/issues/33335
19
19
  #status_code = payload[:status] ? payload[:status] : payload[:exception_object].present? ? 500 : ""
20
- if payload[:exception].present?
20
+ if payload[:exception].present?
21
21
  status_code, exception = [500, payload[:exception].first]
22
22
  else
23
23
  status_code, exception = [payload[:status], nil]
@@ -28,7 +28,7 @@ module ZuoraConnect
28
28
  values = {view_time: payload[:view_runtime], db_time: payload[:db_runtime], response_time: ((finished-started)*1000)}.compact
29
29
  values = values.map{ |k,v| [k,v.round(2)]}.to_h
30
30
 
31
- ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
31
+ ZuoraObservability::Metrics.write_to_telegraf(direction: :inbound, tags: tags, values: values)
32
32
  end
33
33
  end
34
34
 
@@ -42,7 +42,7 @@ module ZuoraConnect
42
42
  end
43
43
 
44
44
  def call(env)
45
- @bad_headers = ["HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED_HOST", "HTTP_X_FORWARDED_PORT", "HTTP_X_FORWARDED_PROTO", "HTTP_X_FORWARDED_SCHEME", "HTTP_X_FORWARDED_SSL"]
45
+ @bad_headers = ["HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED_HOST", "HTTP_X_FORWARDED_PORT", "HTTP_X_FORWARDED_PROTO", "HTTP_X_FORWARDED_SCHEME", "HTTP_X_FORWARDED_SSL"]
46
46
  if !ActionDispatch::Request::HTTP_METHODS.include?(env["REQUEST_METHOD"].upcase)
47
47
  [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]]
48
48
  else
@@ -66,14 +66,14 @@ module ZuoraConnect
66
66
 
67
67
  if defined?(Prometheus) && env['PATH_INFO'] == '/connect/internal/metrics'
68
68
  # Prometheus Stuff
69
- metrics = ZuoraConnect::AppInstance.get_metrics('stats')
69
+ metrics = ZuoraObservability::Metrics.resque
70
70
  redis_up = metrics.present? && metrics.dig(:Resque, :Workers_Total).present? ? 1 : 0
71
71
  Prometheus::REDIS_CONNECTION.set(redis_up)
72
72
 
73
73
  process_prometheus_metric(metrics: metrics)
74
74
 
75
75
  if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
76
- ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, value|
76
+ ZuoraObservability::Metrics.unicorn_listener.each do |key, value|
77
77
  gauge = Prometheus.const_get("unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_').upcase)
78
78
  gauge.set(value) if gauge.present?
79
79
  end
@@ -84,13 +84,13 @@ module ZuoraConnect
84
84
  start_time = Time.now
85
85
  begin
86
86
  @status, @headers, @response = @app.call(env)
87
- ensure
88
-
87
+ ensure
88
+
89
89
  # If the url contains any CSS or JavaScript files then do not collect metrics for them
90
90
  if ["css", "assets", "jpg", "png", "jpeg", "ico"].any? { |word| env['PATH_INFO'].include?(word) } || /.*\.js$/.match(env['PATH_INFO'])
91
91
  tags = {status: @status, controller: 'ActionController', action: 'Assets', app_instance: 0}
92
92
  values = {response_time: ((Time.now - start_time)*1000).round(2) }
93
- ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: 'request-inbound-assets', tags: tags, values: values)
93
+ ZuoraObservability::Metrics.write_to_telegraf(direction: 'request-inbound-assets', tags: tags, values: values)
94
94
  end
95
95
 
96
96
  # Uncomment following block of code for handling engine requests/requests without controller
@@ -112,7 +112,7 @@ module ZuoraConnect
112
112
 
113
113
  values = {response_time: ((Time.now - start_time)*1000).round(2) }
114
114
 
115
- ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
115
+ ZuoraObservability::Metrics.write_to_telegraf(direction: :inbound, tags: tags, values: values)
116
116
  end
117
117
  end
118
118
  Thread.current[:inbound_metric] = nil
@@ -140,7 +140,7 @@ module ZuoraConnect
140
140
  gauge_name.to_sym,
141
141
  docstring: "#{key} metric",
142
142
  labels: %i(type name),
143
- preset_labels: { type: type, name: ZuoraConnect::Telegraf.app_name },
143
+ preset_labels: { type: type, name: ZuoraObservability::Env.app_name },
144
144
  store_settings: most_recent_aggregation
145
145
  )
146
146
  gauge.set(value)
@@ -9,12 +9,11 @@ require 'resque/silence_done'
9
9
  require 'resque/self_lookup'
10
10
  require 'resque/plugins/custom_logger'
11
11
  require 'resque/plugins/app_instance_job'
12
- require 'logging/connect_formatter'
13
- require 'metrics/influx/point_value'
14
12
  require 'metrics/net'
15
13
  require 'mono_logger'
16
14
  require 'zuora_connect/zuora_audit'
17
15
  require 'active_record'
16
+ require 'zuora_observability'
18
17
  ::ActiveRecord::Base.send :include, ZuoraConnect::ZuoraAudit
19
18
 
20
19
  module ZuoraConnect
@@ -29,68 +28,9 @@ module ZuoraConnect
29
28
  when 'test'
30
29
  Rails.logger
31
30
  else
32
- @logger ||= custom_logger(name: "Connect", level: Rails.logger.level)
31
+ @logger ||= ZuoraObservability::Logger.custom_logger(name: "Connect", level: Rails.logger.level)
33
32
  end
34
33
  end
35
-
36
- def custom_logger(name: "", level: Rails.logger.present? ? Rails.logger.level : MonoLogger::INFO, type: :ougai)
37
- #puts name + ' - ' + {Logger::WARN => 'Logger::WARN', Logger::ERROR => 'Logger::ERROR', Logger::DEBUG => 'Logger::DEBUG', Logger::INFO => 'Logger::INFO' }[level] + ' - '
38
- if type == :ougai
39
- require 'ougai'
40
- require "ougai/formatters/customizable"
41
- #logger = Ougai::Logger.new(MonoLogger.new(STDOUT))
42
- logger = Ougai::Logger.new(STDOUT)
43
- logger.level = level
44
- if ZuoraConnect.configuration.json_logging
45
- logger.formatter = Ougai::Formatters::ConnectFormatter.new(name)
46
- logger.before_log = lambda do |data|
47
- data[:trace_id] = ZuoraConnect::RequestIdMiddleware.request_id if ZuoraConnect::RequestIdMiddleware.request_id.present?
48
- data[:zuora_trace_id] = ZuoraConnect::RequestIdMiddleware.zuora_request_id if ZuoraConnect::RequestIdMiddleware.zuora_request_id.present?
49
- #data[:traces] = {amazon_id: data[:trace_id], zuora_id: data[:zuora_trace_id]}
50
- end
51
- else
52
- logger.formatter = Ougai::Formatters::Customizable.new(
53
- format_err: proc do |data|
54
- next nil unless data.key?(:err)
55
- err = data.delete(:err)
56
- " #{err[:name]} (#{err[:message]})\n #{err[:stack]}"
57
- end,
58
- format_data: proc do |data|
59
- data.delete(:app_instance_id); data.delete(:tenant_ids); data.delete(:organization); data.delete(:environment)
60
- format('%s %s: %s', 'DATA'.ljust(6), Time.now.strftime('%FT%T.%6NZ'), "#{data.to_json}") if data.present?
61
- end,
62
- format_msg: proc do |severity, datetime, _progname, data|
63
- msg = data.delete(:msg)
64
- format('%s %s: %s', severity.ljust(6), datetime, msg)
65
- end
66
- )
67
- logger.formatter.datetime_format = '%FT%T.%6NZ'
68
- end
69
- else
70
- logger = MonoLogger.new(STDOUT)
71
- logger.level = level
72
- logger.formatter = proc do |serverity, datetime, progname, msg|
73
- begin
74
- msg = JSON.parse(msg)
75
- rescue JSON::ParserError => ex
76
- end
77
- if ZuoraConnect.configuration.json_logging
78
- require 'json'
79
- store = {
80
- name: name,
81
- level: serverity,
82
- timestamp: datetime.strftime('%FT%T.%6NZ'),
83
- pid: Process.pid,
84
- message: name == "ActionMailer" ? msg.strip : msg
85
- }
86
- JSON.dump(store) + "\n"
87
- else
88
- format('%s %s: %s', serverity.ljust(6), datetime, msg) + "\n"
89
- end
90
- end
91
- end
92
- return logger
93
- end
94
34
  end
95
35
 
96
36
  module Controllers
@@ -147,7 +87,7 @@ module ZuoraConnect
147
87
  verify_server_cert: false,
148
88
  log_level: Logger::INFO,
149
89
  service_name: ENV['DEIS_APP'].present? ? ENV['DEIS_APP'] : Rails.application.class.parent_name,
150
- logger: ZuoraConnect.custom_logger(name: "ElasticAPM", level: MonoLogger::WARN)
90
+ logger: ZuoraObservability::Logger.custom_logger(name: "ElasticAPM", level: MonoLogger::WARN)
151
91
  })
152
92
  defaults.merge!({disable_send: true}) if defined?(Rails::Console)
153
93
 
@@ -138,12 +138,8 @@ module ZuoraConnect
138
138
  end
139
139
  ZuoraConnect.logger.error(ex) if !ZuoraConnect::AppInstance::IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
140
140
  end
141
- begin
142
- if @appinstance.user_timezone.blank?
143
- Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
144
- end
145
- rescue
146
- ZuoraConnect.logger.error(ex)
141
+ if @appinstance.user_timezone.blank?
142
+ @appinstance.set_timezone(timezone: session["#{@appinstance.id}::user::timezone"], type: :default)
147
143
  end
148
144
  end
149
145
  rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
@@ -10,9 +10,10 @@ module ZuoraConnect
10
10
 
11
11
  initializer "connect", before: :load_config_initializers do |app|
12
12
  Rails.application.routes.prepend do
13
+ get '/connect/internal/data' => 'zuora_observability/metrics#metrics'
13
14
  mount ZuoraConnect::Engine, at: "/connect"
14
15
  match '/api/connect/health', via: :all, to: 'zuora_connect/static#health'
15
- match '/api/connect/internal/data', via: :all, to: 'zuora_connect/static#metrics'
16
+ match '/api/connect/internal/data', via: :all, to: 'zuora_observability/metrics#metrics'
16
17
  end
17
18
  end
18
19
 
@@ -46,68 +46,5 @@ module ZuoraConnect
46
46
 
47
47
  # hook to process_action
48
48
  ActiveSupport::Notifications.subscribe('process_action.action_controller', ZuoraConnect::PageRequest.new)
49
-
50
- initializer(:rails_stdout_logging, before: :initialize_logger) do
51
- require 'lograge'
52
-
53
- Rails.configuration.logger = ZuoraConnect.custom_logger(name: "Rails")
54
- if !Rails.env.test? && !Rails.env.development?
55
- Rails.configuration.lograge.enabled = true
56
- Rails.configuration.colorize_logging = false
57
- end
58
-
59
- if Rails.configuration.lograge.enabled
60
- if Rails.configuration.logger.class.to_s == 'Ougai::Logger'
61
- Rails.configuration.lograge.formatter = Class.new do |fmt|
62
- def fmt.call(data)
63
- { msg: 'Rails Request', request: data }
64
- end
65
- end
66
- end
67
- #Rails.configuration.lograge.formatter = Lograge::Formatters::Json.new
68
- Rails.configuration.lograge.custom_options = lambda do |event|
69
- exceptions = %w(controller action format)
70
- items = {
71
- #time: event.time.strftime('%FT%T.%6N'),
72
- params: event.payload[:params].as_json(except: exceptions).to_json.to_s
73
- }
74
- items.merge!({exception_object: event.payload[:exception_object]}) if event.payload[:exception_object].present?
75
- items.merge!({exception: event.payload[:exception]}) if event.payload[:exception].present?
76
-
77
- if event.payload[:headers].present?
78
- # By convertion, headers usually do not have dots. Nginx even rejects headers with dots
79
- # All Rails headers are namespaced, like 'rack.input'.
80
- # Thus, we can obtain the client headers by rejecting dots
81
- request_headers =
82
- event.payload[:headers].env.
83
- reject { |key| key.to_s.include?('.') || REQUEST_HEADERS_TO_IGNORE.include?(key.to_s) }
84
- begin
85
- if request_headers["HTTP_AUTHORIZATION"].present?
86
- if request_headers["HTTP_AUTHORIZATION"].include?("Basic")
87
- user_password = request_headers["HTTP_AUTHORIZATION"].split("Basic").last.strip
88
- user, password = Base64.decode64(user_password).split(":")
89
- request_headers["HTTP_AUTHORIZATION"] = "Basic #{user}:ValueFiltered"
90
- elsif
91
- request_headers["HTTP_AUTHORIZATION"] = "ValueFiltered"
92
- end
93
- end
94
- request_headers["HTTP_API_TOKEN"] = "ValueFiltered" if request_headers["HTTP_API_TOKEN"].present?
95
- rescue
96
- request_headers.delete("HTTP_API_TOKEN")
97
- request_headers.delete("HTTP_AUTHORIZATION")
98
- end
99
- items.merge!({ headers: request_headers.to_s })
100
- end
101
-
102
- if Thread.current[:appinstance].present?
103
- items.merge!({connect_user: Thread.current[:appinstance].connect_user, new_session: Thread.current[:appinstance].new_session_message})
104
- if Thread.current[:appinstance].logitems.present? && Thread.current[:appinstance].logitems.class == Hash
105
- items.merge!(Thread.current[:appinstance].logitems)
106
- end
107
- end
108
- return items
109
- end
110
- end
111
- end
112
49
  end
113
50
  end
@@ -1,3 +1,3 @@
1
1
  module ZuoraConnect
2
- VERSION = "2.0.60t"
2
+ VERSION = "3.0.0-a"
3
3
  end
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.60t
4
+ version: 3.0.0.pre.a
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-16 00:00:00.000000000 Z
11
+ date: 2020-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: apartment
@@ -182,6 +182,20 @@ dependencies:
182
182
  - - ">="
183
183
  - !ruby/object:Gem::Version
184
184
  version: '0'
185
+ - !ruby/object:Gem::Dependency
186
+ name: zuora_observability
187
+ requirement: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ type: :runtime
193
+ prerelease: false
194
+ version_requirements: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
185
199
  - !ruby/object:Gem::Dependency
186
200
  name: rspec
187
201
  requirement: !ruby/object:Gem::Requirement
@@ -318,7 +332,6 @@ files:
318
332
  - app/models/zuora_connect/app_instance.rb
319
333
  - app/models/zuora_connect/app_instance_base.rb
320
334
  - app/models/zuora_connect/login.rb
321
- - app/models/zuora_connect/telegraf.rb
322
335
  - app/models/zuora_connect/zuora_user.rb
323
336
  - app/views/layouts/zuora_connect/application.html.erb
324
337
  - app/views/sql/refresh_aggregate_table.txt
@@ -353,8 +366,6 @@ files:
353
366
  - db/migrate/20190520232222_add_unique_index.rb
354
367
  - db/migrate/20190520232223_add_provisioning_fields.rb
355
368
  - db/migrate/20190520232224_add_environment_fields.rb
356
- - lib/logging/connect_formatter.rb
357
- - lib/metrics/influx/point_value.rb
358
369
  - lib/metrics/net.rb
359
370
  - lib/middleware/bad_multipart_form_data_sanitizer.rb
360
371
  - lib/middleware/json_parse_errors.rb
@@ -1,97 +0,0 @@
1
- module ZuoraConnect
2
- class Telegraf
3
- attr_accessor :host
4
-
5
- OUTBOUND_METRICS = true
6
- OUTBOUND_METRICS_NAME = "request-outbound"
7
- INBOUND_METRICS = true
8
- INBOUND_METRICS_NAME = "request-inbound"
9
-
10
- def initialize
11
- self.connect
12
- end
13
-
14
- def connect
15
- ZuoraConnect.logger.debug(self.format_metric_log('Telegraf','Need new connection')) if ZuoraConnect.configuration.telegraf_debug
16
- uri = URI.parse(ZuoraConnect.configuration.telegraf_endpoint)
17
- self.host = UDPSocket.new.tap do |socket|
18
- socket.connect uri.host, uri.port
19
- end
20
- rescue => ex
21
- self.host = nil
22
- ZuoraConnect.logger.warn(self.format_metric_log('Telegraf', "Failed to connect: #{ex.class}")) if Rails.env.to_s != 'production'
23
- end
24
-
25
- def write(direction: 'Unknown', tags: {}, values: {})
26
- time = Benchmark.measure do |bench|
27
- # To avoid writing metrics from rspec tests
28
- if Rails.env.to_sym != :test
29
- app_instance = Thread.current[:appinstance].present? ? Thread.current[:appinstance].id : 0
30
- tags = { app_name: self.class.app_name, process_type: self.class.process_type, app_instance: app_instance, pod_name: self.class.pod_name}.merge(tags)
31
-
32
- if direction == :inbound
33
- if INBOUND_METRICS && !Thread.current[:inbound_metric].to_bool
34
- self.write_udp(series: INBOUND_METRICS_NAME, tags: tags, values: values)
35
- Thread.current[:inbound_metric] = true
36
- else
37
- return
38
- end
39
- elsif direction == :outbound
40
- self.write_udp(series: OUTBOUND_METRICS_NAME, tags: tags, values: values) if OUTBOUND_METRICS
41
- else
42
- self.write_udp(series: direction, tags: tags, values: values)
43
- end
44
- end
45
- end
46
- if ZuoraConnect.configuration.telegraf_debug
47
- ZuoraConnect.logger.debug(self.format_metric_log('Telegraf', tags.to_s))
48
- ZuoraConnect.logger.debug(self.format_metric_log('Telegraf', values.to_s))
49
- ZuoraConnect.logger.debug(self.format_metric_log('Telegraf', "Writing '#{direction.capitalize}': #{time.real.round(5)} ms"))
50
- end
51
- end
52
-
53
-
54
- def write_udp(series: '', tags: {}, values: {})
55
- return if !values.present?
56
- self.host.write InfluxDB::PointValue.new({series: series, tags: tags, values: values}).dump
57
- rescue => ex
58
- self.connect
59
- ZuoraConnect.logger.warn(self.format_metric_log('Telegraf',"Failed to write udp: #{ex.class}")) if Rails.env.to_s != 'production'
60
- end
61
-
62
- def format_metric_log(message, dump = nil)
63
- message_color, dump_color = "1;91", "0;1"
64
- log_entry = " \e[#{message_color}m#{message}\e[0m "
65
- log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
66
- if Rails.env == :development
67
- log_entry
68
- else
69
- [message, dump].compact.join(' - ')
70
- end
71
- end
72
-
73
- def self.app_name
74
- return ENV['DEIS_APP'].present? ? ENV['DEIS_APP'] : Rails.application.class.parent_name
75
- end
76
-
77
- def self.pod_name
78
- return ENV['HOSTNAME'].present? ? ENV['HOSTNAME'] : Socket.gethostname
79
- end
80
-
81
- def self.full_process_name(process_name: nil, function: nil)
82
- keys = [self.pod_name, process_name.present? ? process_name : self.process_type, Process.pid, function]
83
- return keys.compact.join('][').prepend('[').concat(']')
84
- end
85
-
86
- # Returns the process type if any
87
- def self.process_type(default: 'Unknown')
88
- p_type = default
89
- if ENV['HOSTNAME'] && ENV['DEIS_APP']
90
- temp = ENV['HOSTNAME'].split(ENV['DEIS_APP'])[1]
91
- temp = temp.split(/(-[0-9a-zA-Z]{5})$/)[0] # remove the 5 char hash
92
- p_type = temp[1, temp.rindex("-")-1]
93
- end
94
- return p_type
95
- end
96
- end
97
- end
@@ -1,44 +0,0 @@
1
- require 'ougai/formatters/base'
2
- require 'ougai/formatters/for_json'
3
-
4
- module Ougai
5
- module Formatters
6
- # A JSON formatter compatible with node-bunyan
7
- class ConnectFormatter < Base
8
- include ForJson
9
-
10
- # Intialize a formatter
11
- # @param [String] app_name application name (execution program name if nil)
12
- # @param [String] hostname hostname (hostname if nil)
13
- # @param [Hash] opts the initial values of attributes
14
- # @option opts [String] :trace_indent (2) the value of trace_indent attribute
15
- # @option opts [String] :trace_max_lines (100) the value of trace_max_lines attribute
16
- # @option opts [String] :serialize_backtrace (true) the value of serialize_backtrace attribute
17
- # @option opts [String] :jsonize (true) the value of jsonize attribute
18
- # @option opts [String] :with_newline (true) the value of with_newline attribute
19
- def initialize(app_name = nil, hostname = nil, opts = {})
20
- aname, hname, opts = Base.parse_new_params([app_name, hostname, opts])
21
- super(aname, hname, opts)
22
- init_opts_for_json(opts)
23
- end
24
-
25
- def _call(severity, time, progname, data)
26
- data.merge!({message: data.delete(:msg)})
27
- if data[:timestamp].present?
28
- time = data[:timestamp]
29
- data.delete(:timestamp)
30
- end
31
- dump({
32
- name: progname || @app_name,
33
- pid: $$,
34
- level: severity,
35
- timestamp: time.utc.strftime('%FT%T.%6NZ'),
36
- }.merge(data))
37
- end
38
-
39
- def convert_time(data)
40
- #data[:timestamp] = format_datetime(data[:time])
41
- end
42
- end
43
- end
44
- end
@@ -1,79 +0,0 @@
1
- module InfluxDB
2
- # Convert data point to string using Line protocol
3
- class PointValue
4
- attr_reader :series, :values, :tags, :timestamp
5
-
6
- def initialize(data)
7
- @series = escape data[:series], :measurement
8
- @values = escape_values data[:values]
9
- @tags = escape_tags data[:tags]
10
- @timestamp = data[:timestamp]
11
- end
12
-
13
- def dump
14
- dump = @series.dup
15
- dump << ",#{@tags}" if @tags
16
- dump << " #{@values}"
17
- dump << " #{@timestamp}" if @timestamp
18
- dump
19
- end
20
-
21
- private
22
-
23
- ESCAPES = {
24
- measurement: [' '.freeze, ','.freeze],
25
- tag_key: ['='.freeze, ' '.freeze, ','.freeze],
26
- tag_value: ['='.freeze, ' '.freeze, ','.freeze],
27
- field_key: ['='.freeze, ' '.freeze, ','.freeze, '"'.freeze],
28
- field_value: ["\\".freeze, '"'.freeze],
29
- }.freeze
30
-
31
- private_constant :ESCAPES
32
-
33
- def escape(str, type)
34
- # rubocop:disable Layout/AlignParameters
35
- str = str.encode "UTF-8".freeze, "UTF-8".freeze,
36
- invalid: :replace,
37
- undef: :replace,
38
- replace: "".freeze
39
- # rubocop:enable Layout/AlignParameters
40
-
41
- ESCAPES[type].each do |ch|
42
- str = str.gsub(ch) { "\\#{ch}" }
43
- end
44
- str
45
- end
46
-
47
- def escape_values(values)
48
- return if values.nil?
49
- values.map do |k, v|
50
- key = escape(k.to_s, :field_key)
51
- val = escape_value(v)
52
- "#{key}=#{val}"
53
- end.join(",".freeze)
54
- end
55
-
56
- def escape_value(value)
57
- if value.is_a?(String)
58
- '"'.freeze + escape(value, :field_value) + '"'.freeze
59
- elsif value.is_a?(Integer)
60
- "#{value}i"
61
- else
62
- value.to_s
63
- end
64
- end
65
-
66
- def escape_tags(tags)
67
- return if tags.nil?
68
-
69
- tags = tags.map do |k, v|
70
- key = escape(k.to_s, :tag_key)
71
- val = escape(v.to_s, :tag_value)
72
-
73
- "#{key}=#{val}" unless key == "".freeze || val == "".freeze
74
- end.compact
75
-
76
- tags.join(",") unless tags.empty?
77
- end
78
- end
79
- end