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