elastic-apm 1.0.0.beta2 → 1.0.0

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: 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