elastic-apm 0.6.1 → 0.6.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.

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