apisonator 2.100.0

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.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +317 -0
  3. data/Gemfile +11 -0
  4. data/Gemfile.base +65 -0
  5. data/Gemfile.lock +319 -0
  6. data/Gemfile.on_prem +1 -0
  7. data/Gemfile.on_prem.lock +297 -0
  8. data/LICENSE +202 -0
  9. data/NOTICE +15 -0
  10. data/README.md +230 -0
  11. data/Rakefile +287 -0
  12. data/apisonator.gemspec +47 -0
  13. data/app/api/api.rb +13 -0
  14. data/app/api/internal/alert_limits.rb +32 -0
  15. data/app/api/internal/application_keys.rb +49 -0
  16. data/app/api/internal/application_referrer_filters.rb +43 -0
  17. data/app/api/internal/applications.rb +77 -0
  18. data/app/api/internal/errors.rb +54 -0
  19. data/app/api/internal/events.rb +42 -0
  20. data/app/api/internal/internal.rb +104 -0
  21. data/app/api/internal/metrics.rb +40 -0
  22. data/app/api/internal/service_tokens.rb +46 -0
  23. data/app/api/internal/services.rb +58 -0
  24. data/app/api/internal/stats.rb +42 -0
  25. data/app/api/internal/usagelimits.rb +62 -0
  26. data/app/api/internal/utilization.rb +23 -0
  27. data/bin/3scale_backend +223 -0
  28. data/bin/3scale_backend_worker +26 -0
  29. data/config.ru +4 -0
  30. data/config/puma.rb +192 -0
  31. data/config/schedule.rb +9 -0
  32. data/ext/mkrf_conf.rb +64 -0
  33. data/lib/3scale/backend.rb +67 -0
  34. data/lib/3scale/backend/alert_limit.rb +56 -0
  35. data/lib/3scale/backend/alerts.rb +137 -0
  36. data/lib/3scale/backend/analytics/kinesis.rb +3 -0
  37. data/lib/3scale/backend/analytics/kinesis/adapter.rb +180 -0
  38. data/lib/3scale/backend/analytics/kinesis/exporter.rb +86 -0
  39. data/lib/3scale/backend/analytics/kinesis/job.rb +135 -0
  40. data/lib/3scale/backend/analytics/redshift.rb +3 -0
  41. data/lib/3scale/backend/analytics/redshift/adapter.rb +367 -0
  42. data/lib/3scale/backend/analytics/redshift/importer.rb +83 -0
  43. data/lib/3scale/backend/analytics/redshift/job.rb +33 -0
  44. data/lib/3scale/backend/application.rb +330 -0
  45. data/lib/3scale/backend/application_events.rb +76 -0
  46. data/lib/3scale/backend/background_job.rb +65 -0
  47. data/lib/3scale/backend/configurable.rb +20 -0
  48. data/lib/3scale/backend/configuration.rb +151 -0
  49. data/lib/3scale/backend/configuration/loader.rb +42 -0
  50. data/lib/3scale/backend/constants.rb +19 -0
  51. data/lib/3scale/backend/cors.rb +84 -0
  52. data/lib/3scale/backend/distributed_lock.rb +67 -0
  53. data/lib/3scale/backend/environment.rb +21 -0
  54. data/lib/3scale/backend/error_storage.rb +52 -0
  55. data/lib/3scale/backend/errors.rb +343 -0
  56. data/lib/3scale/backend/event_storage.rb +120 -0
  57. data/lib/3scale/backend/experiment.rb +84 -0
  58. data/lib/3scale/backend/extensions.rb +5 -0
  59. data/lib/3scale/backend/extensions/array.rb +19 -0
  60. data/lib/3scale/backend/extensions/hash.rb +26 -0
  61. data/lib/3scale/backend/extensions/nil_class.rb +13 -0
  62. data/lib/3scale/backend/extensions/redis.rb +44 -0
  63. data/lib/3scale/backend/extensions/string.rb +13 -0
  64. data/lib/3scale/backend/extensions/time.rb +110 -0
  65. data/lib/3scale/backend/failed_jobs_scheduler.rb +141 -0
  66. data/lib/3scale/backend/job_fetcher.rb +122 -0
  67. data/lib/3scale/backend/listener.rb +728 -0
  68. data/lib/3scale/backend/listener_metrics.rb +99 -0
  69. data/lib/3scale/backend/logging.rb +48 -0
  70. data/lib/3scale/backend/logging/external.rb +44 -0
  71. data/lib/3scale/backend/logging/external/impl.rb +93 -0
  72. data/lib/3scale/backend/logging/external/impl/airbrake.rb +66 -0
  73. data/lib/3scale/backend/logging/external/impl/bugsnag.rb +69 -0
  74. data/lib/3scale/backend/logging/external/impl/default.rb +18 -0
  75. data/lib/3scale/backend/logging/external/resque.rb +57 -0
  76. data/lib/3scale/backend/logging/logger.rb +18 -0
  77. data/lib/3scale/backend/logging/middleware.rb +62 -0
  78. data/lib/3scale/backend/logging/middleware/json_writer.rb +21 -0
  79. data/lib/3scale/backend/logging/middleware/text_writer.rb +60 -0
  80. data/lib/3scale/backend/logging/middleware/writer.rb +143 -0
  81. data/lib/3scale/backend/logging/worker.rb +107 -0
  82. data/lib/3scale/backend/manifest.rb +80 -0
  83. data/lib/3scale/backend/memoizer.rb +277 -0
  84. data/lib/3scale/backend/metric.rb +275 -0
  85. data/lib/3scale/backend/metric/collection.rb +91 -0
  86. data/lib/3scale/backend/oauth.rb +4 -0
  87. data/lib/3scale/backend/oauth/token.rb +26 -0
  88. data/lib/3scale/backend/oauth/token_key.rb +30 -0
  89. data/lib/3scale/backend/oauth/token_storage.rb +313 -0
  90. data/lib/3scale/backend/oauth/token_value.rb +25 -0
  91. data/lib/3scale/backend/period.rb +3 -0
  92. data/lib/3scale/backend/period/boundary.rb +107 -0
  93. data/lib/3scale/backend/period/cache.rb +28 -0
  94. data/lib/3scale/backend/period/period.rb +402 -0
  95. data/lib/3scale/backend/queue_storage.rb +16 -0
  96. data/lib/3scale/backend/rack.rb +49 -0
  97. data/lib/3scale/backend/rack/exception_catcher.rb +136 -0
  98. data/lib/3scale/backend/rack/internal_error_catcher.rb +23 -0
  99. data/lib/3scale/backend/rack/prometheus.rb +19 -0
  100. data/lib/3scale/backend/saas.rb +6 -0
  101. data/lib/3scale/backend/saas_analytics.rb +4 -0
  102. data/lib/3scale/backend/server.rb +30 -0
  103. data/lib/3scale/backend/server/falcon.rb +52 -0
  104. data/lib/3scale/backend/server/puma.rb +71 -0
  105. data/lib/3scale/backend/service.rb +317 -0
  106. data/lib/3scale/backend/service_token.rb +97 -0
  107. data/lib/3scale/backend/stats.rb +8 -0
  108. data/lib/3scale/backend/stats/aggregator.rb +170 -0
  109. data/lib/3scale/backend/stats/aggregators/base.rb +72 -0
  110. data/lib/3scale/backend/stats/aggregators/response_code.rb +58 -0
  111. data/lib/3scale/backend/stats/aggregators/usage.rb +34 -0
  112. data/lib/3scale/backend/stats/bucket_reader.rb +135 -0
  113. data/lib/3scale/backend/stats/bucket_storage.rb +108 -0
  114. data/lib/3scale/backend/stats/cleaner.rb +195 -0
  115. data/lib/3scale/backend/stats/codes_commons.rb +14 -0
  116. data/lib/3scale/backend/stats/delete_job_def.rb +60 -0
  117. data/lib/3scale/backend/stats/key_generator.rb +73 -0
  118. data/lib/3scale/backend/stats/keys.rb +104 -0
  119. data/lib/3scale/backend/stats/partition_eraser_job.rb +58 -0
  120. data/lib/3scale/backend/stats/partition_generator_job.rb +46 -0
  121. data/lib/3scale/backend/stats/period_commons.rb +34 -0
  122. data/lib/3scale/backend/stats/stats_parser.rb +141 -0
  123. data/lib/3scale/backend/stats/storage.rb +113 -0
  124. data/lib/3scale/backend/statsd.rb +14 -0
  125. data/lib/3scale/backend/storable.rb +35 -0
  126. data/lib/3scale/backend/storage.rb +40 -0
  127. data/lib/3scale/backend/storage_async.rb +4 -0
  128. data/lib/3scale/backend/storage_async/async_redis.rb +21 -0
  129. data/lib/3scale/backend/storage_async/client.rb +205 -0
  130. data/lib/3scale/backend/storage_async/pipeline.rb +79 -0
  131. data/lib/3scale/backend/storage_async/resque_extensions.rb +30 -0
  132. data/lib/3scale/backend/storage_helpers.rb +278 -0
  133. data/lib/3scale/backend/storage_key_helpers.rb +9 -0
  134. data/lib/3scale/backend/storage_sync.rb +43 -0
  135. data/lib/3scale/backend/transaction.rb +62 -0
  136. data/lib/3scale/backend/transactor.rb +177 -0
  137. data/lib/3scale/backend/transactor/limit_headers.rb +54 -0
  138. data/lib/3scale/backend/transactor/notify_batcher.rb +139 -0
  139. data/lib/3scale/backend/transactor/notify_job.rb +47 -0
  140. data/lib/3scale/backend/transactor/process_job.rb +33 -0
  141. data/lib/3scale/backend/transactor/report_job.rb +84 -0
  142. data/lib/3scale/backend/transactor/status.rb +236 -0
  143. data/lib/3scale/backend/transactor/usage_report.rb +182 -0
  144. data/lib/3scale/backend/usage.rb +63 -0
  145. data/lib/3scale/backend/usage_limit.rb +115 -0
  146. data/lib/3scale/backend/use_cases/provider_key_change_use_case.rb +60 -0
  147. data/lib/3scale/backend/util.rb +17 -0
  148. data/lib/3scale/backend/validators.rb +26 -0
  149. data/lib/3scale/backend/validators/base.rb +36 -0
  150. data/lib/3scale/backend/validators/key.rb +17 -0
  151. data/lib/3scale/backend/validators/limits.rb +57 -0
  152. data/lib/3scale/backend/validators/oauth_key.rb +15 -0
  153. data/lib/3scale/backend/validators/oauth_setting.rb +15 -0
  154. data/lib/3scale/backend/validators/redirect_uri.rb +33 -0
  155. data/lib/3scale/backend/validators/referrer.rb +60 -0
  156. data/lib/3scale/backend/validators/service_state.rb +15 -0
  157. data/lib/3scale/backend/validators/state.rb +15 -0
  158. data/lib/3scale/backend/version.rb +5 -0
  159. data/lib/3scale/backend/views/oauth_access_tokens.builder +14 -0
  160. data/lib/3scale/backend/views/oauth_app_id_by_token.builder +4 -0
  161. data/lib/3scale/backend/worker.rb +87 -0
  162. data/lib/3scale/backend/worker_async.rb +88 -0
  163. data/lib/3scale/backend/worker_metrics.rb +44 -0
  164. data/lib/3scale/backend/worker_sync.rb +32 -0
  165. data/lib/3scale/bundler_shim.rb +17 -0
  166. data/lib/3scale/prometheus_server.rb +10 -0
  167. data/lib/3scale/tasks/connectivity.rake +41 -0
  168. data/lib/3scale/tasks/helpers.rb +3 -0
  169. data/lib/3scale/tasks/helpers/environment.rb +23 -0
  170. data/lib/3scale/tasks/stats.rake +131 -0
  171. data/lib/3scale/tasks/swagger.rake +46 -0
  172. data/licenses.xml +1215 -0
  173. metadata +227 -0
@@ -0,0 +1,18 @@
1
+ # Add an application-wide logger UNRELATED to the request's logs.
2
+ #
3
+ # This allows for additional instrumentation and information gathering
4
+ # in production environment.
5
+ #
6
+ require 'logger'
7
+
8
+ module ThreeScale
9
+ module Backend
10
+ module Logging
11
+ class Logger
12
+ def self.new(*args)
13
+ ::Logger.new(*args)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,62 @@
1
+ require '3scale/backend/logging/middleware/writer'
2
+ require '3scale/backend/logging/middleware/text_writer'
3
+ require '3scale/backend/logging/middleware/json_writer'
4
+
5
+ module ThreeScale
6
+ module Backend
7
+ module Logging
8
+ class Middleware
9
+ WRITERS = { text: TextWriter, json: JsonWriter }.freeze
10
+ private_constant :WRITERS
11
+
12
+ DEFAULT_WRITERS = [WRITERS[:text].new].freeze
13
+ private_constant :DEFAULT_WRITERS
14
+
15
+ class UnsupportedLoggerType < StandardError
16
+ def initialize(logger)
17
+ super "#{logger} is not a supported logger type."
18
+ end
19
+ end
20
+
21
+ # writers is an array of symbols. WRITERS contains the accepted values
22
+ def initialize(app, writers: DEFAULT_WRITERS)
23
+ @app = app
24
+ @writers = writers
25
+ end
26
+
27
+ def call(env)
28
+ began_at = Time.now
29
+ begin
30
+ status, header, body = @app.call(env)
31
+ rescue Exception => e
32
+ @writers.each do |writer|
33
+ writer.log_error(env, 500, e.message, began_at)
34
+ end
35
+ raise e
36
+ end
37
+
38
+ header = ::Rack::Utils::HeaderHash.new(header)
39
+ body = ::Rack::BodyProxy.new(body) do
40
+ @writers.each do |writer|
41
+ writer.log(env, status, header, began_at)
42
+ end
43
+ end
44
+
45
+ [status, header, body]
46
+ end
47
+
48
+ # Returns the Writer instances that correspond to the loggers given.
49
+ # If no loggers are given, returns the default writers.
50
+ def self.writers(loggers)
51
+ writers = Array(loggers).map do |logger|
52
+ writer_class = WRITERS[logger]
53
+ raise UnsupportedLoggerType.new(logger) unless writer_class
54
+ writer_class.new
55
+ end
56
+
57
+ writers.empty? ? DEFAULT_WRITERS : writers
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,21 @@
1
+ require '3scale/backend/logging/middleware/writer'
2
+
3
+ module ThreeScale
4
+ module Backend
5
+ module Logging
6
+ class Middleware
7
+ class JsonWriter
8
+ include Middleware::Writer
9
+
10
+ private
11
+
12
+ def formatted_log(data)
13
+ data.to_json + "\n".freeze
14
+ end
15
+
16
+ alias_method :formatted_error, :formatted_log
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,60 @@
1
+ require '3scale/backend/logging/middleware/writer'
2
+
3
+ module ThreeScale
4
+ module Backend
5
+ module Logging
6
+ class Middleware
7
+ class TextWriter
8
+ include Middleware::Writer
9
+
10
+ FORMAT = "%s - %s [%s] \"%s %s%s %s\" %d %s %s 0 0 0 %s %s %s %s %s\n".freeze
11
+ private_constant :FORMAT
12
+
13
+ ERROR_FORMAT = "%s - %s [%s] \"%s %s%s %s\" %d \"%s\" %s %s %s\n".freeze
14
+ private_constant :ERROR_FORMAT
15
+
16
+ SORTED_LOG_FIELDS = [:forwarded_for,
17
+ :remote_user,
18
+ :time,
19
+ :method,
20
+ :path_info,
21
+ :query_string,
22
+ :http_version,
23
+ :status,
24
+ :length,
25
+ :response_time,
26
+ :memoizer_size,
27
+ :memoizer_count,
28
+ :memoizer_hits,
29
+ :request_id,
30
+ :extensions].freeze
31
+ private_constant :SORTED_LOG_FIELDS
32
+
33
+ SORTED_ERROR_LOG_FIELDS = [:forwarded_for,
34
+ :remote_user,
35
+ :time,
36
+ :method,
37
+ :path_info,
38
+ :query_string,
39
+ :http_version,
40
+ :status,
41
+ :error,
42
+ :response_time,
43
+ :request_id,
44
+ :extensions].freeze
45
+ private_constant :SORTED_ERROR_LOG_FIELDS
46
+
47
+ private
48
+
49
+ def formatted_log(data)
50
+ FORMAT % SORTED_LOG_FIELDS.map { |field| data[field] }
51
+ end
52
+
53
+ def formatted_error(data)
54
+ ERROR_FORMAT % SORTED_ERROR_LOG_FIELDS.map { |field| data[field] }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,143 @@
1
+ module ThreeScale
2
+ module Backend
3
+ module Logging
4
+ class Middleware
5
+ module Writer
6
+ Z3_RANGE = 0..3.freeze
7
+ private_constant :Z3_RANGE
8
+
9
+ private_constant(*[
10
+ :HTTP_X_FORWARDED_FOR,
11
+ :REMOTE_ADDR,
12
+ :REMOTE_USER,
13
+ :REQUEST_METHOD,
14
+ :PATH_INFO,
15
+ :HTTP_VERSION,
16
+ :HTTP_X_REQUEST_ID,
17
+ :QUERY_STRING,
18
+ :HTTP_3SCALE_OPTIONS
19
+ ].each do |k|
20
+ const_set(k, k.to_s.freeze)
21
+ end)
22
+
23
+ private_constant(*{
24
+ DATE_FORMAT: '%d/%b/%Y %H:%M:%S %Z',
25
+ STR_PROVIDER_KEY: 'provider_key',
26
+ STR_POST: 'POST',
27
+ STR_EQUAL: '=',
28
+ STR_DASH: '-',
29
+ STR_AMPERSAND: '&',
30
+ STR_ZERO: '0',
31
+ STR_RACK_ERRORS: 'rack.errors',
32
+ STR_EMPTY: '',
33
+ STR_QUESTION_MARK: '?',
34
+ STR_NEWLINE: "\n",
35
+ STR_DQUOTE: '"',
36
+ STR_ESCAPED_DQUOTE: '\"',
37
+ STR_CONTENT_LENGTH: 'Content-Length'
38
+ }.map do |k, v|
39
+ const_set(k, v.freeze)
40
+ k
41
+ end)
42
+
43
+ def initialize(logger=STDOUT)
44
+ @logger = logger
45
+ end
46
+
47
+ def log(env, status, header, began_at)
48
+ data = log_data(env, status, header, began_at)
49
+ log = formatted_log(data)
50
+ logger(env).write(log)
51
+ end
52
+
53
+ def log_error(env, status, error, began_at)
54
+ data = log_error_data(env, status, error, began_at)
55
+ error = formatted_error(data)
56
+ logger(env).write(error)
57
+ end
58
+
59
+ private
60
+
61
+ def logger(env)
62
+ @logger || env[STR_RACK_ERRORS] || STDERR
63
+ end
64
+
65
+ def log_data(env, status, header, began_at)
66
+ common_request_data(env, status, began_at)
67
+ .merge(success_specific_data(header))
68
+ end
69
+
70
+ def log_error_data(env, status, error, began_at)
71
+ common_request_data(env, status, began_at)
72
+ .merge(error_specific_data(error))
73
+ end
74
+
75
+ def common_request_data(env, status, began_at)
76
+ now = Time.now.getutc
77
+
78
+ { forwarded_for: env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || STR_DASH,
79
+ remote_user: env[REMOTE_USER] || STR_DASH,
80
+ time: now.strftime(DATE_FORMAT),
81
+ method: env[REQUEST_METHOD],
82
+ path_info: env[PATH_INFO],
83
+ query_string: extract_query_string(env),
84
+ http_version: env[HTTP_VERSION],
85
+ status: status.to_s[Z3_RANGE],
86
+ response_time: now - began_at,
87
+ request_id: env[HTTP_X_REQUEST_ID] || STR_DASH,
88
+ extensions: extensions(env) }
89
+ end
90
+
91
+ def success_specific_data(header)
92
+ { length: extract_content_length(header) }.merge(memoizer_data)
93
+ end
94
+
95
+ def memoizer_data
96
+ memoizer = memoizer_stats
97
+
98
+ { memoizer_size: memoizer[:size] || STR_DASH,
99
+ memoizer_count: memoizer[:count] || STR_DASH,
100
+ memoizer_hits: memoizer[:hits] || STR_DASH }
101
+ end
102
+
103
+ def error_specific_data(error)
104
+ { error: error }
105
+ end
106
+
107
+ def extract_query_string(env)
108
+ qs = env[QUERY_STRING]
109
+ if env[REQUEST_METHOD].to_s.upcase == STR_POST
110
+ provider_key = begin
111
+ ::Rack::Request.new(env).params[STR_PROVIDER_KEY]
112
+ rescue IOError
113
+ # happens when body does not parse
114
+ nil
115
+ end
116
+ unless provider_key.nil?
117
+ qs = qs.dup
118
+ qs << STR_AMPERSAND unless qs.empty?
119
+ qs << STR_PROVIDER_KEY + STR_EQUAL + provider_key.to_s
120
+ end
121
+ end
122
+
123
+ qs.empty? ? STR_EMPTY : STR_QUESTION_MARK + qs.tr(STR_NEWLINE, STR_EMPTY)
124
+ end
125
+
126
+ def extract_content_length(headers)
127
+ value = headers[STR_CONTENT_LENGTH] or return STR_DASH
128
+ value.to_s == STR_ZERO ? STR_DASH : value
129
+ end
130
+
131
+ def extensions(env)
132
+ ext = env[HTTP_3SCALE_OPTIONS]
133
+ ext ? "\"#{ext.gsub(STR_DQUOTE, STR_ESCAPED_DQUOTE)}\"" : STR_DASH
134
+ end
135
+
136
+ def memoizer_stats
137
+ ThreeScale::Backend::Memoizer.stats
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,107 @@
1
+ module ThreeScale
2
+ module Backend
3
+ module Logging
4
+ class Worker
5
+ include Configurable
6
+
7
+ module PlainText
8
+ private
9
+
10
+ def logger_formatter
11
+ proc do |severity, datetime, _progname, msg|
12
+ "#{severity} #{Process.pid} #{formatted_datetime(datetime)} #{msg}\n"
13
+ end
14
+ end
15
+
16
+ def formatted_datetime(datetime)
17
+ datetime.getutc.strftime("[%d/%b/%Y %H:%M:%S %Z]".freeze)
18
+ end
19
+ end
20
+ private_constant :PlainText
21
+
22
+ module Json
23
+ STRING_COMMON_FIELDS = [:job_class].freeze
24
+ private_constant :STRING_COMMON_FIELDS
25
+
26
+ FLOAT_COMMON_FIELDS = [:runtime, :run_plus_queued_time].freeze
27
+ private_constant :FLOAT_COMMON_FIELDS
28
+
29
+ INT_COMMON_FIELDS = [:memoizer_size, :memoizer_count, :memoizer_hits].freeze
30
+ private_constant :INT_COMMON_FIELDS
31
+
32
+ COMMON_LOG_FIELDS = (STRING_COMMON_FIELDS +
33
+ FLOAT_COMMON_FIELDS +
34
+ INT_COMMON_FIELDS).freeze
35
+ private_constant :COMMON_LOG_FIELDS
36
+
37
+ private
38
+
39
+ def logger_formatter
40
+ proc do |severity, datetime, _progname, msg|
41
+ common_fields = { severity: severity,
42
+ pid: Process.pid,
43
+ time: datetime.getutc.to_s }
44
+
45
+ # When there is an error, the msg does not contain run times and
46
+ # memoizer stats.
47
+ msg_fields = if severity == 'INFO'.freeze
48
+ formatted_msg(msg)
49
+ else
50
+ { msg: msg }
51
+ end
52
+
53
+ common_fields.merge(msg_fields).to_json + "\n".freeze
54
+ end
55
+ end
56
+
57
+ def formatted_msg(msg)
58
+ # The format of the message depends on the kind of background job
59
+ # that sends it:
60
+ # job_class -variable_part- run_time run_time+queued_time
61
+ # memoizer_size memoizer_count memoizer_hits.
62
+ # -variable_part- depends on the kind of job. It might contain app
63
+ # ids, a message (with spaces), etc. The rest of the message is
64
+ # common for all the jobs. For now, we discard the variable part.
65
+ fields = msg.split(' '.freeze)
66
+ common_field_values = [fields.first] + fields.last(5)
67
+ res = Hash[COMMON_LOG_FIELDS.zip(common_field_values)]
68
+
69
+ FLOAT_COMMON_FIELDS.each do |field|
70
+ res[field] = res[field].to_f
71
+ end
72
+
73
+ INT_COMMON_FIELDS.each do |field|
74
+ res[field] = res[field].to_i
75
+ end
76
+
77
+ res
78
+ end
79
+ end
80
+ private_constant :Json
81
+
82
+ extend(configuration.workers_logger_formatter == :json ? Json : PlainText)
83
+
84
+ class << self
85
+ def configure_logging(worker_class, workers_log_file)
86
+ log_file = workers_log_file || configuration.workers_log_file || '/dev/null'
87
+
88
+ Logging.enable! on: worker_class.singleton_class, with: log_file do |logger|
89
+ logger.formatter = logger_formatter
90
+
91
+ # At this point, we've already configured the logger for Backend
92
+ # (used in Listeners and rake tasks). We can reuse the notify proc
93
+ # defined there.
94
+ logger.define_singleton_method(:notify, backend_logger_notify_proc)
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def backend_logger_notify_proc
101
+ Backend.logger.method(:notify).to_proc
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,80 @@
1
+ require '3scale/backend/version'
2
+ require '3scale/backend/util'
3
+ require '3scale/backend/server'
4
+
5
+ module ThreeScale
6
+ module Backend
7
+ module Manifest
8
+ class << self
9
+ LISTENER_WORKERS = 'LISTENER_WORKERS'.freeze
10
+ private_constant :LISTENER_WORKERS
11
+ PUMA_WORKERS = 'PUMA_WORKERS'.freeze
12
+ private_constant :PUMA_WORKERS
13
+ PUMA_WORKERS_CPUMULT = 8
14
+ private_constant :PUMA_WORKERS_CPUMULT
15
+
16
+ # Thread safety of our application. Turn this on if we ever are MT safe.
17
+ def thread_safe?
18
+ false
19
+ end
20
+
21
+ # Compute workers based on LISTENER_WORKERS and PUMA_WORKERS env
22
+ # variables. The former takes precedence.
23
+ # If those envs do not exist or are empty, use number of cpus
24
+ def compute_workers(ncpus)
25
+ return 0 unless Process.respond_to?(:fork)
26
+
27
+ compute_workers_from_env(LISTENER_WORKERS) ||
28
+ compute_workers_from_env(PUMA_WORKERS) ||
29
+ ncpus * PUMA_WORKERS_CPUMULT
30
+ end
31
+
32
+ def server_model
33
+ # Serving model settings here
34
+ #
35
+ # compute default workers and threads values
36
+ # We want to adapt workers and threads to our characteristics.
37
+ # Note that these values will likely need to be tweaked depending on
38
+ # the Ruby implementation and how our app behaves!
39
+ ncpus = ThreeScale::Backend::Util.number_of_cpus
40
+ workers = compute_workers ncpus
41
+ # if no workers but mt-safe, we spawn more threads.
42
+ min_threads, max_threads = if thread_safe?
43
+ shift = workers.zero? ? 2 : 0
44
+ [ncpus << shift, ncpus << 1 + shift]
45
+ else
46
+ [1, 1]
47
+ end
48
+ {
49
+ ncpus: ncpus,
50
+ workers: workers,
51
+ min_threads: min_threads,
52
+ max_threads: max_threads
53
+ }
54
+ end
55
+
56
+ def report
57
+ {
58
+ version: ThreeScale::Backend::VERSION,
59
+ root_dir: ThreeScale::Backend::Util.root_dir,
60
+ servers: ThreeScale::Backend::Server.list,
61
+ thread_safe: thread_safe?,
62
+ server_model: server_model,
63
+ }
64
+ end
65
+
66
+ private
67
+
68
+ def compute_workers_from_env(env_name)
69
+ if ENV[env_name] && !ENV[env_name].empty?
70
+ begin
71
+ Integer(ENV[env_name])
72
+ rescue => e
73
+ raise e, "#{env_name} environment var cannot be parsed: #{e.message}"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end