apisonator 2.100.0

Sign up to get free protection for your applications and to get access to all the features.
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