elastic-apm 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/.jenkins_exclude.yml +4 -4
  3. data/.ci/.jenkins_ruby.yml +1 -1
  4. data/.ci/Jenkinsfile +5 -3
  5. data/.ci/jobs/apm-agent-ruby-downstream.yml +1 -0
  6. data/.ci/jobs/apm-agent-ruby-linting-mbp.yml +1 -0
  7. data/.ci/jobs/apm-agent-ruby-mbp.yml +1 -0
  8. data/.ci/prepare-git-context.sh +5 -2
  9. data/.github/ISSUE_TEMPLATE/Bug_report.md +38 -0
  10. data/.github/ISSUE_TEMPLATE/Feature_request.md +17 -0
  11. data/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  12. data/.gitignore +3 -0
  13. data/.rubocop.yml +6 -0
  14. data/CHANGELOG.asciidoc +25 -1
  15. data/Gemfile +6 -2
  16. data/bench/sql.rb +49 -0
  17. data/bin/build_docs +1 -1
  18. data/codecov.yml +32 -0
  19. data/docs/api.asciidoc +37 -0
  20. data/docs/configuration.asciidoc +18 -1
  21. data/docs/supported-technologies.asciidoc +20 -1
  22. data/lib/elastic_apm.rb +29 -5
  23. data/lib/elastic_apm/agent.rb +6 -2
  24. data/lib/elastic_apm/child_durations.rb +9 -4
  25. data/lib/elastic_apm/config.rb +8 -1
  26. data/lib/elastic_apm/config/options.rb +3 -4
  27. data/lib/elastic_apm/context/response.rb +10 -2
  28. data/lib/elastic_apm/instrumenter.rb +20 -11
  29. data/lib/elastic_apm/normalizers/rails/active_record.rb +12 -5
  30. data/lib/elastic_apm/rails.rb +1 -10
  31. data/lib/elastic_apm/railtie.rb +1 -1
  32. data/lib/elastic_apm/span.rb +3 -2
  33. data/lib/elastic_apm/span/context.rb +26 -44
  34. data/lib/elastic_apm/span/context/db.rb +19 -0
  35. data/lib/elastic_apm/span/context/destination.rb +44 -0
  36. data/lib/elastic_apm/span/context/http.rb +26 -0
  37. data/lib/elastic_apm/spies/elasticsearch.rb +18 -5
  38. data/lib/elastic_apm/spies/faraday.rb +36 -18
  39. data/lib/elastic_apm/spies/http.rb +16 -2
  40. data/lib/elastic_apm/spies/mongo.rb +5 -0
  41. data/lib/elastic_apm/spies/net_http.rb +27 -7
  42. data/lib/elastic_apm/spies/sequel.rb +25 -15
  43. data/lib/elastic_apm/spies/shoryuken.rb +48 -0
  44. data/lib/elastic_apm/spies/sneakers.rb +57 -0
  45. data/lib/elastic_apm/sql.rb +19 -0
  46. data/lib/elastic_apm/sql/signature.rb +152 -0
  47. data/lib/elastic_apm/sql/tokenizer.rb +247 -0
  48. data/lib/elastic_apm/sql/tokens.rb +46 -0
  49. data/lib/elastic_apm/sql_summarizer.rb +1 -2
  50. data/lib/elastic_apm/transaction.rb +11 -11
  51. data/lib/elastic_apm/transport/connection/proxy_pipe.rb +2 -2
  52. data/lib/elastic_apm/transport/headers.rb +4 -0
  53. data/lib/elastic_apm/transport/serializers/span_serializer.rb +24 -7
  54. data/lib/elastic_apm/version.rb +1 -1
  55. metadata +16 -3
  56. data/.github/workflows/main.yml +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aaf3f0eada3b3bfe036dc55802688666e3df0ee48848b45dd73aa6861e625dc6
4
- data.tar.gz: feb50b6f3d2da29af6591f31a62ea95189ab64868fb5403e3d85ceec548868d8
3
+ metadata.gz: 37a020cb4be0022f87d148e568cb6c755bb7464c401141d3f9de743b4f960132
4
+ data.tar.gz: e7d34598029f879e51e25b88fa1e23048290e51a21a664818f50b8c3b29bbc34
5
5
  SHA512:
6
- metadata.gz: b7bcd197586b7782f25fa814ec0430c33f7b21abaa6b79c81fe93ee07654df1448eea4257f8c29b6f6dce1b7778c0b88f6e825a1338bdba591fd4934b9bcaa09
7
- data.tar.gz: 181bf8aa045473ef55cb794199638722e1bd7f142e558077928a94e03ca75812d21633c6781e734d7029b12e9b4d54232498f604a6be26f70daaffcd1e91f03e
6
+ metadata.gz: 0f604ede3b49fc35a5560e28841e5d7bcb6c209f3a9c064dbfcfed0db158e75d501dbaec057d148f5254f6077a73de81ae5134ea4001995b614a547edfcb47aa
7
+ data.tar.gz: 6f2911e3d564ba2967bf4f3ae583b105c4f56a03014ef47ccfc65dd1ff05d9b6b43530044ed8abff694e38b27db431b50f94d5b0bf69448f52b4b4f29d42fa6a
@@ -1,5 +1,5 @@
1
1
  exclude:
2
- - RUBY_VERSION: ruby:2.7-rc
2
+ - RUBY_VERSION: ruby:2.7
3
3
  FRAMEWORK: rails-4.2
4
4
  - RUBY_VERSION: jruby:9.2
5
5
  FRAMEWORK: rails-4.2
@@ -26,7 +26,7 @@ exclude:
26
26
  FRAMEWORK: rails-6.0
27
27
 
28
28
  # Only test master on newest ruby
29
- - RUBY_VERSION: ruby:2.7-rc
29
+ - RUBY_VERSION: ruby:2.6
30
30
  FRAMEWORK: rails-master
31
31
  - RUBY_VERSION: ruby:2.5
32
32
  FRAMEWORK: rails-master
@@ -70,7 +70,7 @@ exclude:
70
70
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
71
71
  FRAMEWORK: sinatra-master
72
72
 
73
- - RUBY_VERSION: ruby:2.7-rc
73
+ - RUBY_VERSION: ruby:2.6
74
74
  FRAMEWORK: grape-master
75
75
  - RUBY_VERSION: ruby:2.5
76
76
  FRAMEWORK: grape-master
@@ -93,7 +93,7 @@ exclude:
93
93
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
94
94
  FRAMEWORK: grape-master
95
95
 
96
- - RUBY_VERSION: ruby:2.7-rc
96
+ - RUBY_VERSION: ruby:2.6
97
97
  FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
98
98
  - RUBY_VERSION: ruby:2.5
99
99
  FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
@@ -1,5 +1,5 @@
1
1
  RUBY_VERSION:
2
- - ruby:2.7-rc
2
+ - ruby:2.7
3
3
  - ruby:2.6
4
4
  - ruby:2.5
5
5
  - ruby:2.4
@@ -24,6 +24,7 @@ pipeline {
24
24
  ITS_PIPELINE = 'apm-integration-tests-selector-mbp/master'
25
25
  RELEASE_SECRET = 'secret/apm-team/ci/apm-agent-ruby-rubygems-release'
26
26
  OPBEANS_REPO = 'opbeans-ruby'
27
+ REFERENCE_REPO = '/var/lib/jenkins/.git-references/apm-agent-ruby.git'
27
28
  }
28
29
  options {
29
30
  timeout(time: 2, unit: 'HOURS')
@@ -51,7 +52,7 @@ pipeline {
51
52
  steps {
52
53
  pipelineManager([ cancelPreviousRunningBuilds: [ when: 'PR' ] ])
53
54
  deleteDir()
54
- gitCheckout(basedir: "${BASE_DIR}", githubNotifyFirstTimeContributor: true)
55
+ gitCheckout(basedir: "${BASE_DIR}", githubNotifyFirstTimeContributor: true, reference: "${env.REFERENCE_REPO}")
55
56
  stash allowEmpty: true, name: 'source', useDefaultExcludes: false
56
57
  }
57
58
  }
@@ -203,7 +204,7 @@ pipeline {
203
204
  unstash 'source'
204
205
  script {
205
206
  dir(BASE_DIR){
206
- docker.image("${env.RUBY_DOCKER_TAG}").inside('-v /etc/passwd:/etc/passwd -v ${HOME}/.ssh:${HOME}/.ssh') {
207
+ docker.image("${env.RUBY_DOCKER_TAG}").inside('-v ${REFERENCE_REPO}:${REFERENCE_REPO} -v /etc/passwd:/etc/passwd -v ${HOME}/.ssh:${HOME}/.ssh') {
207
208
  withEnv(["HOME=${env.WORKSPACE}/${env.BASE_DIR ?: ''}"]) {
208
209
  rubygemsLogin.withApi(secret: "${env.RELEASE_SECRET}") {
209
210
  sshagent(['f6c7695a-671e-4f4f-a331-acdce44ff9ba']) {
@@ -228,7 +229,8 @@ pipeline {
228
229
  dir("${OPBEANS_REPO}"){
229
230
  git credentialsId: 'f6c7695a-671e-4f4f-a331-acdce44ff9ba',
230
231
  url: "git@github.com:elastic/${OPBEANS_REPO}.git"
231
- sh script: ".ci/bump-version.sh ${env.BRANCH_NAME}", label: 'Bump version'
232
+ // It's required to transform the tag value to the gem version
233
+ sh script: ".ci/bump-version.sh ${env.BRANCH_NAME.replaceAll('^v', '')}", label: 'Bump version'
232
234
  // The opbeans pipeline will trigger a release for the master branch
233
235
  gitPush()
234
236
  // The opbeans pipeline will trigger a release for the release tag
@@ -32,6 +32,7 @@
32
32
  recursive: true
33
33
  parent-credentials: true
34
34
  timeout: 100
35
+ reference-repo: /var/lib/jenkins/.git-references/apm-agent-ruby.git
35
36
  timeout: '15'
36
37
  use-author: true
37
38
  wipe-workspace: 'True'
@@ -33,6 +33,7 @@
33
33
  recursive: true
34
34
  parent-credentials: true
35
35
  timeout: 100
36
+ reference-repo: /var/lib/jenkins/.git-references/apm-agent-ruby.git
36
37
  timeout: '15'
37
38
  use-author: true
38
39
  wipe-workspace: 'True'
@@ -36,6 +36,7 @@
36
36
  recursive: true
37
37
  parent-credentials: true
38
38
  timeout: 100
39
+ reference-repo: /var/lib/jenkins/.git-references/apm-agent-ruby.git
39
40
  timeout: '15'
40
41
  use-author: true
41
42
  wipe-workspace: 'True'
@@ -10,14 +10,17 @@ git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
10
10
  # Force the git user details when pushing using the last commit details
11
11
  USER_MAIL=$(git log -1 --pretty=format:'%ae')
12
12
  USER_NAME=$(git log -1 --pretty=format:'%an')
13
- git config --global user.email "${USER_MAIL}"
14
- git config --global user.name "${USER_NAME}"
13
+ git config user.email "${USER_MAIL}"
14
+ git config user.name "${USER_NAME}"
15
15
 
16
16
  # Checkout the branch as it's detached based by default.
17
17
  # See https://issues.jenkins-ci.org/browse/JENKINS-33171
18
18
  git fetch --all
19
19
  git checkout "${BRANCH_NAME}"
20
20
 
21
+ # Checkout the master branch to be able to rebase the *.x branch
22
+ git checkout master
23
+
21
24
  # Ensure the master branch points to the original commit to avoid commit injection
22
25
  # when running the release pipeline.
23
26
  # used GIT_BASE_COMMIT instead GIT_COMMIT to support the MultiBranchPipelines.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+
5
+ ---
6
+
7
+ **Describe the bug**: ...
8
+
9
+ **To Reproduce**
10
+
11
+ 1. ...
12
+ 2. ...
13
+ 3. ...
14
+ 4. ...
15
+
16
+ **Expected behavior**: ...
17
+
18
+ **Environment (please complete the following information)**
19
+ - OS: [e.g. Linux]
20
+ - Ruby version:
21
+ - Framework and version [e.g. Rails 6.0.1]:
22
+ - APM Server version:
23
+ - Agent version:
24
+
25
+
26
+ **Additional context**
27
+
28
+ Add any other context about the problem here.
29
+
30
+ - Agent config options <!-- be careful not to post sensitive information -->
31
+ <details>
32
+ <summary>Click to expand</summary>
33
+
34
+ ```
35
+ replace this line with your agent config options
36
+ remember to mask any sensitive fields like tokens
37
+ ```
38
+ </details>
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+
5
+ ---
6
+
7
+ **Is your feature request related to a problem? Please describe.**
8
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9
+
10
+ **Describe the solution you'd like**
11
+ A clear and concise description of what you want to happen.
12
+
13
+ **Describe alternatives you've considered**
14
+ A clear and concise description of any alternative solutions or features you've considered.
15
+
16
+ **Additional context**
17
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,14 @@
1
+ ## What does this pull request do?
2
+
3
+ <!-- Comment:
4
+ Here you can explain the changes made on the PR.
5
+ -->
6
+
7
+ ## Why is it important?
8
+
9
+ <!-- Comment:
10
+ Here you can explains how this change will impact the funcionality of the agent
11
+ -->
12
+
13
+ ## Related issues
14
+ closes #ISSUE
data/.gitignore CHANGED
@@ -17,3 +17,6 @@ spec/junit-reports
17
17
  .gem
18
18
  *.bulk
19
19
  vendor/
20
+
21
+ .idea/
22
+ log/
@@ -44,6 +44,9 @@ Metrics/ModuleLength:
44
44
  Metrics/BlockLength:
45
45
  Enabled: false
46
46
 
47
+ Metrics/BlockNesting:
48
+ Enabled: false
49
+
47
50
  Metrics/MethodLength:
48
51
  Enabled: false
49
52
 
@@ -92,3 +95,6 @@ Style/SpecialGlobalVars:
92
95
 
93
96
  Style/MissingRespondToMissing:
94
97
  Enabled: false
98
+
99
+ Style/BracesAroundHashParameters:
100
+ Enabled: false
@@ -35,8 +35,32 @@ endif::[]
35
35
  [[release-notes-3.x]]
36
36
  === Ruby Agent version 3.x
37
37
 
38
+ [[release-notes-3.4.0]]
39
+ ==== 3.4.0 (2020-01-10)
40
+
41
+ [float]
42
+ ===== Added
43
+
44
+ - Add `span.context.destination` fields {pull}647[#647]
45
+ - Add more precise (experimental) SQL summarizer {pull}640[#640]
46
+ - Add support for Shoryuken (AWS SQS) {pull}674[#674]
47
+ - Add support for Sneakers (Experimental) {pull}676[#676]
48
+ - Add option `api_key` to specify an Api key to use with the apm server {pull}655[#655]
49
+
50
+ [float]
51
+ ===== Changed
52
+
53
+ - Allow action dispatch spy to be disabled via `disabled_instrumentations` {pull}657[#657]
54
+
55
+ [float]
56
+ ===== Fixed
57
+
58
+ - Fix Rails Console detection when top-level `Console` constant defined {pull}664[#664]
59
+ - Fix Ruby 2.7 related deprecation warnings {pull}667[#667]
60
+ - Fix HTTP response header values not being converted to strings {pull}675[#675]
61
+
38
62
  [[release-notes-3.3.0]]
39
- ==== 3.2.0 (2019-12-05)
63
+ ==== 3.3.0 (2019-12-05)
40
64
 
41
65
  [float]
42
66
  ===== Added
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  # Tools
8
8
  gem 'bootsnap', require: false
9
+ gem 'cucumber', require: false
9
10
  gem 'pry'
10
11
  gem 'rack-test'
11
12
  gem 'rspec', '~> 3'
@@ -16,6 +17,7 @@ gem 'timecop'
16
17
  gem 'webmock'
17
18
 
18
19
  # Integrations
20
+ gem 'aws-sdk-sqs', require: nil
19
21
  gem 'elasticsearch', require: nil
20
22
  gem 'fakeredis', require: nil
21
23
  gem 'faraday', require: nil
@@ -24,9 +26,11 @@ gem 'mongo', require: nil
24
26
  gem 'opentracing', require: nil
25
27
  gem 'rake', require: nil
26
28
  gem 'sequel', require: nil
29
+ gem 'shoryuken', require: nil
27
30
  gem 'sidekiq', require: nil
28
- gem 'simplecov', require: false, group: :test
29
- gem 'simplecov-cobertura', require: false, group: :test
31
+ gem 'sneakers', '~> 2.12', require: nil
32
+ gem 'simplecov', require: false
33
+ gem 'simplecov-cobertura', require: false
30
34
  gem 'yard', require: nil
31
35
  gem 'yarjuf'
32
36
 
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
+
6
+ require 'json'
7
+ require 'benchmark'
8
+ include Benchmark # rubocop:disable Style/MixinUsage
9
+
10
+ require 'elastic_apm/sql_summarizer'
11
+ require 'elastic_apm/sql/signature'
12
+
13
+ examples =
14
+ JSON
15
+ .parse(File.read('../apm/tests/random_sql_query_set.json'))
16
+ .map { |ex| ex['input'] }
17
+
18
+ puts "#{'=' * 14} Parsing #{examples.length} examples #{'=' * 14}"
19
+
20
+ summarizer = ElasticAPM::SqlSummarizer.new
21
+
22
+ result_old = nil
23
+ result_new = nil
24
+
25
+ benchmark(CAPTION, 7, FORMAT, 'avg/ex:') do |bm|
26
+ old = bm.report('old:') do
27
+ result_old = examples.map { |i| summarizer.summarize(i) }
28
+ end
29
+ new = bm.report('new:') do
30
+ result_new = examples.map { |i| ElasticAPM::Sql::Signature.parse(i) }
31
+ end
32
+
33
+ [(new - old) / examples.length]
34
+ end
35
+
36
+ pp(result_old.count { |res| res == 'SQL' })
37
+ pp(result_new.count { |res| res =~ /(--|\/\*\*)/ })
38
+
39
+ ## Stackprof
40
+
41
+ require 'stackprof'
42
+
43
+ puts 'Running stackprof'
44
+ profile = StackProf.run(mode: :wall, interval: 1) do
45
+ examples.each { |i| ElasticAPM::Sql::Signature.parse(i) }
46
+ end
47
+ puts ''
48
+
49
+ StackProf::Report.new(profile).print_text
@@ -2,4 +2,4 @@
2
2
  set -ex
3
3
 
4
4
  # Requires elastic/docs to be checked out at ../docs
5
- ../docs/build_docs.pl --doc docs/index.asciidoc --chunk 1
5
+ ../docs/build_docs --doc docs/index.asciidoc --chunk 1
@@ -0,0 +1,32 @@
1
+ # Enable coverage report message for diff on commit
2
+ # Docs can be found here: https://docs.codecov.io/v4.3.0/docs/commit-status
3
+ coverage:
4
+ status:
5
+ project:
6
+ default:
7
+ target: 80%
8
+ threshold: 1
9
+ base: auto
10
+ branches: null
11
+ if_no_uploads: error
12
+ if_not_found: success
13
+ if_ci_failed: error
14
+ only_pulls: false
15
+ flags: null
16
+ paths: null
17
+ patch:
18
+ default:
19
+ target: auto
20
+ # Allows PRs without tests, overall stats count
21
+ threshold: 100
22
+ base: auto
23
+ branches: null
24
+ if_no_uploads: error
25
+ if_not_found: success
26
+ if_ci_failed: error
27
+ only_pulls: false
28
+ flags: null
29
+ paths: null
30
+
31
+ # Disable comments on Pull Requests
32
+ comment: false
@@ -146,11 +146,30 @@ Arguments:
146
146
  * `action`: The action type of span eg. `connect` or `query`.
147
147
  * `context`: An instance of `Span::Context`.
148
148
  * `include_stacktrace`: Whether or not to collect a Stacktrace.
149
+ * `trace_context:`: An optional `TraceContext` object for Distributed Tracing.
150
+ * `parent:`: An optional parent transaction or span. Relevant when the span is created in another thread.
151
+ * `sync:`: An boolean to indicate whether the span is created synchronously or not.
149
152
  * `&block`: An optional block to wrap with the span.
150
153
  The block is passed the span as an optional argument.
151
154
 
152
155
  Returns the created span.
153
156
 
157
+ If you'd like to create an asynchronous span, you have to pass the parent `Span` or `Transaction` to the `start_span` method.
158
+ You can also set the `sync` flag to `false`, if you'd like the span to be marked as asynchronous. This has no effect other than being queryable in Elasticsearch.
159
+
160
+ [source,ruby]
161
+ ----
162
+ transaction = ElasticAPM.current_transaction # or start one with `.start_transaction`
163
+ Thread.new do
164
+ ElasticAPM.start_span(
165
+ 'job 1',
166
+ parent: transaction,
167
+ sync: false
168
+ ) { Worker.perform }
169
+ ElasticAPM.end_span
170
+ end
171
+ ----
172
+
154
173
  [float]
155
174
  [[api-agent-end_span]]
156
175
  ==== `ElasticAPM.end_span`
@@ -171,11 +190,29 @@ Arguments:
171
190
  * `action`: The action type of span eg. `connect` or `query`.
172
191
  * `context`: An instance of `Span::Context`.
173
192
  * `include_stacktrace`: Whether or not to collect a Stacktrace.
193
+ * `trace_context:`: An optional `TraceContext` object for Distributed Tracing.
194
+ * `parent:`: An optional parent transaction or span. Relevant when the span is created in another thread.
195
+ * `sync:`: An boolean to indicate whether the span is created synchronously or not.
174
196
  * `&block`: An optional block to wrap with the span.
175
197
  The block is passed the span as an optional argument.
176
198
 
177
199
  Returns the return value of the given block.
178
200
 
201
+ If you'd like to create an asynchronous span, you have to pass the parent `Span` or `Transaction` to the `with_span` method.
202
+ You can also set the `sync` flag to `false`, if you'd like the span to be marked as asynchronous.
203
+
204
+ [source,ruby]
205
+ ----
206
+ transaction = ElasticAPM.current_transaction # or start one with `.start_transaction`
207
+ Thread.new do
208
+ ElasticAPM.with_span(
209
+ 'job 1',
210
+ parent: transaction,
211
+ sync: false
212
+ ) { Worker.perform }
213
+ end
214
+ ----
215
+
179
216
  [float]
180
217
  [[api-agent-build-context]]
181
218
  ==== `ElasticAPM.build_context`