d13n 0.5.2

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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.rspec +6 -0
  4. data/.rubocop.yml +5 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +22 -0
  7. data/Gemfile.lock +151 -0
  8. data/Guardfile +63 -0
  9. data/README.md +200 -0
  10. data/bin/d13n +11 -0
  11. data/d13n.gemspec +34 -0
  12. data/lib/d13n/application/class_methods.rb +56 -0
  13. data/lib/d13n/application.rb +3 -0
  14. data/lib/d13n/cli/command.rb +76 -0
  15. data/lib/d13n/cli/commands/scaffold.rb +345 -0
  16. data/lib/d13n/configuration/default_source.rb +200 -0
  17. data/lib/d13n/configuration/dotted_hash.rb +39 -0
  18. data/lib/d13n/configuration/environment_source.rb +89 -0
  19. data/lib/d13n/configuration/manager.rb +239 -0
  20. data/lib/d13n/configuration/manual_source.rb +4 -0
  21. data/lib/d13n/configuration/mask_defaults.rb +6 -0
  22. data/lib/d13n/configuration/server_source.rb +83 -0
  23. data/lib/d13n/configuration/yaml_source.rb +66 -0
  24. data/lib/d13n/configuration.rb +6 -0
  25. data/lib/d13n/ext/string.rb +17 -0
  26. data/lib/d13n/logger/log_once.rb +24 -0
  27. data/lib/d13n/logger/memory_logger.rb +48 -0
  28. data/lib/d13n/logger/null_logger.rb +16 -0
  29. data/lib/d13n/logger.rb +213 -0
  30. data/lib/d13n/metric/conductor.rb +123 -0
  31. data/lib/d13n/metric/helper.rb +62 -0
  32. data/lib/d13n/metric/http_clients/http_helper.rb +15 -0
  33. data/lib/d13n/metric/http_clients/net_http_wrappers.rb +54 -0
  34. data/lib/d13n/metric/http_clients.rb +4 -0
  35. data/lib/d13n/metric/instrumentation/app_exception.rb +70 -0
  36. data/lib/d13n/metric/instrumentation/controller_instrumentation.rb +91 -0
  37. data/lib/d13n/metric/instrumentation/em-websocket.rb +71 -0
  38. data/lib/d13n/metric/instrumentation/exception.rb +65 -0
  39. data/lib/d13n/metric/instrumentation/middleware_tracing.rb +82 -0
  40. data/lib/d13n/metric/instrumentation/net.rb +36 -0
  41. data/lib/d13n/metric/instrumentation/sinatra/stream_namer.rb +35 -0
  42. data/lib/d13n/metric/instrumentation/sinatra.rb +165 -0
  43. data/lib/d13n/metric/instrumentation/websocket_instrumentation.rb +42 -0
  44. data/lib/d13n/metric/instrumentation.rb +41 -0
  45. data/lib/d13n/metric/manager.rb +106 -0
  46. data/lib/d13n/metric/metrics/app_database_metric.rb +4 -0
  47. data/lib/d13n/metric/metrics/app_http_metric.rb +229 -0
  48. data/lib/d13n/metric/metrics/app_state_metric.rb +103 -0
  49. data/lib/d13n/metric/metrics/base.rb +14 -0
  50. data/lib/d13n/metric/metrics/biz_state_metric.rb +4 -0
  51. data/lib/d13n/metric/metrics.rb +6 -0
  52. data/lib/d13n/metric/stream/span_tracer_helpers.rb +72 -0
  53. data/lib/d13n/metric/stream/stream_tracer_helpers.rb +141 -0
  54. data/lib/d13n/metric/stream/traced_span_stack.rb +73 -0
  55. data/lib/d13n/metric/stream.rb +322 -0
  56. data/lib/d13n/metric/stream_state.rb +68 -0
  57. data/lib/d13n/metric.rb +11 -0
  58. data/lib/d13n/rack/d13n_middleware.rb +21 -0
  59. data/lib/d13n/rack/metric_middleware.rb +18 -0
  60. data/lib/d13n/service/background_job/sinatra.rb +24 -0
  61. data/lib/d13n/service/background_job.rb +1 -0
  62. data/lib/d13n/service/start.rb +75 -0
  63. data/lib/d13n/service.rb +91 -0
  64. data/lib/d13n/support/request_id.rb +29 -0
  65. data/lib/d13n/version.rb +14 -0
  66. data/lib/d13n.rb +92 -0
  67. data/templates/.rspec.template +6 -0
  68. data/templates/.ruby-version.template +1 -0
  69. data/templates/Gemfile.template +16 -0
  70. data/templates/Guardfile.template +64 -0
  71. data/templates/Jenkinsfile.template +85 -0
  72. data/templates/Makefile.template +178 -0
  73. data/templates/README.md.template +1 -0
  74. data/templates/Rakefile.template +6 -0
  75. data/templates/application.yml.template +14 -0
  76. data/templates/config.ru.template +4 -0
  77. data/templates/docker/.dockerignore.template +5 -0
  78. data/templates/docker/Dockerfile.application.development +15 -0
  79. data/templates/docker/Dockerfile.cache.development +18 -0
  80. data/templates/docker/Dockerfile.development +27 -0
  81. data/templates/docker/Dockerfile.release +16 -0
  82. data/templates/docker/docker-compose.yml.development +53 -0
  83. data/templates/docker/docker-compose.yml.release +37 -0
  84. data/templates/lib/api/service.rb.template +10 -0
  85. data/templates/lib/api/support.rb.template +38 -0
  86. data/templates/lib/api/version.rb.template +3 -0
  87. data/templates/lib/api.rb.template +4 -0
  88. data/templates/lib/application.rb.template +49 -0
  89. data/templates/lib/service.rb.template +4 -0
  90. data/templates/lib/version.rb.template +3 -0
  91. data/templates/scripts/test.sh.template +7 -0
  92. data/templates/spec/spec_helper.rb.template +56 -0
  93. data/templates/tasks/migration.rake.template +11 -0
  94. data/templates/tasks/spec.rake.template +21 -0
  95. metadata +199 -0
@@ -0,0 +1,65 @@
1
+ module D13n::Metric::Instrumentation
2
+ module Exception
3
+ def self.included(descendance)
4
+ descendance.include(InstanceMethods)
5
+ descendance.extend(ClassMethods)
6
+ end
7
+ module ClassMethods
8
+ def d13n_error_inherated?
9
+ !!(self < D13n::Error)
10
+ end
11
+
12
+ def exception_with_d13n_instrumentation(*arg)
13
+ return exception_without_d13n_instrumentation(*arg) if d13n_error_inherated?
14
+
15
+ manager = D13n::Metric::Manager.instance
16
+ metric = manager.metric(:app_state)
17
+
18
+ if metric.nil?
19
+ D13n.logger.info "Null intrumentation metric class and ignore collection"
20
+ return exception_without_d13n_instrumentation(*arg)
21
+ end
22
+
23
+ metric.instance(manager, {type: 'exception', at: 'runtime', src:'others'}).process do
24
+ exception_without_d13n_instrumentation(*arg)
25
+ end
26
+ return exception_without_d13n_instrumentation(*arg)
27
+ end
28
+ end
29
+
30
+ module InstanceMethods
31
+ def exception_with_d13n_instrumentation(*arg)
32
+ self.class.exception_with_d13n_instrumentation(*arg)
33
+ end
34
+ end
35
+
36
+ module_function
37
+ def enable?
38
+ D13n.config[:'metric.app.state.exception.enable'] == 'true' || D13n.config[:'metric.app.state.exception.enable'] == true
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ D13n::Metric::Instrumentation::Conductor.direct do
45
+ named :exception
46
+
47
+ depend_on do
48
+ D13n::Metric::Instrumentation::Exception.enable?
49
+ end
50
+
51
+ performances do
52
+ D13n.logger.info 'Installing Exeception instrumentation'
53
+ end
54
+
55
+ performances do
56
+ class StandardError
57
+ class << self
58
+ alias exception_without_d13n_instrumentation exception
59
+ alias exception exception_with_d13n_instrumentation
60
+ end
61
+ alias exception_without_d13n_instrumentation exception
62
+ alias exception exception_with_d13n_instrumentation
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,82 @@
1
+ module D13n::Metric::Instrumentation
2
+ module MiddlewareTracing
3
+ STREAM_STARTED_KEY = 'd13n.stream_started'.freeze unless defined?(STREAM_STARTED_KEY)
4
+
5
+ def call(env)
6
+ first_middleware = stream_started(env)
7
+
8
+ state = D13n::Metric::StreamState.st_get
9
+
10
+ begin
11
+ D13n::Metric::Stream.start(state, category, build_stream_options(env, first_middleware))
12
+ state.notify_rack_call(env) if first_middleware
13
+ result = (@target == self) ? traced_call(env) : @target.call(env)
14
+
15
+ if first_middleware
16
+ capture_response_attributes(state, result)
17
+ end
18
+
19
+ result
20
+ rescue Exception => e
21
+ D13n.logger.error(e)
22
+ raise e
23
+ ensure
24
+ D13n::Metric::Stream.stop(state)
25
+ end
26
+ end
27
+
28
+ def capture_response_code(state, result)
29
+
30
+ if result.is_a?(Array) && state.current_stream
31
+ state.current_stream.http_response_code = result[0]
32
+ end
33
+ end
34
+
35
+ CONTENT_TYPE = 'Content-Type'.freeze unless defined?(CONTENT_TYPE)
36
+
37
+ def capture_response_content_type(state, result)
38
+ if result.is_a?(Array) && state.current_stream
39
+ _, headers, _ = result
40
+ state.current_stream.response_content_type = headers[CONTENT_TYPE]
41
+ end
42
+ end
43
+
44
+ CONTENT_LENGTH = 'Content-Length'.freeze unless defined?(CONTENT_LENGTH)
45
+
46
+ def capture_response_content_length(state, result)
47
+ if result.is_a?(Array) && state.current_stream
48
+ _, headers, _ = result
49
+ state.current_stream.response_content_length = headers[CONTENT_LENGTH]
50
+ end
51
+ end
52
+
53
+ def capture_response_attributes(state, result)
54
+ capture_response_code(state, result)
55
+ capture_response_content_type(state, result)
56
+ capture_response_content_length(state, result)
57
+ end
58
+ #
59
+ # stream_name, apdex_started_at, request
60
+ #
61
+
62
+ def build_stream_options(env, first_middleware)
63
+ opts = @stream_options
64
+ opts = merge_first_middleware_options(opts, env) if first_middleware
65
+ opts
66
+ end
67
+
68
+ def merge_first_middleware_options(opts, env)
69
+ opts[:apdex_started_at] = parse_request_timestamp(env)
70
+ opts[:request] = ::Rack::Request.new(env) if defined?(::Rack)
71
+ opts
72
+ end
73
+
74
+ def parse_request_timestamp(env)
75
+ Time.now.to_f
76
+ end
77
+
78
+ def stream_started(env)
79
+ env[STREAM_STARTED_KEY] = true unless env[STREAM_STARTED_KEY]
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,36 @@
1
+
2
+ D13n::Metric::Instrumentation::Conductor.direct do
3
+ named :net_http
4
+
5
+ depend_on do
6
+ defined?(Net) && defined?(Net::HTTP)
7
+ end
8
+
9
+ performances do
10
+ D13n.logger.info 'Installing Net instrumentation'
11
+ require 'd13n/metric/http_clients/net_http_wrappers'
12
+ end
13
+
14
+ performances do
15
+ class Net::HTTP
16
+ def request_with_d13n_instrumentation(request, *args, &block)
17
+ return request_without_d13n_instrumentation(request, *args, &block) unless started?
18
+ wrapped_request = D13n::Metric::HTTPClients::NetHTTPClientRequest.new(self, request)
19
+ manager = D13n::Metric::Manager.instance
20
+ metric = manager.metric(:app_http)
21
+
22
+ if metric.nil?
23
+ D13n.logger.info "Null intrumentation metric class and ignore collection"
24
+ return request_without_d13n_instrumentation(request, *args, &block)
25
+ end
26
+
27
+ metric.instance(manager, direction: 'out').process(wrapped_request) do
28
+ request_without_d13n_instrumentation(request, *args, &block)
29
+ end
30
+ end
31
+
32
+ alias request_without_d13n_instrumentation request
33
+ alias request request_with_d13n_instrumentation
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ module D13n::Metric::Instrumentation::Sinatra
2
+ module StreamNamer
3
+ extend self
4
+
5
+ SINATRA_ROUTE = 'sinatra.route'
6
+ UNKNOWN = 'unknown'.freeze
7
+ def for_route(env, request)
8
+ env[SINATRA_ROUTE]
9
+ end
10
+
11
+ def initial_stream_name(request)
12
+ stream_name(UNKNOWN, request)
13
+ end
14
+
15
+ ROOT = '.'.freeze
16
+
17
+
18
+ def stream_name(route_text, request)
19
+ verb = http_verb(request)
20
+
21
+ route_text = route_text.source if route_text.is_a?(Regexp)
22
+ name = route_text.gsub(%r{^[/^\\A]*(.*?)[/\$\?\\z]*$}, '\1')
23
+ name = ROOT if name.empty?
24
+ name = "#{verb}#{name}" unless verb.nil?
25
+ name
26
+ rescue => e
27
+ ::D13n.logger.debug("#{e.class} : #{e.message} - Error encountered trying to identify Sinatra transaction name")
28
+ UNKNOWN
29
+ end
30
+
31
+ def http_verb(request)
32
+ request.request_method if request.respond_to?(:request_method)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,165 @@
1
+ require 'd13n/metric/instrumentation/controller_instrumentation'
2
+ require 'd13n/metric/instrumentation/sinatra/stream_namer'
3
+ require 'd13n/rack/metric_middleware'
4
+ D13n::Metric::Instrumentation::Conductor.direct do
5
+ named :sinatra
6
+
7
+ depend_on do
8
+ D13n.config[:'metric.app.http.in.sinatra.enable'] &&
9
+ defined?(::Sinatra) && defined?(::Sinatra::Base) &&
10
+ Sinatra::Base.private_method_defined?(:dispatch!) &&
11
+ Sinatra::Base.private_method_defined?(:process_route) &&
12
+ Sinatra::Base.private_method_defined?(:route_eval)
13
+ end
14
+
15
+ performances do
16
+ D13n.logger.info 'Installing Sinatra instrumentation'
17
+ end
18
+
19
+ performances do
20
+ ::Sinatra::Base.class_eval do
21
+ include D13n::Metric::Instrumentation::Sinatra
22
+ alias dispatch_without_d13n_instrumentation dispatch!
23
+ alias dispatch! dispatch_with_d13n_instrumentation
24
+
25
+ alias process_route_without_d13n_instrumentation process_route
26
+ alias process_route process_route_with_d13n_instrumentation
27
+
28
+ alias route_eval_without_d13n_instrumentation route_eval
29
+ alias route_eval route_eval_with_d13n_instrumentation
30
+
31
+ end
32
+ end
33
+
34
+ performances do
35
+ if Sinatra::Base.respond_to?(:build)
36
+ require 'd13n/rack/metric_middleware'
37
+
38
+ ::Sinatra::Base.class_eval do
39
+ class << self
40
+ alias build_without_d13n_instrumentation build
41
+ alias build build_with_d13n_instrumentation
42
+ end
43
+ end
44
+ else
45
+ D13n.logger.info("Skipping auto-injection of middleware for Sinatra - require Sinatra 1.2.1+")
46
+ end
47
+ end
48
+
49
+ performances do
50
+ if defined?(::SinatraWebsocket) &&
51
+ defined?(::Sinatra::Request) &&
52
+ Sinatra::Request.respond_to?(:websocket)
53
+ ::Sinatra::Base.class_eval do
54
+ class << self
55
+ alias websocket_without_d13n_instrumentation websocket
56
+ alias websocket websocket_with_d13n_instrumentation
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ module D13n::Metric::Instrumentation
64
+ module Sinatra
65
+ include D13n::Metric::Instrumentation::ControllerInstrumentation
66
+
67
+ def self.included(descendance)
68
+ descendance.extend(ClassMethods)
69
+ end
70
+
71
+ module ClassMethods
72
+ def d13n_middlewares
73
+ middlewares = []
74
+ if D13n::Rack::MetricMiddleware.enabled?
75
+ middlewares << D13n::Rack::MetricMiddleware
76
+ end
77
+ middlewares
78
+ end
79
+
80
+ def websocket_with_d13n_instrumentation(*args, &block)
81
+ websocket_without_d13n_instrumentation(*args, &block)
82
+ end
83
+
84
+ def build_with_d13n_instrumentation(*args, &block)
85
+ if auto_middleware_enable?
86
+ d13n_middlewares.each do |middleware_kls|
87
+ try_to_use(self, middleware_kls)
88
+ end
89
+ end
90
+
91
+ build_without_d13n_instrumentation(*args, &block)
92
+ end
93
+
94
+ private
95
+
96
+ def auto_middleware_enable?
97
+ D13n.config[:'metric.app.http.in.sinatra.auto_middleware.enable']
98
+ end
99
+
100
+
101
+ def try_to_use(app, clazz)
102
+ if app.middleware.nil?
103
+ D13n.logger.debug("Failed to use middle for middleware missing in app")
104
+ return nil
105
+ end
106
+ has_middleware = app.middleware.any? { |info| info[0] == clazz }
107
+ app.use(clazz) unless has_middleware
108
+ end
109
+ end
110
+
111
+ def process_route_with_d13n_instrumentation(*args, &block)
112
+ begin
113
+ env["d13n.last_route"] = args[0]
114
+ rescue => e
115
+ D13n.logger.debug("Failed determining last route in Sinatra", e)
116
+ end
117
+
118
+ process_route_without_d13n_instrumentation(*args, &block)
119
+ end
120
+
121
+ def route_eval_with_d13n_instrumentation(*args, &block)
122
+ begin
123
+ stream_name = StreamNamer.for_route(env, request)
124
+
125
+ unless stream_name.nil?
126
+ ::D13n::Metric::Stream.set_default_stream_name("#{self.class.name}.#{stream_name}", :sinatra)
127
+ end
128
+ rescue => e
129
+ D13n.logger.debug("Failed during route_eval to set stream name", e)
130
+ end
131
+
132
+ route_eval_without_d13n_instrumentation(*args, &block)
133
+ end
134
+
135
+ def dispatch_with_d13n_instrumentation
136
+ request_params = get_request_params
137
+ name = StreamNamer.initial_stream_name(request)
138
+ filter_params = get_filter_parames(request_params)
139
+ perform_action_with_d13n_stream(:category => :sinatra,
140
+ :name => name,
141
+ :params => filter_params) do
142
+ dispatch_and_notice_errors_with_d13n_instrumentation
143
+ end
144
+ end
145
+
146
+ def dispatch_and_notice_errors_with_d13n_instrumentation
147
+ dispatch_without_d13n_instrumentation
148
+ ensure
149
+ had_error = env.has_key?('sinatra.error')
150
+ ::D13n::Metric::Manager.notice_error(env['sinatra.error']) if had_error
151
+ end
152
+
153
+ def get_request_params
154
+ begin
155
+ @request.params
156
+ rescue => e
157
+ D13n.logger.debug("Failed to get params from Rack request.", e)
158
+ end
159
+ end
160
+
161
+ def get_filter_parames(request_params)
162
+ request_params
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,42 @@
1
+ require 'd13n/metric/stream'
2
+ require 'd13n/metric/stream_state'
3
+ module D13n::Metric::Instrumentation
4
+ module WebSocketInstrumentation
5
+ def perform_websocket_with_d13n_stream(*args, &block)
6
+ state = D13n::Metric::StreamState.st_get
7
+ category = :websocket
8
+
9
+ trace_options = args.last.is_a?(Hash) ? args.last : {}
10
+ stream_options = create_stream_options(trace_options, category, state)
11
+
12
+ begin
13
+ stream = D13n::Metric::Stream.start(state, category, stream_options)
14
+
15
+ begin
16
+ yield
17
+ update_stream_data(state)
18
+ rescue => e
19
+ D13n::Metric::Manager.notice_error(e)
20
+ raise
21
+ ensure
22
+ D13n::Metric::Stream.stop(state)
23
+ end
24
+ end
25
+ end
26
+
27
+ protected
28
+ def create_stream_options(trace_options, categroy, state)
29
+ stream_options = {}
30
+ stream_options[:stream_name]
31
+ stream_options
32
+ end
33
+
34
+ def update_stream_data(state)
35
+ stream = state.current_stream
36
+ stream.http_response_code = 200
37
+ stream.request_content_length = request.delete(:request_content_length)
38
+ stream.response_content_type = "websocket"
39
+ stream.response_content_length = request.delete(:response_content_length)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ require 'd13n/metric/conductor'
2
+ module D13n::Metric::Instrumentation
3
+ def load_instrumentation_files path
4
+ Dir.glob(path) do |file|
5
+ begin
6
+ require file.to_s
7
+ rescue => e
8
+ D13n.logger.warn "Error loading instrumentation file '#{file}':", e
9
+ end
10
+ end
11
+ end
12
+
13
+ def add_instrumentation file
14
+ if @instrumented
15
+ load_instrumentation_files file
16
+ else
17
+ @instrumentation_files << file
18
+ end
19
+ end
20
+
21
+ def setup_instrumentation
22
+ _setup_instrumentation
23
+ end
24
+
25
+ private
26
+ def _setup_instrumentation
27
+ return if @instrumented
28
+
29
+ @instrumentation_files = []
30
+
31
+ @instrumented = true
32
+
33
+ instrumentation_path = File.expand_path(File.join(File.dirname(__FILE__), 'instrumentation'))
34
+
35
+ @instrumentation_files << File.join(instrumentation_path, '*.rb')
36
+
37
+ @instrumentation_files.each { |path| load_instrumentation_files(path) }
38
+ Conductor.perform!
39
+ D13n.logger.info "Finished instrumentation"
40
+ end
41
+ end
@@ -0,0 +1,106 @@
1
+ require 'statsd-instrument'
2
+ require 'd13n/metric/metrics'
3
+ require 'd13n/metric/instrumentation'
4
+ require 'd13n/metric/stream'
5
+ module D13n::Metric
6
+ class MetricInitError < MetricError;end
7
+ class MetricArgError < MetricError; end
8
+ class MetricNotFoundError < MetricError; end
9
+ class InstrumentInitError < MetricError; end
10
+ class Manager
11
+ include D13n::Metric::Instrumentation
12
+ def self.start(channel='logger', opts={})
13
+ @instance ||= new(channel, opts)
14
+ end
15
+
16
+ def self.instance
17
+ @instance || start
18
+ end
19
+
20
+ def self.notice_error(exception, opts={})
21
+ Stream.notice_error(exception, opts)
22
+ end
23
+
24
+ extend Forwardable
25
+
26
+ def_delegators StatsD, :measure, :increment, :gauge, :set
27
+
28
+ CHANNELS = ['udp', 'logger', 'null']
29
+
30
+ METRIC_MAPPING = {
31
+ 'app_state' => AppStateMetric,
32
+ 'app_http' => AppHttpMetric,
33
+ 'app_database' => AppDatabaseMetric,
34
+ 'biz_state' => BizStateMetric
35
+ }
36
+
37
+ attr_reader :channel, :backend
38
+
39
+ def initialize(channel, opts={})
40
+ self.channel = channel
41
+ @opts = opts
42
+ set_backend
43
+ setup_instrumentation
44
+ end
45
+
46
+ def set_backend
47
+ @backend = if @channel == 'udp'
48
+ setup_udp_backend
49
+ elsif @channel == 'logger'
50
+ setup_logger_backend
51
+ else @channel == 'null'
52
+ setup_null_backend
53
+ end
54
+ D13n.logger.info "Using #{@backend.to_s} as channel in metric"
55
+ StatsD.backend = @backend
56
+ end
57
+
58
+ def setup_udp_backend
59
+ @host = @opts.fetch(:host, default_host)
60
+ @port = @opts.fetch(:port, default_port)
61
+ @backend_uri = "#{@host}:#{@port}"
62
+ @protocol = @opts.fetch(:protocol, default_protocol)
63
+ StatsD::Instrument::Backends::UDPBackend.new(@backend_uri, @protocol)
64
+ end
65
+
66
+ def setup_logger_backend
67
+ @logger = @opts.fetch(:logger, D13n.logger)
68
+ raise InstrumentInitError.new "Missing Logger for logger backend" if @logger.nil?
69
+ StatsD::Instrument::Backends::LoggerBackend.new(@logger)
70
+ end
71
+
72
+ def setup_null_backend
73
+ StatsD::Instrument::Backends::NullBackend.new
74
+ end
75
+
76
+ def channel=(c)
77
+ @channel = c.to_s.downcase
78
+ raise MetricArgError.new("Invalid Instrument channel: #{c}") unless CHANNELS.include?(@channel)
79
+ end
80
+
81
+ def metric(type)
82
+ metric_for(type)
83
+ rescue MetricNotFoundError => e
84
+ D13n.logger.error "Instrument Metric Type #{type} Not Found in [#{METRIC_MAPPING.keys.join(',')}]"
85
+ return nil
86
+ end
87
+
88
+ def metric_for(type)
89
+ expected_metric = METRIC_MAPPING[type.to_s.downcase]
90
+ raise MetricNotFoundError.new "#{type} of metric not found!" if expected_metric.nil?
91
+ expected_metric
92
+ end
93
+
94
+ def default_host
95
+ D13n.config[:'service.metric.host'] || 'localhost'
96
+ end
97
+
98
+ def default_port
99
+ D13n.config[:'service.metric.port'] || 8125
100
+ end
101
+
102
+ def default_protocol
103
+ D13n.config[:'service.metric.protocol'] || :datadog
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,4 @@
1
+ module D13n::Metric
2
+ class AppDatabaseMetric < Base
3
+ end
4
+ end