elastic-apm 2.8.0 → 2.8.1
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -1
- data/Jenkinsfile +5 -1
- data/bench/app.rb +38 -24
- data/bench/benchmark.rb +16 -44
- data/bench/report.rb +42 -33
- data/bench/stackprof.rb +8 -21
- data/docs/configuration.asciidoc +12 -0
- data/docs/debugging.asciidoc +30 -0
- data/docs/index.asciidoc +2 -0
- data/lib/elastic_apm/config.rb +9 -1
- data/lib/elastic_apm/sql_summarizer.rb +2 -2
- data/lib/elastic_apm/transport/serializers/span_serializer.rb +1 -1
- data/lib/elastic_apm/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11b66b86db45e066da0c6055bd5cb58894a5ba0eca8fb9d891b5b918fcd8d7c0
|
4
|
+
data.tar.gz: 87bfdbcc9b57f128f032d8e617dfe4540fcf8afeea91f80621d5e1a6b476d47e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a514f4463ee2294d1e825fd9ba0b42a764d8380e9ea4ba90254acf92ebd7ffec8d4f2a329a77307732e7206a22009c3cb91218650e499235d8ca2cae3cf1d8ae
|
7
|
+
data.tar.gz: 93e558bab35f323f77116031333ce065fa00b101871ea80e913b082612552857dadc9074c6c4219bf97010eddc6b9abc996fa2dac68454aed1dcb91048c9bd6c
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,12 @@ 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
|
+
## 2.8.1 (2019-05-29)
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
|
11
|
+
- Database statements are properly truncated ([#431](https://github.com/elastic/apm-agent-ruby/pull/431))
|
12
|
+
|
7
13
|
## 2.8.0 (2019-05-20)
|
8
14
|
|
9
15
|
### Added
|
data/Gemfile
CHANGED
@@ -6,7 +6,6 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
6
|
|
7
7
|
gemspec
|
8
8
|
|
9
|
-
gem 'pry'
|
10
9
|
gem 'rack-test'
|
11
10
|
gem 'rspec'
|
12
11
|
gem 'rspec-its'
|
@@ -16,6 +15,7 @@ gem 'webmock'
|
|
16
15
|
|
17
16
|
gem 'elasticsearch', require: nil
|
18
17
|
gem 'fakeredis', require: nil
|
18
|
+
gem 'faraday', require: nil
|
19
19
|
gem 'json-schema', require: nil
|
20
20
|
gem 'mongo', require: nil
|
21
21
|
gem 'opentracing', require: nil
|
@@ -45,6 +45,8 @@ else
|
|
45
45
|
gem framework
|
46
46
|
end
|
47
47
|
|
48
|
+
gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
|
49
|
+
|
48
50
|
unless version =~ /^(master|6)/
|
49
51
|
gem 'delayed_job', require: nil
|
50
52
|
end
|
data/Jenkinsfile
CHANGED
@@ -32,7 +32,7 @@ pipeline {
|
|
32
32
|
quietPeriod(10)
|
33
33
|
}
|
34
34
|
triggers {
|
35
|
-
issueCommentTrigger('.*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
|
35
|
+
issueCommentTrigger('(?i).*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
|
36
36
|
}
|
37
37
|
parameters {
|
38
38
|
booleanParam(name: 'Run_As_Master_Branch', defaultValue: false, description: 'Allow to run any steps on a PR, some steps normally only run on master branch.')
|
@@ -266,6 +266,10 @@ def runBenchmark(version){
|
|
266
266
|
} catch(e){
|
267
267
|
throw e
|
268
268
|
} finally {
|
269
|
+
archiveArtifacts(
|
270
|
+
allowEmptyArchive: true,
|
271
|
+
artifacts: "**/benchmark-${transformedVersion}.raw,**/benchmark-${transformedVersion}.error",
|
272
|
+
onlyIfSuccessful: false)
|
269
273
|
sendBenchmarks(file: "benchmark-${transformedVersion}.bulk",
|
270
274
|
index: "benchmark-ruby", archive: true)
|
271
275
|
}
|
data/bench/app.rb
CHANGED
@@ -1,39 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
5
|
+
require 'active_record'
|
6
|
+
require 'action_controller/railtie'
|
4
7
|
require 'elastic-apm'
|
8
|
+
require 'elastic_apm/railtie'
|
5
9
|
|
6
|
-
|
7
|
-
module Helpers
|
8
|
-
def with_app(config = {})
|
9
|
-
app = App.new(config)
|
10
|
-
app.start
|
11
|
-
result = yield app
|
12
|
-
app.stop
|
10
|
+
$log = Logger.new('/tmp/bench.log')
|
13
11
|
|
14
|
-
|
15
|
-
end
|
12
|
+
ActiveRecord::Base.logger = $log
|
16
13
|
|
17
|
-
|
14
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: '/tmp/bench.sqlite3')
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
disable_send: true
|
24
|
-
}.merge(config)
|
25
|
-
)
|
26
|
-
# @serializer = ElasticAPM::Serializers::Transactions.new(@config)
|
27
|
-
@mock_env = Rack::MockRequest.env_for('/')
|
16
|
+
ActiveRecord::Schema.define do
|
17
|
+
create_table :posts, force: true do |t|
|
18
|
+
t.string :title
|
19
|
+
t.timestamps
|
28
20
|
end
|
21
|
+
end
|
29
22
|
|
30
|
-
|
23
|
+
class Post < ActiveRecord::Base
|
24
|
+
end
|
31
25
|
|
32
|
-
|
33
|
-
|
26
|
+
10.times { |i| Post.create! title: "Post #{i}" }
|
27
|
+
|
28
|
+
class ApplicationController < ActionController::Base
|
29
|
+
def index
|
30
|
+
render inline: '<%= Post.pluck(:title).join(", ") %>'
|
34
31
|
end
|
35
32
|
|
36
|
-
def
|
37
|
-
|
33
|
+
def favicon
|
34
|
+
render nothing: true
|
38
35
|
end
|
39
36
|
end
|
37
|
+
|
38
|
+
class App < Rails::Application
|
39
|
+
config.secret_key_base = '__secret'
|
40
|
+
config.logger = $log
|
41
|
+
config.eager_load = false
|
42
|
+
|
43
|
+
config.elastic_apm.disable_send = true
|
44
|
+
config.elastic_apm.logger = $log
|
45
|
+
config.elastic_apm.log_level = Logger::DEBUG
|
46
|
+
end
|
47
|
+
|
48
|
+
App.initialize!
|
49
|
+
|
50
|
+
App.routes.draw do
|
51
|
+
get '/favicon.ico', to: 'application#favicon'
|
52
|
+
root to: 'application#index'
|
53
|
+
end
|
data/bench/benchmark.rb
CHANGED
@@ -1,64 +1,36 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
ENV['RAILS_ENV'] = 'production'
|
5
|
+
|
6
|
+
require 'bundler'
|
4
7
|
require 'bundler/setup'
|
5
8
|
|
6
9
|
require 'benchmark'
|
7
10
|
include Benchmark
|
8
|
-
|
9
11
|
require 'rack/test'
|
10
12
|
|
11
13
|
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
14
|
|
28
|
-
|
15
|
+
def app
|
16
|
+
App
|
29
17
|
end
|
30
18
|
|
31
|
-
|
32
|
-
[benchmarks.reduce(Tms.new(0), &:+) / benchmarks.length]
|
33
|
-
end
|
19
|
+
include Rack::Test::Methods
|
34
20
|
|
35
|
-
def
|
36
|
-
|
21
|
+
def perform
|
22
|
+
10_000.times do
|
23
|
+
get '/'
|
24
|
+
end
|
37
25
|
end
|
38
26
|
|
39
|
-
|
40
|
-
|
27
|
+
bench = Benchmark.benchmark(CAPTION, 15, FORMAT) do |b|
|
28
|
+
perform # warm up
|
41
29
|
|
42
|
-
|
43
|
-
benchmarks =
|
44
|
-
with_app(config) do |app|
|
45
|
-
# warm-up
|
46
|
-
puts "1 run of warm-up"
|
47
|
-
perform(app, count: transaction_count)
|
30
|
+
b.report('with agent:') { perform }
|
48
31
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
32
|
+
ElasticAPM.stop
|
33
|
+
perform # warm up
|
53
34
|
|
54
|
-
|
55
|
-
end
|
35
|
+
b.report('without agent:') { perform }
|
56
36
|
end
|
57
|
-
|
58
|
-
transaction_count = Integer(ARGV.shift || 100_000)
|
59
|
-
|
60
|
-
banner 'Default settings'
|
61
|
-
do_bench transaction_count: transaction_count
|
62
|
-
|
63
|
-
banner 'With transaction_sample_rate = 0'
|
64
|
-
do_bench(transaction_count: transaction_count, transaction_sample_rate: 0)
|
data/bench/report.rb
CHANGED
@@ -1,46 +1,55 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
Encoding.default_external = 'utf-8'
|
5
|
-
|
6
4
|
require 'time'
|
7
|
-
require 'bundler/setup'
|
8
5
|
require 'json'
|
9
6
|
|
10
7
|
input = STDIN.read.split("\n")
|
11
|
-
STDERR.puts input
|
12
|
-
|
13
|
-
titles = input.grep(/^===/).map { |t| t.gsub(/^=== /, '') }
|
14
|
-
counts = input.grep(/^Count: /).map { |a| a.gsub(/^Count: /, '').to_i }
|
15
|
-
averages = input.grep(/^avg/).map { |a| a.match(/\((.+)\)/)[1].to_f }
|
16
8
|
|
17
9
|
git_sha, git_msg = `git log -n 1 --pretty="format:%H|||%s"`.split('|||')
|
18
10
|
git_date = `git log -n 1 --pretty="format:%ai"`
|
19
11
|
platform = Gem::Platform.local
|
20
12
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
{
|
25
|
-
title: title,
|
26
|
-
avg: avg,
|
27
|
-
transaction_count: count,
|
28
|
-
executed_at: Time.new.iso8601,
|
29
|
-
'git.commit' => git_sha,
|
30
|
-
'git.date' => String(git_date).strip != '' && Time.parse(git_date).iso8601,
|
31
|
-
'git.subject' => git_msg,
|
32
|
-
hostname: `hostname`.chomp,
|
33
|
-
engine: RUBY_ENGINE,
|
34
|
-
arch: platform.cpu,
|
35
|
-
os: platform.os,
|
36
|
-
ruby_version: "#{RUBY_ENGINE == 'jruby' ? 'j' : ''}#{RUBY_VERSION}"
|
37
|
-
}
|
38
|
-
end.compact
|
39
|
-
|
40
|
-
STDERR.puts '=== Reporting to ES'
|
41
|
-
STDERR.puts payloads.inspect
|
42
|
-
|
43
|
-
payloads.each do |payload|
|
44
|
-
puts '{ "index" : { "_index" : "benchmark-ruby", "_type" : "_doc" } }'
|
45
|
-
puts payload.to_json
|
13
|
+
def doc(payload)
|
14
|
+
puts({ index: { _index: "benchmark-ruby", _type: "_doc" } }.to_json)
|
15
|
+
puts(payload.to_json)
|
46
16
|
end
|
17
|
+
|
18
|
+
meta = {
|
19
|
+
executed_at: Time.new.iso8601,
|
20
|
+
'git.commit' => git_sha,
|
21
|
+
'git.date' => String(git_date).strip != '' && Time.parse(git_date).iso8601,
|
22
|
+
'git.subject' => git_msg,
|
23
|
+
hostname: `hostname`.chomp,
|
24
|
+
engine: RUBY_ENGINE,
|
25
|
+
arch: platform.cpu,
|
26
|
+
os: platform.os,
|
27
|
+
ruby_version: "#{RUBY_ENGINE == 'jruby' ? 'j' : ''}#{RUBY_VERSION}"
|
28
|
+
}
|
29
|
+
|
30
|
+
results =
|
31
|
+
input
|
32
|
+
.grep(/^with/)
|
33
|
+
.map do |line|
|
34
|
+
title = line.match(/^(.*):/) { |m| m[1] }
|
35
|
+
user, system, total, real = line.scan(/[0-9\.]+/).map(&:to_f)
|
36
|
+
meta.merge(
|
37
|
+
title: title,
|
38
|
+
user: user,
|
39
|
+
system: system,
|
40
|
+
total: total,
|
41
|
+
real: real,
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
results.each { |result| doc result }
|
46
|
+
|
47
|
+
overhead =
|
48
|
+
(results[0][:total] - results[1][:total]) *
|
49
|
+
1000 / # milliseconds
|
50
|
+
10_000 # transactions
|
51
|
+
|
52
|
+
doc meta.merge(
|
53
|
+
title: 'overhead',
|
54
|
+
overhead: overhead
|
55
|
+
)
|
data/bench/stackprof.rb
CHANGED
@@ -1,36 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
Dir.chdir('./bench')
|
4
|
-
|
5
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
6
|
-
|
7
4
|
require 'stackprof'
|
8
5
|
require 'rack/test'
|
9
|
-
require 'elastic-apm'
|
10
6
|
|
11
|
-
|
7
|
+
require './bench/app'
|
12
8
|
|
13
|
-
|
9
|
+
def app
|
10
|
+
App
|
11
|
+
end
|
12
|
+
|
13
|
+
include Rack::Test::Methods
|
14
14
|
|
15
15
|
puts 'Running '
|
16
16
|
profile = StackProf.run(mode: :cpu) do
|
17
17
|
10_000.times do
|
18
|
-
|
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
|
18
|
+
get '/'
|
30
19
|
end
|
31
20
|
end
|
32
21
|
puts ''
|
33
22
|
|
34
|
-
ElasticAPM.stop
|
35
|
-
|
36
23
|
StackProf::Report.new(profile).print_text
|
data/docs/configuration.asciidoc
CHANGED
@@ -579,6 +579,18 @@ It has to be provided in *<<config-format-duration, duration format>>*.
|
|
579
579
|
|
580
580
|
The path to a custom CA certificate for connecting to APM Server.
|
581
581
|
|
582
|
+
[float]
|
583
|
+
[[config-stack-trace-limit]]
|
584
|
+
==== `stack_trace_limit`
|
585
|
+
|
586
|
+
[options="header"]
|
587
|
+
|============
|
588
|
+
| Environment | `Config` key | Default
|
589
|
+
| `ELASTIC_APM_STACK_TRACE_LIMIT` | `stack_trace_limit` | `999999`
|
590
|
+
|============
|
591
|
+
|
592
|
+
The maximum number of stack trace lines per span/error.
|
593
|
+
|
582
594
|
[float]
|
583
595
|
[[config-transaction-max-spans]]
|
584
596
|
==== `transaction_max_spans`
|
@@ -0,0 +1,30 @@
|
|
1
|
+
[[debugging]]
|
2
|
+
== Debugging the agent itself
|
3
|
+
|
4
|
+
Hopefully the agent Just Works™, but depending on your situation the agent might need some tuning.
|
5
|
+
|
6
|
+
First, to learn more about what's going on inside the agent, you can increase the amount of log messages it writes. To do this, set the log level with the option `log_level = 0` -- `0` being the level of most messages, `DEBUG`.
|
7
|
+
|
8
|
+
In your `config/elastic_apm.yml`:
|
9
|
+
|
10
|
+
[source,yaml]
|
11
|
+
----
|
12
|
+
log_level: <%= Logger::DEBUG %>
|
13
|
+
----
|
14
|
+
|
15
|
+
[float]
|
16
|
+
[[debugging-log-messages]]
|
17
|
+
=== Log messages
|
18
|
+
|
19
|
+
[float]
|
20
|
+
[[debugging-errors-queue-full]]
|
21
|
+
==== `Queue is full (256 items), skipping…`
|
22
|
+
|
23
|
+
The agent has an internal queue that holds events after they are done, and before they are safely serialized and sent to APM Server. To avoid using up all of your memory, this queue has a fixed size. Depending on your load and server setup, events may be added to the queue faster than they are consumed, hence the warning.
|
24
|
+
|
25
|
+
Things to consider:
|
26
|
+
|
27
|
+
- Is `server_url` misconfigured or APM Server down? If the agent fails to connect you will also see log messages containing `Connection error` or `Couldn't establish connection to APM Server`.
|
28
|
+
- Experiencing high load? The agent can spawn multiple instances of its Workers that pick off the queue by changing the option `pool_size` (default is `1`).
|
29
|
+
- If you have high load you may also consider setting `transaction_sample_rate` to something smaller than `1.0`. This determines whether to include _spans_ for every _transaction_. If you have enough traffic, skipping some (probably) identical spans won't have a noticeable effect on your data.
|
30
|
+
|
data/docs/index.asciidoc
CHANGED
data/lib/elastic_apm/config.rb
CHANGED
@@ -403,7 +403,7 @@ module ElasticAPM
|
|
403
403
|
end
|
404
404
|
|
405
405
|
def set_rails(app) # rubocop:disable Metrics/AbcSize
|
406
|
-
self.service_name ||= format_name(service_name || app
|
406
|
+
self.service_name ||= format_name(service_name || rails_app_name(app))
|
407
407
|
self.framework_name ||= 'Ruby on Rails'
|
408
408
|
self.framework_version ||= Rails::VERSION::STRING
|
409
409
|
self.logger ||= Rails.logger
|
@@ -412,6 +412,14 @@ module ElasticAPM
|
|
412
412
|
self.view_paths = app.config.paths['app/views'].existent
|
413
413
|
end
|
414
414
|
|
415
|
+
def rails_app_name(app)
|
416
|
+
if Rails::VERSION::MAJOR >= 6
|
417
|
+
app.class.module_parent_name
|
418
|
+
else
|
419
|
+
app.class.parent_name
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
415
423
|
def build_logger
|
416
424
|
logger = Logger.new(log_path == '-' ? STDOUT : log_path)
|
417
425
|
logger.level = log_level
|
@@ -6,7 +6,7 @@ module ElasticAPM
|
|
6
6
|
# @api private
|
7
7
|
class SqlSummarizer
|
8
8
|
DEFAULT = 'SQL'
|
9
|
-
TABLE_REGEX = %{["'`]?([A-Za-z0-9_]+)}
|
9
|
+
TABLE_REGEX = %{["'`]?([A-Za-z0-9_]+)["'`]?}
|
10
10
|
|
11
11
|
REGEXES = {
|
12
12
|
/^BEGIN/i => 'BEGIN',
|
@@ -26,7 +26,7 @@ module ElasticAPM
|
|
26
26
|
def summarize(sql)
|
27
27
|
self.class.cache[sql] ||=
|
28
28
|
REGEXES.find do |regex, sig|
|
29
|
-
if (match = sql.match(regex))
|
29
|
+
if (match = sql[0...1000].match(regex))
|
30
30
|
break format(FORMAT, sig, match[1] && match[1].gsub(/["']/, ''))
|
31
31
|
end
|
32
32
|
end || DEFAULT
|
data/lib/elastic_apm/version.rb
CHANGED
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: 2.8.
|
4
|
+
version: 2.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikkel Malmberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- docs/configuration.asciidoc
|
74
74
|
- docs/context.asciidoc
|
75
75
|
- docs/custom-instrumentation.asciidoc
|
76
|
+
- docs/debugging.asciidoc
|
76
77
|
- docs/getting-started-rack.asciidoc
|
77
78
|
- docs/getting-started-rails.asciidoc
|
78
79
|
- docs/index.asciidoc
|