elastic-apm 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of elastic-apm might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da4eac00d32100e5f82cd8dfe3042278eb4f81865c797ee743b4e2fa89269c18
4
- data.tar.gz: bd07824d56e89d645b08cfb2b5090a6ec4fcefbf360cb559420cd7f050629cd1
3
+ metadata.gz: 5e3f8d9490f60e28d99b6e15e7efa2823fb773bacbdc9762f91fc92a4214b05b
4
+ data.tar.gz: 655814ff9046d8e9dd2d586688b9bc45acdb95f0102626af5ad0886330b58c16
5
5
  SHA512:
6
- metadata.gz: 1b57fe86030e4f0aeb667cf886ac45708c4c41d26a0e85ed7736ee8c98319763cc15e0504bee2407f29a4503e98c32899061ad7a5b7fd035fcc5ed527cd7b410
7
- data.tar.gz: bfc683d303d7b0a7c5400cd064c76f12dca648eeb6c6cecf73bc25cdb6bae4253e32e708aa57168aa9f0963e5531c7e4cdba10dd5f9d10782197c6bc3426e382
6
+ metadata.gz: d4b9cace9b89eddb0ec281061fd098daa1e9297feb7fbc1c5de8ba44746ad2ab225df877480b5a213847d65502e39c321a79d4f35bee257d60d4a63a254c76e5
7
+ data.tar.gz: ae713fe3ad97666862ed91ecaeb8a199cfdaacb69edeb011840bb34e7da7692e97dffe15b729e3ec1275663bf2e381f241cb7579ca366a1ac7224c7465cbe9db
data/Gemfile CHANGED
@@ -7,9 +7,9 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
7
7
  gemspec
8
8
 
9
9
  gem 'elasticsearch'
10
- gem 'fakeredis', require: nil,
11
- github: 'guilleiguaran/fakeredis' # needs master right now
10
+ gem 'fakeredis', require: nil
12
11
  gem 'json-schema'
12
+ gem 'mongo'
13
13
  gem 'pry'
14
14
  gem 'rack-test'
15
15
  gem 'redis', require: nil
@@ -39,8 +39,5 @@ else
39
39
  gem framework
40
40
  end
41
41
 
42
- # doesn't work with Rails master, so skip testing
43
- gem 'delayed_job', '~> 4' unless [framework, version] == %w[rails 5.2]
44
-
45
42
  gem 'rails' if framework == 'sinatra'
46
43
  gem 'sinatra' if framework == 'rails'
@@ -61,7 +61,7 @@ module ElasticAPM
61
61
  # @param context [Context] An optional [Context]
62
62
  # @yield [Transaction] Optional block encapsulating transaction
63
63
  # @return [Transaction] Unless block given
64
- def self.transaction(name, type = nil, context: nil, &block)
64
+ def self.transaction(name = nil, type = nil, context: nil, &block)
65
65
  return (block_given? ? yield : nil) unless agent
66
66
 
67
67
  agent.transaction(name, type, context: context, &block)
@@ -8,21 +8,13 @@ module ElasticAPM
8
8
  class Config
9
9
  DEFAULTS = {
10
10
  config_file: 'config/elastic_apm.yml',
11
-
12
11
  server_url: 'http://localhost:8200',
13
- secret_token: nil,
14
12
 
15
- service_name: nil,
16
- service_version: nil,
17
13
  environment: ENV['RAILS_ENV'] || ENV['RACK_ENV'],
18
14
  enabled_environments: %w[production],
19
- framework_name: nil,
20
- framework_version: nil,
21
- hostname: nil,
22
15
 
23
16
  log_path: '-',
24
17
  log_level: Logger::INFO,
25
- logger: nil,
26
18
 
27
19
  max_queue_size: 500,
28
20
  flush_interval: 10,
@@ -184,6 +176,7 @@ module ElasticAPM
184
176
  delayed_job
185
177
  elasticsearch
186
178
  json
179
+ mongo
187
180
  net_http
188
181
  redis
189
182
  sequel
@@ -37,8 +37,7 @@ module ElasticAPM
37
37
  request = prepare_request path, payload.to_json
38
38
  response = @adapter.perform request
39
39
 
40
- status = response.code.to_i
41
- return response if status >= 200 && status <= 299
40
+ return response if response.is_a?(Net::HTTPSuccess)
42
41
 
43
42
  error 'POST returned an unsuccessful status code (%d)', response.code
44
43
  error "apm-server's response: %s", response.body
@@ -68,6 +68,8 @@ end
68
68
 
69
69
  # @api private
70
70
  module Kernel
71
+ private
72
+
71
73
  alias require_without_apm require
72
74
 
73
75
  def require(path)
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElasticAPM
4
+ # @api private
5
+ module Injectors
6
+ # @api private
7
+ class MongoInjector
8
+ def install
9
+ ::Mongo::Monitoring::Global.subscribe(
10
+ ::Mongo::Monitoring::COMMAND,
11
+ Subscriber.new
12
+ )
13
+ end
14
+
15
+ # @api private
16
+ class Subscriber
17
+ TYPE = 'db.mongodb.query'.freeze
18
+
19
+ def initialize
20
+ @events = {}
21
+ end
22
+
23
+ def started(event)
24
+ push_event(event)
25
+ end
26
+
27
+ def failed(event)
28
+ pop_event(event)
29
+ end
30
+
31
+ def succeeded(event)
32
+ pop_event(event)
33
+ end
34
+
35
+ private
36
+
37
+ def push_event(event)
38
+ ctx = Span::Context.new(
39
+ instance: event.database_name,
40
+ statement: nil,
41
+ type: 'mongodb'.freeze,
42
+ user: nil
43
+ )
44
+ span = ElasticAPM.span(event.command_name, TYPE, context: ctx)
45
+ @events[event.operation_id] = span
46
+ end
47
+
48
+ def pop_event(event)
49
+ span = @events[event.operation_id]
50
+ span.done
51
+ end
52
+ end
53
+ end
54
+
55
+ register 'Mongo', 'mongo', MongoInjector.new
56
+ end
57
+ end
@@ -5,7 +5,7 @@ module ElasticAPM
5
5
  module Injectors
6
6
  # @api private
7
7
  class NetHTTPInjector
8
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
8
+ # rubocop:disable Metrics/MethodLength
9
9
  def install
10
10
  Net::HTTP.class_eval do
11
11
  alias request_without_apm request
@@ -15,21 +15,10 @@ module ElasticAPM
15
15
  return request_without_apm(req, body, &block)
16
16
  end
17
17
 
18
- host, port = req['host'] && req['host'].split(':')
18
+ host, = req['host'] && req['host'].split(':')
19
19
  method = req.method
20
- path = req.path
21
- scheme = use_ssl? ? 'https' : 'http'
22
20
 
23
- # inside a session
24
21
  host ||= address
25
- port ||= 80
26
-
27
- # TODO: investigate
28
- _extra = {
29
- scheme: scheme,
30
- port: port,
31
- path: path
32
- }
33
22
 
34
23
  name = "#{method} #{host}"
35
24
  type = "ext.net_http.#{method}"
@@ -40,7 +29,7 @@ module ElasticAPM
40
29
  end
41
30
  end
42
31
  end
43
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
32
+ # rubocop:enable Metrics/MethodLength
44
33
  end
45
34
 
46
35
  register 'Net::HTTP', 'net/http', NetHTTPInjector.new
@@ -57,7 +57,12 @@ module ElasticAPM # :nodoc:
57
57
  end
58
58
  end
59
59
 
60
- %w[action_controller action_view active_record].each do |lib|
60
+ %w[
61
+ action_controller
62
+ action_mailer
63
+ action_view
64
+ active_record
65
+ ].each do |lib|
61
66
  require "elastic_apm/normalizers/#{lib}"
62
67
  end
63
68
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElasticAPM
4
+ module Normalizers
5
+ module ActionMailer
6
+ # @api private
7
+ class ProcessActionNormalizer < Normalizer
8
+ register 'process.action_mailer'
9
+ TYPE = 'app.mailer.action'.freeze
10
+
11
+ def normalize(transaction, _name, payload)
12
+ transaction.name = endpoint(payload)
13
+ [transaction.name, TYPE, nil]
14
+ end
15
+
16
+ private
17
+
18
+ def endpoint(payload)
19
+ "#{payload[:mailer]}##{payload[:action]}"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -4,7 +4,7 @@ module ElasticAPM
4
4
  module Serializers
5
5
  # @api private
6
6
  class Errors < Serializer
7
- # rubocop:disable Metrics/MethodLength
7
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
8
8
  def build(error)
9
9
  base = {
10
10
  id: error.id,
@@ -17,13 +17,17 @@ module ElasticAPM
17
17
  base[:exception] = build_exception exception
18
18
  end
19
19
 
20
+ if (log = error.log)
21
+ base[:log] = build_log log
22
+ end
23
+
20
24
  if (transaction_id = error.transaction_id)
21
25
  base[:transaction] = { id: transaction_id }
22
26
  end
23
27
 
24
28
  base
25
29
  end
26
- # rubocop:enable Metrics/MethodLength
30
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
27
31
 
28
32
  def build_all(errors)
29
33
  { errors: Array(errors).map(&method(:build)) }
@@ -42,6 +46,16 @@ module ElasticAPM
42
46
  handled: exception.handled
43
47
  }
44
48
  end
49
+
50
+ def build_log(log)
51
+ {
52
+ message: log.message,
53
+ level: log.level,
54
+ logger_name: log.logger_name,
55
+ param_message: log.param_message,
56
+ stacktrace: log.stacktrace.to_a
57
+ }
58
+ end
45
59
  end
46
60
  end
47
61
  end
@@ -71,38 +71,45 @@ module ElasticAPM
71
71
  false
72
72
  end
73
73
 
74
- # rubocop:disable Metrics/MethodLength
75
- def build_frame(config, line, type)
76
- abs_path, lineno, function, _module_name = parse_line(line)
77
-
78
- frame = Frame.new
79
- frame.abs_path = abs_path
80
- frame.filename = strip_load_path(abs_path)
81
- frame.function = function
82
- frame.lineno = lineno.to_i
83
- frame.library_frame = library_frame?(config, abs_path)
74
+ class << self
75
+ attr_accessor :frame_cache
76
+ end
84
77
 
85
- line_count =
86
- context_lines_for(config, type, library_frame: frame.library_frame)
87
- frame.build_context line_count
78
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
79
+ def build_frame(config, line, type)
80
+ # TODO: Eventually move this to agent 'context'
81
+ self.class.frame_cache ||= Util::LruCache.new(2048) do |cache, keys|
82
+ line, type = keys
83
+ abs_path, lineno, function, _module_name = parse_line(line)
84
+
85
+ frame = Frame.new
86
+ frame.abs_path = abs_path
87
+ frame.filename = strip_load_path(abs_path)
88
+ frame.function = function
89
+ frame.lineno = lineno.to_i
90
+ frame.library_frame = library_frame?(config, abs_path)
91
+
92
+ line_count =
93
+ context_lines_for(config, type, library_frame: frame.library_frame)
94
+ frame.build_context line_count
95
+
96
+ cache[[line, type]] = frame
97
+ end
88
98
 
89
- frame
99
+ self.class.frame_cache[[line, type]]
90
100
  end
91
- # rubocop:enable Metrics/MethodLength
101
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
92
102
 
93
103
  def strip_load_path(path)
94
- return nil unless path
104
+ return nil if path.nil?
95
105
 
96
106
  prefix =
97
107
  $LOAD_PATH
98
108
  .map(&:to_s)
99
109
  .select { |s| path.start_with?(s) }
100
- .sort_by(&:length)
101
- .last
102
-
103
- return path unless prefix
110
+ .max_by(&:length)
104
111
 
105
- path[prefix.chomp(File::SEPARATOR).length + 1..-1]
112
+ prefix ? path[prefix.chomp(File::SEPARATOR).length + 1..-1] : path
106
113
  end
107
114
 
108
115
  def context_lines_for(config, type, library_frame:)
@@ -6,7 +6,13 @@ module ElasticAPM
6
6
  DEFAULT_TYPE = 'custom'.freeze
7
7
 
8
8
  # rubocop:disable Metrics/MethodLength
9
- def initialize(instrumenter, name, type = nil, context: nil, sampled: true)
9
+ def initialize(
10
+ instrumenter,
11
+ name = nil,
12
+ type = nil,
13
+ context: nil,
14
+ sampled: true
15
+ )
10
16
  @id = SecureRandom.uuid
11
17
  @instrumenter = instrumenter
12
18
  @name = name
@@ -4,16 +4,21 @@ module ElasticAPM
4
4
  module Util
5
5
  # @api private
6
6
  class LruCache
7
- def initialize(max_size = 512)
7
+ def initialize(max_size = 512, &block)
8
8
  @max_size = max_size
9
- @data = {}
9
+ @data = Hash.new(&block)
10
+ @missing_key_block = block
10
11
  end
11
12
 
12
13
  def [](key)
13
14
  found = true
14
15
  value = @data.delete(key) { found = false }
15
16
 
16
- found ? @data[key] = value : nil
17
+ if found
18
+ @data[key] = value
19
+ else
20
+ @missing_key_block && @missing_key_block.call(self, key)
21
+ end
17
22
  end
18
23
 
19
24
  def []=(key, val)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElasticAPM
4
- VERSION = '0.6.1'.freeze
4
+ VERSION = '0.6.2'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic-apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Malmberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-12 00:00:00.000000000 Z
11
+ date: 2018-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -76,6 +76,7 @@ files:
76
76
  - lib/elastic_apm/injectors/delayed_job.rb
77
77
  - lib/elastic_apm/injectors/elasticsearch.rb
78
78
  - lib/elastic_apm/injectors/json.rb
79
+ - lib/elastic_apm/injectors/mongo.rb
79
80
  - lib/elastic_apm/injectors/net_http.rb
80
81
  - lib/elastic_apm/injectors/redis.rb
81
82
  - lib/elastic_apm/injectors/sequel.rb
@@ -89,6 +90,7 @@ files:
89
90
  - lib/elastic_apm/naively_hashable.rb
90
91
  - lib/elastic_apm/normalizers.rb
91
92
  - lib/elastic_apm/normalizers/action_controller.rb
93
+ - lib/elastic_apm/normalizers/action_mailer.rb
92
94
  - lib/elastic_apm/normalizers/action_view.rb
93
95
  - lib/elastic_apm/normalizers/active_record.rb
94
96
  - lib/elastic_apm/process_info.rb