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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +317 -0
- data/Gemfile +11 -0
- data/Gemfile.base +65 -0
- data/Gemfile.lock +319 -0
- data/Gemfile.on_prem +1 -0
- data/Gemfile.on_prem.lock +297 -0
- data/LICENSE +202 -0
- data/NOTICE +15 -0
- data/README.md +230 -0
- data/Rakefile +287 -0
- data/apisonator.gemspec +47 -0
- data/app/api/api.rb +13 -0
- data/app/api/internal/alert_limits.rb +32 -0
- data/app/api/internal/application_keys.rb +49 -0
- data/app/api/internal/application_referrer_filters.rb +43 -0
- data/app/api/internal/applications.rb +77 -0
- data/app/api/internal/errors.rb +54 -0
- data/app/api/internal/events.rb +42 -0
- data/app/api/internal/internal.rb +104 -0
- data/app/api/internal/metrics.rb +40 -0
- data/app/api/internal/service_tokens.rb +46 -0
- data/app/api/internal/services.rb +58 -0
- data/app/api/internal/stats.rb +42 -0
- data/app/api/internal/usagelimits.rb +62 -0
- data/app/api/internal/utilization.rb +23 -0
- data/bin/3scale_backend +223 -0
- data/bin/3scale_backend_worker +26 -0
- data/config.ru +4 -0
- data/config/puma.rb +192 -0
- data/config/schedule.rb +9 -0
- data/ext/mkrf_conf.rb +64 -0
- data/lib/3scale/backend.rb +67 -0
- data/lib/3scale/backend/alert_limit.rb +56 -0
- data/lib/3scale/backend/alerts.rb +137 -0
- data/lib/3scale/backend/analytics/kinesis.rb +3 -0
- data/lib/3scale/backend/analytics/kinesis/adapter.rb +180 -0
- data/lib/3scale/backend/analytics/kinesis/exporter.rb +86 -0
- data/lib/3scale/backend/analytics/kinesis/job.rb +135 -0
- data/lib/3scale/backend/analytics/redshift.rb +3 -0
- data/lib/3scale/backend/analytics/redshift/adapter.rb +367 -0
- data/lib/3scale/backend/analytics/redshift/importer.rb +83 -0
- data/lib/3scale/backend/analytics/redshift/job.rb +33 -0
- data/lib/3scale/backend/application.rb +330 -0
- data/lib/3scale/backend/application_events.rb +76 -0
- data/lib/3scale/backend/background_job.rb +65 -0
- data/lib/3scale/backend/configurable.rb +20 -0
- data/lib/3scale/backend/configuration.rb +151 -0
- data/lib/3scale/backend/configuration/loader.rb +42 -0
- data/lib/3scale/backend/constants.rb +19 -0
- data/lib/3scale/backend/cors.rb +84 -0
- data/lib/3scale/backend/distributed_lock.rb +67 -0
- data/lib/3scale/backend/environment.rb +21 -0
- data/lib/3scale/backend/error_storage.rb +52 -0
- data/lib/3scale/backend/errors.rb +343 -0
- data/lib/3scale/backend/event_storage.rb +120 -0
- data/lib/3scale/backend/experiment.rb +84 -0
- data/lib/3scale/backend/extensions.rb +5 -0
- data/lib/3scale/backend/extensions/array.rb +19 -0
- data/lib/3scale/backend/extensions/hash.rb +26 -0
- data/lib/3scale/backend/extensions/nil_class.rb +13 -0
- data/lib/3scale/backend/extensions/redis.rb +44 -0
- data/lib/3scale/backend/extensions/string.rb +13 -0
- data/lib/3scale/backend/extensions/time.rb +110 -0
- data/lib/3scale/backend/failed_jobs_scheduler.rb +141 -0
- data/lib/3scale/backend/job_fetcher.rb +122 -0
- data/lib/3scale/backend/listener.rb +728 -0
- data/lib/3scale/backend/listener_metrics.rb +99 -0
- data/lib/3scale/backend/logging.rb +48 -0
- data/lib/3scale/backend/logging/external.rb +44 -0
- data/lib/3scale/backend/logging/external/impl.rb +93 -0
- data/lib/3scale/backend/logging/external/impl/airbrake.rb +66 -0
- data/lib/3scale/backend/logging/external/impl/bugsnag.rb +69 -0
- data/lib/3scale/backend/logging/external/impl/default.rb +18 -0
- data/lib/3scale/backend/logging/external/resque.rb +57 -0
- data/lib/3scale/backend/logging/logger.rb +18 -0
- data/lib/3scale/backend/logging/middleware.rb +62 -0
- data/lib/3scale/backend/logging/middleware/json_writer.rb +21 -0
- data/lib/3scale/backend/logging/middleware/text_writer.rb +60 -0
- data/lib/3scale/backend/logging/middleware/writer.rb +143 -0
- data/lib/3scale/backend/logging/worker.rb +107 -0
- data/lib/3scale/backend/manifest.rb +80 -0
- data/lib/3scale/backend/memoizer.rb +277 -0
- data/lib/3scale/backend/metric.rb +275 -0
- data/lib/3scale/backend/metric/collection.rb +91 -0
- data/lib/3scale/backend/oauth.rb +4 -0
- data/lib/3scale/backend/oauth/token.rb +26 -0
- data/lib/3scale/backend/oauth/token_key.rb +30 -0
- data/lib/3scale/backend/oauth/token_storage.rb +313 -0
- data/lib/3scale/backend/oauth/token_value.rb +25 -0
- data/lib/3scale/backend/period.rb +3 -0
- data/lib/3scale/backend/period/boundary.rb +107 -0
- data/lib/3scale/backend/period/cache.rb +28 -0
- data/lib/3scale/backend/period/period.rb +402 -0
- data/lib/3scale/backend/queue_storage.rb +16 -0
- data/lib/3scale/backend/rack.rb +49 -0
- data/lib/3scale/backend/rack/exception_catcher.rb +136 -0
- data/lib/3scale/backend/rack/internal_error_catcher.rb +23 -0
- data/lib/3scale/backend/rack/prometheus.rb +19 -0
- data/lib/3scale/backend/saas.rb +6 -0
- data/lib/3scale/backend/saas_analytics.rb +4 -0
- data/lib/3scale/backend/server.rb +30 -0
- data/lib/3scale/backend/server/falcon.rb +52 -0
- data/lib/3scale/backend/server/puma.rb +71 -0
- data/lib/3scale/backend/service.rb +317 -0
- data/lib/3scale/backend/service_token.rb +97 -0
- data/lib/3scale/backend/stats.rb +8 -0
- data/lib/3scale/backend/stats/aggregator.rb +170 -0
- data/lib/3scale/backend/stats/aggregators/base.rb +72 -0
- data/lib/3scale/backend/stats/aggregators/response_code.rb +58 -0
- data/lib/3scale/backend/stats/aggregators/usage.rb +34 -0
- data/lib/3scale/backend/stats/bucket_reader.rb +135 -0
- data/lib/3scale/backend/stats/bucket_storage.rb +108 -0
- data/lib/3scale/backend/stats/cleaner.rb +195 -0
- data/lib/3scale/backend/stats/codes_commons.rb +14 -0
- data/lib/3scale/backend/stats/delete_job_def.rb +60 -0
- data/lib/3scale/backend/stats/key_generator.rb +73 -0
- data/lib/3scale/backend/stats/keys.rb +104 -0
- data/lib/3scale/backend/stats/partition_eraser_job.rb +58 -0
- data/lib/3scale/backend/stats/partition_generator_job.rb +46 -0
- data/lib/3scale/backend/stats/period_commons.rb +34 -0
- data/lib/3scale/backend/stats/stats_parser.rb +141 -0
- data/lib/3scale/backend/stats/storage.rb +113 -0
- data/lib/3scale/backend/statsd.rb +14 -0
- data/lib/3scale/backend/storable.rb +35 -0
- data/lib/3scale/backend/storage.rb +40 -0
- data/lib/3scale/backend/storage_async.rb +4 -0
- data/lib/3scale/backend/storage_async/async_redis.rb +21 -0
- data/lib/3scale/backend/storage_async/client.rb +205 -0
- data/lib/3scale/backend/storage_async/pipeline.rb +79 -0
- data/lib/3scale/backend/storage_async/resque_extensions.rb +30 -0
- data/lib/3scale/backend/storage_helpers.rb +278 -0
- data/lib/3scale/backend/storage_key_helpers.rb +9 -0
- data/lib/3scale/backend/storage_sync.rb +43 -0
- data/lib/3scale/backend/transaction.rb +62 -0
- data/lib/3scale/backend/transactor.rb +177 -0
- data/lib/3scale/backend/transactor/limit_headers.rb +54 -0
- data/lib/3scale/backend/transactor/notify_batcher.rb +139 -0
- data/lib/3scale/backend/transactor/notify_job.rb +47 -0
- data/lib/3scale/backend/transactor/process_job.rb +33 -0
- data/lib/3scale/backend/transactor/report_job.rb +84 -0
- data/lib/3scale/backend/transactor/status.rb +236 -0
- data/lib/3scale/backend/transactor/usage_report.rb +182 -0
- data/lib/3scale/backend/usage.rb +63 -0
- data/lib/3scale/backend/usage_limit.rb +115 -0
- data/lib/3scale/backend/use_cases/provider_key_change_use_case.rb +60 -0
- data/lib/3scale/backend/util.rb +17 -0
- data/lib/3scale/backend/validators.rb +26 -0
- data/lib/3scale/backend/validators/base.rb +36 -0
- data/lib/3scale/backend/validators/key.rb +17 -0
- data/lib/3scale/backend/validators/limits.rb +57 -0
- data/lib/3scale/backend/validators/oauth_key.rb +15 -0
- data/lib/3scale/backend/validators/oauth_setting.rb +15 -0
- data/lib/3scale/backend/validators/redirect_uri.rb +33 -0
- data/lib/3scale/backend/validators/referrer.rb +60 -0
- data/lib/3scale/backend/validators/service_state.rb +15 -0
- data/lib/3scale/backend/validators/state.rb +15 -0
- data/lib/3scale/backend/version.rb +5 -0
- data/lib/3scale/backend/views/oauth_access_tokens.builder +14 -0
- data/lib/3scale/backend/views/oauth_app_id_by_token.builder +4 -0
- data/lib/3scale/backend/worker.rb +87 -0
- data/lib/3scale/backend/worker_async.rb +88 -0
- data/lib/3scale/backend/worker_metrics.rb +44 -0
- data/lib/3scale/backend/worker_sync.rb +32 -0
- data/lib/3scale/bundler_shim.rb +17 -0
- data/lib/3scale/prometheus_server.rb +10 -0
- data/lib/3scale/tasks/connectivity.rake +41 -0
- data/lib/3scale/tasks/helpers.rb +3 -0
- data/lib/3scale/tasks/helpers/environment.rb +23 -0
- data/lib/3scale/tasks/stats.rake +131 -0
- data/lib/3scale/tasks/swagger.rake +46 -0
- data/licenses.xml +1215 -0
- metadata +227 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'yabeda/prometheus'
|
|
2
|
+
require 'rack'
|
|
3
|
+
|
|
4
|
+
module ThreeScale
|
|
5
|
+
module Backend
|
|
6
|
+
class ListenerMetrics
|
|
7
|
+
REQUEST_TYPES = {
|
|
8
|
+
'/transactions/authorize.xml' => 'authorize',
|
|
9
|
+
'/transactions/oauth_authorize.xml' => 'authorize_oauth',
|
|
10
|
+
'/transactions/authrep.xml' => 'authrep',
|
|
11
|
+
'/transactions/oauth_authrep.xml' => 'authrep_oauth',
|
|
12
|
+
'/transactions.xml' => 'report'
|
|
13
|
+
}
|
|
14
|
+
private_constant :REQUEST_TYPES
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
ERRORS_4XX_TO_TRACK = Set[403, 404, 409].freeze
|
|
18
|
+
private_constant :ERRORS_4XX_TO_TRACK
|
|
19
|
+
|
|
20
|
+
def start_metrics_server(port = nil)
|
|
21
|
+
configure_data_store
|
|
22
|
+
define_metrics
|
|
23
|
+
|
|
24
|
+
# Yabeda does not accept the port as a param
|
|
25
|
+
ENV['PROMETHEUS_EXPORTER_PORT'] = port.to_s if port
|
|
26
|
+
Yabeda::Prometheus::Exporter.start_metrics_server!
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def report_resp_code(path, resp_code)
|
|
30
|
+
Yabeda.apisonator_listener.response_codes.increment(
|
|
31
|
+
{
|
|
32
|
+
request_type: REQUEST_TYPES[path],
|
|
33
|
+
resp_code: code_group(resp_code)
|
|
34
|
+
},
|
|
35
|
+
by: 1
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def report_response_time(path, request_time)
|
|
40
|
+
Yabeda.apisonator_listener.response_times.measure(
|
|
41
|
+
{ request_type: REQUEST_TYPES[path] },
|
|
42
|
+
request_time
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def configure_data_store
|
|
49
|
+
# Needed to aggregate metrics across processes.
|
|
50
|
+
# Ref: https://github.com/yabeda-rb/yabeda-prometheus#multi-process-server-support
|
|
51
|
+
Dir['/tmp/prometheus/*.bin'].each do |file_path|
|
|
52
|
+
File.unlink(file_path)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Prometheus::Client.config.data_store = Prometheus::Client::DataStores::DirectFileStore.new(
|
|
56
|
+
dir: '/tmp/prometheus'
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def define_metrics
|
|
61
|
+
Yabeda.configure do
|
|
62
|
+
group :apisonator_listener do
|
|
63
|
+
counter :response_codes do
|
|
64
|
+
comment 'Response codes'
|
|
65
|
+
tags %i[request_type resp_code]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
histogram :response_times do
|
|
69
|
+
comment 'Response times'
|
|
70
|
+
unit :seconds
|
|
71
|
+
tags %i[request_type]
|
|
72
|
+
# Most requests will be under 100ms, so use a higher granularity from there
|
|
73
|
+
buckets [0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.25, 0.5, 0.75, 1]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Note that this method raises if called more than once. Both
|
|
79
|
+
# listeners and workers define their metrics, but that's fine because
|
|
80
|
+
# a process cannot act as both.
|
|
81
|
+
Yabeda.configure!
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def code_group(resp_code)
|
|
85
|
+
case resp_code
|
|
86
|
+
when (200...300)
|
|
87
|
+
'2xx'.freeze
|
|
88
|
+
when (400...500)
|
|
89
|
+
ERRORS_4XX_TO_TRACK.include?(resp_code) ? resp_code : '4xx'.freeze
|
|
90
|
+
when (500...600)
|
|
91
|
+
'5xx'.freeze
|
|
92
|
+
else
|
|
93
|
+
'unknown'.freeze
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require '3scale/backend/environment'
|
|
2
|
+
require '3scale/backend/configuration'
|
|
3
|
+
require '3scale/backend/logging/logger'
|
|
4
|
+
require '3scale/backend/logging/external'
|
|
5
|
+
|
|
6
|
+
module ThreeScale
|
|
7
|
+
module Backend
|
|
8
|
+
# include this module to have a handy access to the default logger
|
|
9
|
+
module Logging
|
|
10
|
+
def self.included(base)
|
|
11
|
+
enable! on: base
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.enable!(on:, with: [], as: :logger)
|
|
15
|
+
logger = if with.empty?
|
|
16
|
+
Backend.logger
|
|
17
|
+
else
|
|
18
|
+
Backend::Logging::Logger.new(*with)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# define the method before yielding
|
|
22
|
+
on.send :define_method, as do
|
|
23
|
+
logger
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
yield logger if block_given?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def enable_logging
|
|
35
|
+
Logging.enable! on: self.singleton_class,
|
|
36
|
+
with: [configuration.log_file, 10] do |logger|
|
|
37
|
+
logger.define_singleton_method(:notify, logger_notify_proc(logger))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def logger_notify_proc(logger)
|
|
42
|
+
Logging::External.notify_proc || logger.method(:error).to_proc
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
enable_logging
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require '3scale/backend/configuration'
|
|
2
|
+
require '3scale/backend/logging/external/impl'
|
|
3
|
+
|
|
4
|
+
module ThreeScale
|
|
5
|
+
module Backend
|
|
6
|
+
module Logging
|
|
7
|
+
module External
|
|
8
|
+
class << self
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
attr_accessor :impl, :enabled
|
|
12
|
+
alias_method :enabled?, :enabled
|
|
13
|
+
public :enabled?
|
|
14
|
+
|
|
15
|
+
public
|
|
16
|
+
|
|
17
|
+
def setup
|
|
18
|
+
config = Backend.configuration.hoptoad
|
|
19
|
+
|
|
20
|
+
service = if config.service && !config.service.empty?
|
|
21
|
+
config.service.to_sym
|
|
22
|
+
else
|
|
23
|
+
:default
|
|
24
|
+
end
|
|
25
|
+
self.impl = Impl.load service
|
|
26
|
+
self.enabled = impl.setup(config.api_key)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def reset
|
|
30
|
+
self.enabled = false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# delegate methods not overriden to the impl
|
|
34
|
+
(Impl::METHODS - public_instance_methods(false)).each do |m|
|
|
35
|
+
define_method(m) do |*args|
|
|
36
|
+
setup unless enabled?
|
|
37
|
+
impl.public_send m, *args
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
module ThreeScale
|
|
2
|
+
module Backend
|
|
3
|
+
module Logging
|
|
4
|
+
module External
|
|
5
|
+
# This is the module that each implementation has to populate with its
|
|
6
|
+
# own class. The implementation file must be named after the class and
|
|
7
|
+
# live in a specific subdirectory relative to this file matching this
|
|
8
|
+
# file's name.
|
|
9
|
+
#
|
|
10
|
+
# To load the class one must specify a symbol with the base name without
|
|
11
|
+
# extension as the file that implements it. The class name is expected
|
|
12
|
+
# to be the capitalized symbol.
|
|
13
|
+
module Impl
|
|
14
|
+
# methods to be implemented by each external logging service
|
|
15
|
+
#
|
|
16
|
+
# setup - Meant to configure the service for a general use. Each other
|
|
17
|
+
# method in the list calls setup if it has not been called
|
|
18
|
+
# before.
|
|
19
|
+
# setup_rake - Perform additional configuration for Rake
|
|
20
|
+
# setup_rack - Receives the Rack object, meant to add a middleware.
|
|
21
|
+
# setup_worker - Additional configuration for job worker usage.
|
|
22
|
+
# notify_proc - The global logger's notify method will call the proc
|
|
23
|
+
# returned by this. If nil is returned a fallback will
|
|
24
|
+
# be chosen for that method (typically local logging).
|
|
25
|
+
#
|
|
26
|
+
METHODS = [:setup, :setup_rake, :setup_rack,
|
|
27
|
+
:setup_worker, :notify_proc].freeze
|
|
28
|
+
|
|
29
|
+
class Error < StandardError
|
|
30
|
+
class FileNotFound < self
|
|
31
|
+
def initialize(impl)
|
|
32
|
+
super "external logging implementation not found for #{impl.inspect}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class ClassNotFound < self
|
|
37
|
+
def initialize(impl)
|
|
38
|
+
super "external logging implementation does not provide a " \
|
|
39
|
+
"similarly named class: #{impl.inspect}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class << self
|
|
45
|
+
# returns the class implementing the logging service
|
|
46
|
+
def load(impl)
|
|
47
|
+
require(find_file impl)
|
|
48
|
+
|
|
49
|
+
fetch_impl_klass impl
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def find_file(impl)
|
|
55
|
+
re = build_regexp impl
|
|
56
|
+
|
|
57
|
+
impl_file = Dir[glob].find do |path|
|
|
58
|
+
re.match(File.basename path)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
impl_file || raise(Error::FileNotFound.new(impl))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def fetch_impl_klass(impl)
|
|
65
|
+
const_get(impl.capitalize)
|
|
66
|
+
rescue NameError
|
|
67
|
+
raise Error::ClassNotFound.new(impl)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build_regexp(impl)
|
|
71
|
+
Regexp.new("\\A#{Regexp.escape(impl.to_s + extname)}\\z")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# these are almost constants, but since this is meant to be init
|
|
75
|
+
# code with throw-away strings they are left here as helper methods
|
|
76
|
+
def glob
|
|
77
|
+
directory << File::SEPARATOR << '*' << File.extname(__FILE__)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def directory
|
|
81
|
+
__FILE__.chomp(extname) + File::SEPARATOR
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def extname
|
|
85
|
+
# assume implementations will be coded in our own language
|
|
86
|
+
File.extname __FILE__
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require '3scale/backend/environment'
|
|
2
|
+
require '3scale/backend/configuration'
|
|
3
|
+
|
|
4
|
+
module ThreeScale
|
|
5
|
+
module Backend
|
|
6
|
+
module Logging
|
|
7
|
+
module External
|
|
8
|
+
module Impl
|
|
9
|
+
module Airbrake
|
|
10
|
+
class << self
|
|
11
|
+
def setup(api_key)
|
|
12
|
+
do_require
|
|
13
|
+
|
|
14
|
+
configure api_key
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def setup_rack(rack)
|
|
18
|
+
rack.use middleware
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def setup_rake
|
|
22
|
+
require 'airbrake/tasks'
|
|
23
|
+
require 'airbrake/rake_handler'
|
|
24
|
+
|
|
25
|
+
::Airbrake.configure do |config|
|
|
26
|
+
config.rescue_rake_exceptions = true
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def setup_worker
|
|
31
|
+
require '3scale/backend/logging/external/resque'
|
|
32
|
+
|
|
33
|
+
External::Resque.setup klass
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def notify_proc
|
|
37
|
+
klass.method(:notify).to_proc
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def do_require
|
|
43
|
+
require 'airbrake'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def klass
|
|
47
|
+
::Airbrake
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def middleware
|
|
51
|
+
::Airbrake::Sinatra
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def configure(api_key)
|
|
55
|
+
::Airbrake.configure do |config|
|
|
56
|
+
config.api_key = api_key
|
|
57
|
+
config.environment_name = Backend.environment
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require '3scale/backend/version'
|
|
2
|
+
require '3scale/backend/environment'
|
|
3
|
+
require '3scale/backend/util'
|
|
4
|
+
require '3scale/backend/logging'
|
|
5
|
+
|
|
6
|
+
module ThreeScale
|
|
7
|
+
module Backend
|
|
8
|
+
module Logging
|
|
9
|
+
module External
|
|
10
|
+
module Impl
|
|
11
|
+
module Bugsnag
|
|
12
|
+
class << self
|
|
13
|
+
def setup(api_key)
|
|
14
|
+
do_require
|
|
15
|
+
|
|
16
|
+
configure api_key
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def setup_rack(rack)
|
|
20
|
+
rack.use middleware
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def setup_rake
|
|
24
|
+
# no-op
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def setup_worker
|
|
28
|
+
require '3scale/backend/logging/external/resque'
|
|
29
|
+
|
|
30
|
+
External::Resque.setup klass
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def notify_proc
|
|
34
|
+
klass.method(:notify).to_proc
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def do_require
|
|
40
|
+
require 'bugsnag'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def klass
|
|
44
|
+
::Bugsnag
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def middleware
|
|
48
|
+
::Bugsnag::Rack
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def configure(api_key)
|
|
52
|
+
::Bugsnag.configure do |config|
|
|
53
|
+
config.api_key = api_key
|
|
54
|
+
config.release_stage = Backend.environment
|
|
55
|
+
config.app_version = Backend::VERSION
|
|
56
|
+
config.timeout = 3
|
|
57
|
+
config.logger = Backend.logger
|
|
58
|
+
config.meta_data_filters = []
|
|
59
|
+
config.notify_release_stages = ['production', 'preview']
|
|
60
|
+
config.project_root = Backend::Util.root_dir
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module ThreeScale
|
|
2
|
+
module Backend
|
|
3
|
+
module Logging
|
|
4
|
+
module External
|
|
5
|
+
module Impl
|
|
6
|
+
# the default implementation does nothing
|
|
7
|
+
class Default
|
|
8
|
+
class << self
|
|
9
|
+
(Impl::METHODS - public_instance_methods(false)).each do |m|
|
|
10
|
+
define_method(m) { |*| }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# This is a module to configure an external error logging service for Resque.
|
|
2
|
+
#
|
|
3
|
+
# The requirement is that an object be passed in that implements the same
|
|
4
|
+
# interface as Airbrake.
|
|
5
|
+
#
|
|
6
|
+
# This requires a Resque version with https://github.com/resque/resque/pull/1602
|
|
7
|
+
#
|
|
8
|
+
module ThreeScale
|
|
9
|
+
module Backend
|
|
10
|
+
module Logging
|
|
11
|
+
module External
|
|
12
|
+
module Resque
|
|
13
|
+
class << self
|
|
14
|
+
def setup(klass)
|
|
15
|
+
load_resque_failure_for klass
|
|
16
|
+
|
|
17
|
+
::Resque::Failure::Multiple.classes = [
|
|
18
|
+
::Resque::Failure::Redis,
|
|
19
|
+
Class.new(::Resque::Failure::Airbrake) do
|
|
20
|
+
def self.configure(&block)
|
|
21
|
+
# calling this hook is an error
|
|
22
|
+
raise "error: tried to configure #{self.inspect} from Resque"
|
|
23
|
+
end
|
|
24
|
+
end,
|
|
25
|
+
]
|
|
26
|
+
::Resque::Failure.backend = ::Resque::Failure::Multiple
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# set the argument as ::Airbrake and load Resque::Failure
|
|
32
|
+
def load_resque_failure_for(klass)
|
|
33
|
+
require 'resque/failure/base'
|
|
34
|
+
require 'resque/failure/multiple'
|
|
35
|
+
require 'resque/failure/redis'
|
|
36
|
+
|
|
37
|
+
# ensure we have a matching ::Airbrake top-level constant or
|
|
38
|
+
# define it if missing
|
|
39
|
+
begin
|
|
40
|
+
airbrake = ::Kernel.const_get(:Airbrake)
|
|
41
|
+
rescue NameError
|
|
42
|
+
# not defined, so set our own
|
|
43
|
+
::Kernel.const_set(:Airbrake, klass)
|
|
44
|
+
else
|
|
45
|
+
# defined, expect it's our own object
|
|
46
|
+
raise "Airbrake constant pre-defined as #{airbrake.inspect}, " \
|
|
47
|
+
" required to be #{klass.inspect}!" if airbrake != klass
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
require 'resque/failure/airbrake'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|