elastic-apm 1.0.0.beta2 → 1.0.0

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: 21a3aac2c28d8806a3f8703746bc0cfb81620680c4daba5393bc27f88b15b213
4
- data.tar.gz: 18faebc9de42ca039c12d5ce97791c51186d5bdabbf0276078a4906c415741dc
3
+ metadata.gz: 4c8a85fd85634ae33591a952d1a9833d6b2a7e828b36a366c5811f5d9116e901
4
+ data.tar.gz: 1bf462f1c2d14b015a2b52fc3dd510fad3fa642a14eb4b16f1aecca293bd25f7
5
5
  SHA512:
6
- metadata.gz: 7fff60cded68fdac8b9b3dfdd0cbd88a2e7fc91007cfd80c78278281493c152ab0115e4145665e4b6bd3c946f4fd8956e5b4c4036a4bf14a6f7f1dd00024dce0
7
- data.tar.gz: 7d87ef00a486b5bcc7d84f1c98ade6a3eb997f042685f608de3c6421762706ce20309aa8e1b6a9ac3a87b23f7d21a555ef9a5f87270ead7c0bb04290e87ea7d6
6
+ metadata.gz: 530ecf5853ada4749b8c7f0e14a1faa7bd37a5af3221082f3b00bca1f078a8c49e1fa55543f97183709207f5021a946333f8f7ccc91842781602fb1139418781
7
+ data.tar.gz: 57c299275b25b447378a3c73352082f171f75805183ed00f7ac2ba4ad7cbf2fe6a78dc1c5e4627ee40a7241177b8413f190d624e2a3b175a87446e66c68472a3
@@ -3,6 +3,7 @@ AllCops:
3
3
  Exclude:
4
4
  - 'elastic-apm.gemspec'
5
5
  - 'vendor/**/*'
6
+ - 'bench/*'
6
7
 
7
8
  Layout/AlignParameters:
8
9
  EnforcedStyle: with_fixed_indentation
@@ -4,18 +4,20 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## 1.0.0.beta2 (2018-06-21)
7
+ ## 1.0.0 (2018-06-29)
8
8
 
9
9
  ### Added
10
10
 
11
11
  - Added config.disable_send ([#156](https://github.com/elastic/apm-agent-ruby/pulls/156))
12
12
 
13
+ ### Changed
14
+
15
+ - Set the default `span_frame_min_duration` to 5ms
16
+
13
17
  ### Fixed
14
18
 
15
19
  - Fixed some Elasticsearch spans not validating JSON Schema ([#157](https://github.com/elastic/apm-agent-ruby/pulls/157))
16
20
 
17
- ## 1.0.0.beta1 (2018-06-14)
18
-
19
21
  ## 0.8.0 (2018-06-13)
20
22
 
21
23
  ### Added
data/Gemfile CHANGED
@@ -39,3 +39,8 @@ when /.+/
39
39
  else
40
40
  gem framework
41
41
  end
42
+
43
+ group :bench do
44
+ gem 'ruby-prof', platforms: %i[ruby]
45
+ gem 'stackprof', platforms: %i[ruby]
46
+ end
@@ -0,0 +1,2 @@
1
+ tmp/*
2
+ db/*
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
4
+ require 'elastic-apm'
5
+
6
+ class App
7
+ module Helpers
8
+ def with_app(config = {})
9
+ app = App.new(config)
10
+ app.start
11
+ result = yield app
12
+ app.stop
13
+
14
+ result
15
+ end
16
+
17
+ end
18
+
19
+ def initialize(config = {})
20
+ @config = ElasticAPM::Config.new(
21
+ {
22
+ environment: 'bench',
23
+ enabled_environments: ['bench'],
24
+ disable_send: true
25
+ }.merge(config)
26
+ )
27
+ @serializer = ElasticAPM::Serializers::Transactions.new(@config)
28
+ @mock_env = Rack::MockRequest.env_for('/')
29
+ end
30
+
31
+ attr_reader :mock_env, :serializer
32
+
33
+ def start
34
+ @agent = ElasticAPM.start(@config)
35
+ end
36
+
37
+ def stop
38
+ ElasticAPM.stop
39
+ end
40
+ end
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+
6
+ require 'benchmark'
7
+ include Benchmark
8
+
9
+ require 'rack/test'
10
+
11
+ require './bench/app'
12
+ include App::Helpers
13
+
14
+ def perform(app, count: 1000)
15
+ app.start
16
+
17
+ transactions = count.times.map do |i|
18
+ ElasticAPM.transaction "Transaction##{i}",
19
+ context: ElasticAPM.build_context(app.mock_env) do
20
+ ElasticAPM.span('Number one') { 'ok 1' }
21
+ ElasticAPM.span('Number two') { 'ok 2' }
22
+ ElasticAPM.span('Number three') { 'ok 3' }
23
+ end
24
+ end
25
+
26
+ app.serializer.build_all(transactions)
27
+
28
+ app.stop
29
+ end
30
+
31
+ def avg(benchmarks)
32
+ [benchmarks.reduce(Tms.new(0), &:+) / benchmarks.length]
33
+ end
34
+
35
+ def banner(text)
36
+ puts "=== #{text}"
37
+ end
38
+
39
+ def do_bench(transaction_count: 10, **config)
40
+ puts "Count: #{transaction_count} transactions... \n \n"
41
+
42
+ bench = Benchmark.benchmark(CAPTION, 7, FORMAT, 'avg:') do |x|
43
+ benchmarks =
44
+ with_app(config) do |app|
45
+ 10.times.map do |i|
46
+ x.report("run[#{i}]") { perform(app, count: transaction_count) }
47
+ end
48
+ end
49
+
50
+ avg(benchmarks)
51
+ end
52
+ end
53
+
54
+ transaction_count = Integer(ARGV.shift || 10)
55
+
56
+ banner 'Default settings'
57
+ do_bench transaction_count: transaction_count
58
+
59
+ banner 'With transaction_sample_rate = 0'
60
+ do_bench(transaction_count: transaction_count, transaction_sample_rate: 0)
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Encoding.default_external = 'utf-8'
5
+
6
+ require 'time'
7
+ require 'bundler/setup'
8
+ require 'faraday'
9
+ require 'json'
10
+
11
+ ELASTICSEARCH_URL = ENV.fetch('CLOUD_ADDR') { '' }.chomp
12
+ if ELASTICSEARCH_URL == ''
13
+ puts 'ELASTICSEARCH_URL missing, exiting ...'
14
+ exit 1
15
+ end
16
+
17
+ input = STDIN.read.split("\n")
18
+ puts input
19
+
20
+ titles = input.grep(/^===/).map { |t| t.gsub(/^=== /, '') }
21
+ counts = input.grep(/^Count: /).map { |a| a.gsub(/^Count: /, '').to_i }
22
+ averages = input.grep(/^avg/).map { |a| a.match(/\((.+)\)/)[1].to_f }
23
+
24
+ git_sha, git_date, git_msg = `git log -n 1 --pretty="format:%H|||%ai|||%s"`.split('|||')
25
+ platform = Gem::Platform.local
26
+
27
+ payloads = titles.zip(averages, counts).map do |(title, avg, count)|
28
+ {
29
+ title: title,
30
+ avg: avg,
31
+ transaction_count: count,
32
+ executed_at: Time.new.iso8601,
33
+ 'git.commit' => git_sha,
34
+ 'git.date' => Time.parse(git_date).iso8601,
35
+ 'git.subject' => git_msg,
36
+ hostname: `hostname`.chomp,
37
+ engine: RUBY_ENGINE,
38
+ arch: platform.cpu,
39
+ os: platform.os,
40
+ ruby_version: RUBY_VERSION
41
+ }
42
+ end
43
+
44
+ puts '=== Reporting to ES'
45
+
46
+ CONN = Faraday.new(url: ELASTICSEARCH_URL) do |f|
47
+ f.response :logger
48
+ f.adapter Faraday.default_adapter
49
+ end
50
+
51
+ payloads.each do |payload|
52
+ result = CONN.post('/benchmark-ruby/_doc') do |req|
53
+ req.headers['Content-Type'] = 'application/json'
54
+ req.body = payload.to_json
55
+ end
56
+
57
+ puts result.body unless (200...300).include?(result.status)
58
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby-prof'
4
+ require 'rack/test'
5
+
6
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
7
+ require 'elastic-apm'
8
+
9
+ require './bench/app'
10
+ include App::Helpers
11
+
12
+ def perform(app, count: 1000)
13
+ app.start
14
+
15
+ transactions = count.times.map do |i|
16
+ ElasticAPM.transaction "Transaction##{i}",
17
+ context: ElasticAPM.build_context(app.mock_env) do
18
+ ElasticAPM.span('Number one') { 'ok 1' }
19
+ ElasticAPM.span('Number two') { 'ok 2' }
20
+ ElasticAPM.span('Number three') { 'ok 3' }
21
+ end
22
+ end
23
+
24
+ app.stop
25
+ end
26
+
27
+ def do_bench(transaction_count: 1000, **config)
28
+ with_app(config) do |app|
29
+ profile = RubyProf::Profile.new
30
+ profile.exclude_common_methods!
31
+ profile.start
32
+ perform(app, count: transaction_count)
33
+ profile.stop
34
+ printer = RubyProf::GraphHtmlPrinter.new(profile)
35
+ printer.print(File.open('bench/tmp/out.html', 'w'))
36
+ end
37
+ end
38
+
39
+ do_bench(transaction_count: 10_000)
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir.chdir('./bench')
4
+
5
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
6
+
7
+ require 'stackprof'
8
+ require 'rack/test'
9
+ require 'elastic-apm'
10
+
11
+ ElasticAPM.start environment: 'bench', enabled_environments: ['bench']
12
+
13
+ env = Rack::MockRequest.env_for('/')
14
+
15
+ puts 'Running '
16
+ profile = StackProf.run(mode: :cpu) do
17
+ 10_000.times do
18
+ ElasticAPM.transaction 'Name', 'custom',
19
+ context: ElasticAPM.build_context(env) do
20
+ ElasticAPM.span 'Number one' do
21
+ 'ok'
22
+ end
23
+ ElasticAPM.span 'Number two' do
24
+ 'ok'
25
+ end
26
+ ElasticAPM.span 'Number three' do
27
+ 'ok'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ puts ''
33
+
34
+ ElasticAPM.stop
35
+
36
+ StackProf::Report.new(profile).print_text
@@ -286,18 +286,18 @@ storage use in your Elasticsearch cluster.
286
286
 
287
287
  |============
288
288
  | Environment | `Config` key | Default
289
- | `ELASTIC_APM_SPAN_FRAMES_MIN_DURATION` | `span_frames_min_duration` | `-1`
289
+ | `ELASTIC_APM_SPAN_FRAMES_MIN_DURATION` | `span_frames_min_duration` | `5`
290
290
  |============
291
291
 
292
- In its default settings, the APM agent will collect a stack trace with every recorded span.
293
- While this is very helpful to find the exact place in your code that causes the span,
294
- collecting this stack trace does have some overhead.
292
+ Use this to disable stacktrace collection for spans with a duration shorter than or equal to the given amount of milleseconds.
295
293
 
296
- With the default setting, `-1`, stack traces will be collected for all spans.
294
+ The default is 5ms.
295
+
296
+ Set it to `-1` to disable the feature and collect stack traces for all spans.
297
297
  Setting it to a positive value, e.g. `5`, will limit stack trace collection to spans
298
298
  with durations equal or longer than the given value in milliseconds, e.g. 5 milliseconds.
299
299
 
300
- To disable stack trace collection for spans completely, set the value to 0.
300
+ To disable stack trace collection for spans completely, set the value to `0`.
301
301
 
302
302
  [float]
303
303
  [[config-max-queue-size]]
@@ -17,20 +17,18 @@ ElasticAPM includes some nifty helpers if you just want to instrument a regular
17
17
 
18
18
  [source,ruby]
19
19
  ----
20
- class ThingsController < ApplicationController
20
+ class Thing
21
21
  include SpanHelpers
22
22
 
23
- def index
24
- @result = do_hard_work
23
+ def do_the_work
24
+ # ...
25
25
  end
26
+ span_method :do_hard_work # takes optional `name` and `type`
26
27
 
27
- private
28
-
29
- def do_hard_work
28
+ def self.do_all_the_work
30
29
  # ...
31
30
  end
32
-
33
- span_method :do_hard_work # takes optional `name` and `type`
31
+ span_class_method :do_hard_work, 'Custom name', 'custom.work_thing'
34
32
  end
35
33
  ----
36
34
 
@@ -39,7 +39,7 @@ module ElasticAPM
39
39
  source_lines_span_app_frames: 5,
40
40
  source_lines_error_library_frames: 0,
41
41
  source_lines_span_library_frames: 0,
42
- span_frames_min_duration: -1,
42
+ span_frames_min_duration: 5,
43
43
 
44
44
  disabled_spies: %w[json],
45
45
 
@@ -44,7 +44,7 @@ module ElasticAPM # :nodoc:
44
44
  end
45
45
 
46
46
  def for(name)
47
- @normalizers.fetch(name, @default)
47
+ @normalizers.fetch(name) { @default }
48
48
  end
49
49
 
50
50
  def keys
@@ -5,11 +5,11 @@ module ElasticAPM
5
5
  module SpanHelpers
6
6
  # @api private
7
7
  module ClassMethods
8
- def span_class_method(method, name, type)
8
+ def span_class_method(method, name = nil, type = nil)
9
9
  __span_method_on(singleton_class, method, name, type)
10
10
  end
11
11
 
12
- def span_method(method, name, type)
12
+ def span_method(method, name = nil, type = nil)
13
13
  __span_method_on(self, method, name, type)
14
14
  end
15
15
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
3
4
  require 'elastic_apm/util/inflector'
4
5
 
5
6
  module ElasticAPM
@@ -43,7 +43,7 @@ module ElasticAPM
43
43
  type: 'mongodb'.freeze,
44
44
  user: nil
45
45
  )
46
- span = ElasticAPM.span(event.command_name, TYPE, context: ctx)
46
+ span = ElasticAPM.span(event.command_name.to_s, TYPE, context: ctx)
47
47
  @events[event.operation_id] = span
48
48
  end
49
49
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElasticAPM
4
- VERSION = '1.0.0.beta2'.freeze
4
+ VERSION = '1.0.0'.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: 1.0.0.beta2
4
+ version: 1.0.0
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-06-21 00:00:00.000000000 Z
11
+ date: 2018-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -42,6 +42,13 @@ files:
42
42
  - LICENSE
43
43
  - README.md
44
44
  - Rakefile
45
+ - bench/.gitignore
46
+ - bench/app.rb
47
+ - bench/benchmark.rb
48
+ - bench/report.rb
49
+ - bench/rubyprof.rb
50
+ - bench/stackprof.rb
51
+ - bench/tmp/.gitkeep
45
52
  - bin/build_docs
46
53
  - bin/console
47
54
  - bin/setup
@@ -135,9 +142,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
142
  version: 2.2.0
136
143
  required_rubygems_version: !ruby/object:Gem::Requirement
137
144
  requirements:
138
- - - ">"
145
+ - - ">="
139
146
  - !ruby/object:Gem::Version
140
- version: 1.3.1
147
+ version: '0'
141
148
  requirements: []
142
149
  rubyforge_project:
143
150
  rubygems_version: 2.7.6