elastic-apm 3.3.0 → 3.8.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.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.ci/.jenkins_exclude.yml +43 -24
  3. data/.ci/.jenkins_framework.yml +2 -2
  4. data/.ci/.jenkins_ruby.yml +1 -1
  5. data/.ci/Jenkinsfile +288 -170
  6. data/.ci/docker/jruby/11-jdk/Dockerfile +40 -0
  7. data/.ci/docker/jruby/12-jdk/Dockerfile +40 -0
  8. data/.ci/docker/jruby/13-jdk/Dockerfile +40 -0
  9. data/.ci/docker/jruby/7-jdk/Dockerfile +40 -0
  10. data/.ci/docker/jruby/8-jdk/Dockerfile +40 -0
  11. data/.ci/docker/jruby/README.md +31 -0
  12. data/.ci/docker/jruby/run.sh +73 -0
  13. data/.ci/docker/jruby/test.sh +13 -0
  14. data/.ci/jobs/apm-agent-ruby-downstream.yml +1 -0
  15. data/.ci/jobs/apm-agent-ruby-linting-mbp.yml +1 -0
  16. data/.ci/jobs/apm-agent-ruby-mbp.yml +1 -0
  17. data/.ci/jobs/defaults.yml +1 -1
  18. data/.ci/packer_cache.sh +16 -0
  19. data/.github/ISSUE_TEMPLATE/Bug_report.md +40 -0
  20. data/.github/ISSUE_TEMPLATE/Feature_request.md +17 -0
  21. data/.github/PULL_REQUEST_TEMPLATE.md +60 -0
  22. data/.gitignore +8 -0
  23. data/.rspec +0 -1
  24. data/.rubocop.yml +18 -0
  25. data/CHANGELOG.asciidoc +104 -1
  26. data/CONTRIBUTING.md +6 -48
  27. data/Gemfile +38 -10
  28. data/README.md +62 -13
  29. data/Rakefile +37 -5
  30. data/bench/sql.rb +49 -0
  31. data/bin/build_docs +1 -1
  32. data/bin/run-tests +4 -1
  33. data/docker-compose.yml +7 -0
  34. data/docs/api.asciidoc +52 -3
  35. data/docs/configuration.asciidoc +171 -22
  36. data/docs/getting-started-rails.asciidoc +2 -0
  37. data/docs/graphql.asciidoc +23 -0
  38. data/docs/images/dynamic-config.svg +1 -0
  39. data/docs/index.asciidoc +6 -1
  40. data/docs/introduction.asciidoc +2 -1
  41. data/docs/performance-tuning.asciidoc +106 -0
  42. data/docs/set-up.asciidoc +5 -2
  43. data/docs/supported-technologies.asciidoc +86 -1
  44. data/docs/upgrading.asciidoc +45 -0
  45. data/elastic-apm.gemspec +17 -0
  46. data/lib/elastic-apm.rb +17 -0
  47. data/lib/elastic_apm.rb +58 -5
  48. data/lib/elastic_apm/agent.rb +55 -4
  49. data/lib/elastic_apm/central_config.rb +27 -8
  50. data/lib/elastic_apm/central_config/cache_control.rb +17 -0
  51. data/lib/elastic_apm/child_durations.rb +26 -4
  52. data/lib/elastic_apm/config.rb +86 -5
  53. data/lib/elastic_apm/config/bytes.rb +17 -0
  54. data/lib/elastic_apm/config/duration.rb +17 -0
  55. data/lib/elastic_apm/config/options.rb +21 -5
  56. data/lib/elastic_apm/config/regexp_list.rb +17 -0
  57. data/lib/elastic_apm/config/wildcard_pattern_list.rb +20 -1
  58. data/lib/elastic_apm/context.rb +17 -0
  59. data/lib/elastic_apm/context/request.rb +17 -0
  60. data/lib/elastic_apm/context/request/socket.rb +17 -0
  61. data/lib/elastic_apm/context/request/url.rb +17 -0
  62. data/lib/elastic_apm/context/response.rb +27 -2
  63. data/lib/elastic_apm/context/user.rb +17 -0
  64. data/lib/elastic_apm/context_builder.rb +17 -0
  65. data/lib/elastic_apm/deprecations.rb +17 -0
  66. data/lib/elastic_apm/error.rb +17 -0
  67. data/lib/elastic_apm/error/exception.rb +17 -0
  68. data/lib/elastic_apm/error/log.rb +17 -0
  69. data/lib/elastic_apm/error_builder.rb +17 -0
  70. data/lib/elastic_apm/grape.rb +17 -0
  71. data/lib/elastic_apm/graphql.rb +91 -0
  72. data/lib/elastic_apm/grpc.rb +99 -0
  73. data/lib/elastic_apm/instrumenter.rb +49 -15
  74. data/lib/elastic_apm/internal_error.rb +17 -0
  75. data/lib/elastic_apm/logging.rb +17 -0
  76. data/lib/elastic_apm/metadata.rb +17 -0
  77. data/lib/elastic_apm/metadata/process_info.rb +17 -0
  78. data/lib/elastic_apm/metadata/service_info.rb +22 -2
  79. data/lib/elastic_apm/metadata/system_info.rb +17 -0
  80. data/lib/elastic_apm/metadata/system_info/container_info.rb +17 -0
  81. data/lib/elastic_apm/metrics.rb +33 -1
  82. data/lib/elastic_apm/metrics/breakdown_set.rb +17 -0
  83. data/lib/elastic_apm/metrics/cpu_mem_set.rb +17 -0
  84. data/lib/elastic_apm/metrics/metric.rb +23 -4
  85. data/lib/elastic_apm/metrics/set.rb +17 -0
  86. data/lib/elastic_apm/metrics/span_scoped_set.rb +17 -0
  87. data/lib/elastic_apm/metrics/transaction_set.rb +17 -0
  88. data/lib/elastic_apm/metrics/vm_set.rb +17 -0
  89. data/lib/elastic_apm/metricset.rb +17 -0
  90. data/lib/elastic_apm/middleware.rb +20 -4
  91. data/lib/elastic_apm/naively_hashable.rb +17 -0
  92. data/lib/elastic_apm/normalizers.rb +17 -0
  93. data/lib/elastic_apm/normalizers/grape.rb +17 -0
  94. data/lib/elastic_apm/normalizers/grape/endpoint_run.rb +18 -1
  95. data/lib/elastic_apm/normalizers/rails.rb +17 -0
  96. data/lib/elastic_apm/normalizers/rails/action_controller.rb +17 -0
  97. data/lib/elastic_apm/normalizers/rails/action_mailer.rb +17 -0
  98. data/lib/elastic_apm/normalizers/rails/action_view.rb +17 -0
  99. data/lib/elastic_apm/normalizers/rails/active_record.rb +29 -5
  100. data/lib/elastic_apm/opentracing.rb +66 -24
  101. data/lib/elastic_apm/rails.rb +18 -10
  102. data/lib/elastic_apm/railtie.rb +18 -1
  103. data/lib/elastic_apm/resque.rb +29 -0
  104. data/lib/elastic_apm/sinatra.rb +17 -0
  105. data/lib/elastic_apm/span.rb +20 -2
  106. data/lib/elastic_apm/span/context.rb +43 -44
  107. data/lib/elastic_apm/span/context/db.rb +43 -0
  108. data/lib/elastic_apm/span/context/destination.rb +77 -0
  109. data/lib/elastic_apm/span/context/http.rb +43 -0
  110. data/lib/elastic_apm/span_helpers.rb +17 -0
  111. data/lib/elastic_apm/spies.rb +33 -14
  112. data/lib/elastic_apm/spies/action_dispatch.rb +17 -0
  113. data/lib/elastic_apm/spies/delayed_job.rb +17 -0
  114. data/lib/elastic_apm/spies/elasticsearch.rb +49 -5
  115. data/lib/elastic_apm/spies/faraday.rb +53 -18
  116. data/lib/elastic_apm/spies/http.rb +35 -3
  117. data/lib/elastic_apm/spies/json.rb +17 -0
  118. data/lib/elastic_apm/spies/mongo.rb +23 -1
  119. data/lib/elastic_apm/spies/net_http.rb +50 -8
  120. data/lib/elastic_apm/spies/rake.rb +17 -0
  121. data/lib/elastic_apm/spies/redis.rb +17 -0
  122. data/lib/elastic_apm/spies/resque.rb +53 -0
  123. data/lib/elastic_apm/spies/sequel.rb +52 -15
  124. data/lib/elastic_apm/spies/shoryuken.rb +65 -0
  125. data/lib/elastic_apm/spies/sidekiq.rb +17 -0
  126. data/lib/elastic_apm/spies/sinatra.rb +17 -0
  127. data/lib/elastic_apm/spies/sneakers.rb +74 -0
  128. data/lib/elastic_apm/spies/sucker_punch.rb +54 -0
  129. data/lib/elastic_apm/spies/tilt.rb +17 -0
  130. data/lib/elastic_apm/sql.rb +36 -0
  131. data/lib/elastic_apm/sql/signature.rb +169 -0
  132. data/lib/elastic_apm/sql/tokenizer.rb +264 -0
  133. data/lib/elastic_apm/sql/tokens.rb +63 -0
  134. data/lib/elastic_apm/sql_summarizer.rb +18 -2
  135. data/lib/elastic_apm/stacktrace.rb +17 -0
  136. data/lib/elastic_apm/stacktrace/frame.rb +17 -0
  137. data/lib/elastic_apm/stacktrace_builder.rb +23 -1
  138. data/lib/elastic_apm/subscriber.rb +17 -0
  139. data/lib/elastic_apm/trace_context.rb +85 -49
  140. data/lib/elastic_apm/trace_context/traceparent.rb +113 -0
  141. data/lib/elastic_apm/trace_context/tracestate.rb +43 -0
  142. data/lib/elastic_apm/transaction.rb +43 -15
  143. data/lib/elastic_apm/transport/base.rb +39 -23
  144. data/lib/elastic_apm/transport/connection.rb +17 -0
  145. data/lib/elastic_apm/transport/connection/http.rb +17 -0
  146. data/lib/elastic_apm/transport/connection/proxy_pipe.rb +24 -2
  147. data/lib/elastic_apm/transport/filters.rb +17 -0
  148. data/lib/elastic_apm/transport/filters/hash_sanitizer.rb +77 -0
  149. data/lib/elastic_apm/transport/filters/secrets_filter.rb +29 -53
  150. data/lib/elastic_apm/transport/headers.rb +21 -0
  151. data/lib/elastic_apm/transport/serializers.rb +17 -0
  152. data/lib/elastic_apm/transport/serializers/context_serializer.rb +17 -0
  153. data/lib/elastic_apm/transport/serializers/error_serializer.rb +17 -0
  154. data/lib/elastic_apm/transport/serializers/metadata_serializer.rb +44 -20
  155. data/lib/elastic_apm/transport/serializers/metricset_serializer.rb +17 -0
  156. data/lib/elastic_apm/transport/serializers/span_serializer.rb +45 -8
  157. data/lib/elastic_apm/transport/serializers/transaction_serializer.rb +17 -0
  158. data/lib/elastic_apm/transport/user_agent.rb +17 -0
  159. data/lib/elastic_apm/transport/worker.rb +17 -0
  160. data/lib/elastic_apm/util.rb +17 -0
  161. data/lib/elastic_apm/util/inflector.rb +17 -0
  162. data/lib/elastic_apm/util/lru_cache.rb +17 -0
  163. data/lib/elastic_apm/util/throttle.rb +17 -0
  164. data/lib/elastic_apm/version.rb +18 -1
  165. metadata +36 -7
  166. data/.ci/downstreamTests.groovy +0 -185
  167. data/.ci/prepare-git-context.sh +0 -24
  168. data/.github/workflows/main.yml +0 -14
  169. data/CHANGELOG.md +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aaf3f0eada3b3bfe036dc55802688666e3df0ee48848b45dd73aa6861e625dc6
4
- data.tar.gz: feb50b6f3d2da29af6591f31a62ea95189ab64868fb5403e3d85ceec548868d8
3
+ metadata.gz: 32d176ac5c22246df60ecc92f1baad37011a872af4e64f842b5a43c699a6ced3
4
+ data.tar.gz: bf0505e728d8f1bd0bb941574a844a8990d14e13a94a7c9f2a6c2d0f9eb5d35b
5
5
  SHA512:
6
- metadata.gz: b7bcd197586b7782f25fa814ec0430c33f7b21abaa6b79c81fe93ee07654df1448eea4257f8c29b6f6dce1b7778c0b88f6e825a1338bdba591fd4934b9bcaa09
7
- data.tar.gz: 181bf8aa045473ef55cb794199638722e1bd7f142e558077928a94e03ca75812d21633c6781e734d7029b12e9b4d54232498f604a6be26f70daaffcd1e91f03e
6
+ metadata.gz: d57b6bdbc7e78bea95e197d33f3eef4db7a35b23f9e450c636c3c1e3a5dd75ee8ee195709944ac51d6af7a3ab2451fd19d6139f0dedf9e86a4827732d5097f2a
7
+ data.tar.gz: 924b9bbf782a0fa4e376137e9a44d10cc01be71455ca7614ab1374c70f0926d174eb1078b985cd60c1693e2e0ec1cdd8446502bd40007359262dcc31241250aa
@@ -1,5 +1,28 @@
1
1
  exclude:
2
- - RUBY_VERSION: ruby:2.7-rc
2
+ # Ruby 2.3
3
+ # Only includes rails-5.2, sinatra-2.0
4
+ - RUBY_VERSION: ruby:2.3
5
+ FRAMEWORK: rails-6.0
6
+ - RUBY_VERSION: ruby:2.3
7
+ FRAMEWORK: rails-5.1
8
+ - RUBY_VERSION: ruby:2.3
9
+ FRAMEWORK: rails-5.0
10
+ - RUBY_VERSION: ruby:2.3
11
+ FRAMEWORK: rails-4.2
12
+ - RUBY_VERSION: ruby:2.3
13
+ FRAMEWORK: sinatra-1.4
14
+ - RUBY_VERSION: ruby:2.3
15
+ FRAMEWORK: grape-1.3
16
+ - RUBY_VERSION: ruby:2.3
17
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
18
+ - RUBY_VERSION: ruby:2.3
19
+ FRAMEWORK: rails-master
20
+ - RUBY_VERSION: ruby:2.3
21
+ FRAMEWORK: sinatra-master
22
+ - RUBY_VERSION: ruby:2.3
23
+ FRAMEWORK: grape-master
24
+
25
+ - RUBY_VERSION: ruby:2.7
3
26
  FRAMEWORK: rails-4.2
4
27
  - RUBY_VERSION: jruby:9.2
5
28
  FRAMEWORK: rails-4.2
@@ -18,22 +41,18 @@ exclude:
18
41
 
19
42
  - RUBY_VERSION: ruby:2.4
20
43
  FRAMEWORK: rails-6.0
21
- - RUBY_VERSION: ruby:2.3
22
- FRAMEWORK: rails-6.0
23
44
  - RUBY_VERSION: jruby:9.1
24
45
  FRAMEWORK: rails-6.0
25
46
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
26
47
  FRAMEWORK: rails-6.0
27
48
 
28
49
  # Only test master on newest ruby
29
- - RUBY_VERSION: ruby:2.7-rc
50
+ - RUBY_VERSION: ruby:2.6
30
51
  FRAMEWORK: rails-master
31
52
  - RUBY_VERSION: ruby:2.5
32
53
  FRAMEWORK: rails-master
33
54
  - RUBY_VERSION: ruby:2.4
34
55
  FRAMEWORK: rails-master
35
- - RUBY_VERSION: ruby:2.3
36
- FRAMEWORK: rails-master
37
56
  - RUBY_VERSION: jruby:9.2
38
57
  FRAMEWORK: rails-master
39
58
  - RUBY_VERSION: jruby:9.1
@@ -53,8 +72,6 @@ exclude:
53
72
  FRAMEWORK: sinatra-master
54
73
  - RUBY_VERSION: ruby:2.4
55
74
  FRAMEWORK: sinatra-master
56
- - RUBY_VERSION: ruby:2.3
57
- FRAMEWORK: sinatra-master
58
75
  - RUBY_VERSION: jruby:9.2
59
76
  FRAMEWORK: sinatra-master
60
77
  - RUBY_VERSION: jruby:9.1
@@ -70,14 +87,12 @@ exclude:
70
87
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
71
88
  FRAMEWORK: sinatra-master
72
89
 
73
- - RUBY_VERSION: ruby:2.7-rc
90
+ - RUBY_VERSION: ruby:2.6
74
91
  FRAMEWORK: grape-master
75
92
  - RUBY_VERSION: ruby:2.5
76
93
  FRAMEWORK: grape-master
77
94
  - RUBY_VERSION: ruby:2.4
78
95
  FRAMEWORK: grape-master
79
- - RUBY_VERSION: ruby:2.3
80
- FRAMEWORK: grape-master
81
96
  - RUBY_VERSION: jruby:9.2
82
97
  FRAMEWORK: grape-master
83
98
  - RUBY_VERSION: jruby:9.1
@@ -93,25 +108,29 @@ exclude:
93
108
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
94
109
  FRAMEWORK: grape-master
95
110
 
96
- - RUBY_VERSION: ruby:2.7-rc
97
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
111
+ # Unsupported
112
+ - RUBY_VERSION: jruby:9.1
113
+ FRAMEWORK: grape-1.3
114
+ - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
115
+ FRAMEWORK: grape-1.3
116
+
117
+ - RUBY_VERSION: ruby:2.6
118
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
98
119
  - RUBY_VERSION: ruby:2.5
99
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
120
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
100
121
  - RUBY_VERSION: ruby:2.4
101
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
102
- - RUBY_VERSION: ruby:2.3
103
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
122
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
104
123
  - RUBY_VERSION: jruby:9.2
105
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
124
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
106
125
  - RUBY_VERSION: jruby:9.1
107
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
126
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
108
127
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.2-13-jdk
109
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
128
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
110
129
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.2-12-jdk
111
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
130
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
112
131
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.2-11-jdk
113
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
132
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
114
133
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.2-8-jdk
115
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
134
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
116
135
  - RUBY_VERSION: docker.elastic.co/observability-ci/jruby:9.1-7-jdk
117
- FRAMEWORK: grape-1.2,sinatra-2.0,rails-6.0
136
+ FRAMEWORK: grape-1.3,sinatra-2.0,rails-6.0
@@ -8,6 +8,6 @@ FRAMEWORK:
8
8
  - sinatra-2.0
9
9
  - sinatra-1.4
10
10
 
11
- - grape-1.2
11
+ - grape-1.3
12
12
 
13
- - grape-1.2,sinatra-2.0,rails-6.0
13
+ - grape-1.3,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
@@ -5,16 +5,17 @@ import co.elastic.matrix.*
5
5
  import groovy.transform.Field
6
6
 
7
7
  /**
8
- This is required to store the results of the tests.
8
+ This is the parallel tasks generator,
9
+ it is need as field to store the results of the tests.
9
10
  */
10
- @Field def rubyTasksFailed = false
11
+ @Field def rubyTasksGen
11
12
 
12
13
  pipeline {
13
14
  agent { label 'linux && immutable' }
14
15
  environment {
15
16
  REPO = 'apm-agent-ruby'
16
17
  BASE_DIR = "src/github.com/elastic/${env.REPO}"
17
- PIPELINE_LOG_LEVEL='DEBUG'
18
+ PIPELINE_LOG_LEVEL = 'INFO'
18
19
  NOTIFY_TO = credentials('notify-to')
19
20
  JOB_GCS_BUCKET = credentials('gcs-bucket')
20
21
  CODECOV_SECRET = 'secret/apm-team/ci/apm-agent-ruby-codecov'
@@ -24,6 +25,7 @@ pipeline {
24
25
  ITS_PIPELINE = 'apm-integration-tests-selector-mbp/master'
25
26
  RELEASE_SECRET = 'secret/apm-team/ci/apm-agent-ruby-rubygems-release'
26
27
  OPBEANS_REPO = 'opbeans-ruby'
28
+ REFERENCE_REPO = '/var/lib/jenkins/.git-references/apm-agent-ruby.git'
27
29
  }
28
30
  options {
29
31
  timeout(time: 2, unit: 'HOURS')
@@ -36,7 +38,7 @@ pipeline {
36
38
  quietPeriod(10)
37
39
  }
38
40
  triggers {
39
- issueCommentTrigger('(?i).*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
41
+ issueCommentTrigger('(?i).*(?:jenkins\\W+)?run\\W+(?:the\\W+)?(?:benchmark\\W+)?tests(?:\\W+please)?.*')
40
42
  }
41
43
  parameters {
42
44
  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.')
@@ -51,16 +53,25 @@ pipeline {
51
53
  steps {
52
54
  pipelineManager([ cancelPreviousRunningBuilds: [ when: 'PR' ] ])
53
55
  deleteDir()
54
- gitCheckout(basedir: "${BASE_DIR}", githubNotifyFirstTimeContributor: true)
56
+ gitCheckout(basedir: "${BASE_DIR}", githubNotifyFirstTimeContributor: true, reference: "${env.REFERENCE_REPO}")
55
57
  stash allowEmpty: true, name: 'source', useDefaultExcludes: false
58
+ script {
59
+ dir("${BASE_DIR}"){
60
+ // Skip all the stages except docs for PR's with asciidoc and md changes only
61
+ env.ONLY_DOCS = isGitRegionMatch(patterns: [ '.*\\.(asciidoc|md)' ], shouldMatchAll: true)
62
+ }
63
+ }
56
64
  }
57
65
  }
58
66
  stage('Sanity checks') {
59
67
  when {
60
68
  beforeAgent true
61
- anyOf {
62
- not { changeRequest() }
63
- expression { return params.Run_As_Master_Branch }
69
+ allOf {
70
+ expression { return env.ONLY_DOCS == "false" }
71
+ anyOf {
72
+ not { changeRequest() }
73
+ expression { return params.Run_As_Master_Branch }
74
+ }
64
75
  }
65
76
  }
66
77
  options { skipDefaultCheckout() }
@@ -83,168 +94,177 @@ pipeline {
83
94
  /**
84
95
  Execute unit tests.
85
96
  */
86
- stage('Test') {
87
- options { skipDefaultCheckout() }
88
- steps {
89
- withGithubNotify(context: 'Tests', tab: 'tests') {
90
- deleteDir()
91
- unstash "source"
92
- dir("${BASE_DIR}"){
93
- script {
94
- def ruby = readYaml(file: '.ci/.jenkins_ruby.yml')
95
- def testTasks = [:]
96
- ruby['RUBY_VERSION'].each{ rubyVersion ->
97
- testTasks[rubyVersion] = { runJob(rubyVersion) }
98
- }
99
- parallel(testTasks)
100
- }
97
+ stage('Tests') {
98
+ when {
99
+ beforeAgent true
100
+ expression { return env.ONLY_DOCS == "false" }
101
+ }
102
+ failFast false
103
+ parallel {
104
+ stage('Tests') {
105
+ options { skipDefaultCheckout() }
106
+ steps {
107
+ withGithubNotify(context: 'Tests', tab: 'tests') {
108
+ runTests('.ci/.jenkins_framework.yml')
101
109
  }
102
110
  }
103
- }
104
- }
105
- stage('Benchmarks') {
106
- options { skipDefaultCheckout() }
107
- when {
108
- beforeAgent true
109
- allOf {
110
- anyOf {
111
- branch 'master'
112
- branch "\\d+\\.\\d+"
113
- branch "v\\d?"
114
- tag "v\\d+\\.\\d+\\.\\d+*"
115
- expression { return params.Run_As_Master_Branch }
111
+ post {
112
+ always {
113
+ convergeCoverage()
116
114
  }
117
- expression { return params.bench_ci }
118
115
  }
119
116
  }
120
- stages {
121
- stage('Clean Workspace') {
122
- agent { label 'metal' }
123
- steps {
124
- echo "Cleaning Workspace"
125
- }
126
- post {
127
- always {
128
- cleanWs()
129
- }
117
+ stage('Master Tests frameworks') {
118
+ options { skipDefaultCheckout() }
119
+ steps {
120
+ catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE', message: "The tests for the master framework have failed. Let's warn instead.") {
121
+ runTests('.ci/.jenkins_master_framework.yml')
130
122
  }
131
123
  }
132
- /**
133
- Run the benchmarks and store the results on ES.
134
- The result JSON files are also archive into Jenkins.
135
- */
136
- stage('Run Benchmarks') {
137
- steps {
138
- withGithubNotify(context: 'Run Benchmarks') {
139
- deleteDir()
140
- unstash 'source'
141
- dir("${BASE_DIR}"){
142
- script {
143
- def versions = readYaml(file: ".ci/.jenkins_ruby.yml")
144
- def benchmarkTask = [:]
145
- // TODO: benchmark for the jruby:9.2 and similar versions got some issues with
146
- // NoMethodError: undefined method `[]' for nil:NilClass
147
- // <main> at bench/report.rb:48
148
- versions['RUBY_VERSION'].findAll { !it.contains('9.2') }.each{ v ->
149
- benchmarkTask[v] = runBenchmark(v)
150
- }
151
- parallel(benchmarkTask)
152
- }
153
- }
154
- }
124
+ }
125
+ stage('Integration Tests') {
126
+ agent none
127
+ when {
128
+ beforeAgent true
129
+ anyOf {
130
+ changeRequest()
131
+ expression { return !params.Run_As_Master_Branch }
155
132
  }
156
133
  }
134
+ steps {
135
+ githubNotify(context: "${env.GITHUB_CHECK_ITS_NAME}", description: "${env.GITHUB_CHECK_ITS_NAME} ...", status: 'PENDING', targetUrl: "${env.JENKINS_URL}search/?q=${env.ITS_PIPELINE.replaceAll('/','+')}")
136
+ build(job: env.ITS_PIPELINE, propagate: false, wait: true,
137
+ parameters: [ string(name: 'INTEGRATION_TEST', value: 'Ruby'),
138
+ string(name: 'BUILD_OPTS', value: "--ruby-agent-version ${env.GIT_BASE_COMMIT} --ruby-agent-version-state ${env.GIT_BUILD_CAUSE} --ruby-agent-repo ${env.CHANGE_FORK?.trim() ?: 'elastic'}/${env.REPO} --opbeans-ruby-agent-branch ${env.GIT_BASE_COMMIT}"),
139
+ string(name: 'GITHUB_CHECK_NAME', value: env.GITHUB_CHECK_ITS_NAME),
140
+ string(name: 'GITHUB_CHECK_REPO', value: env.REPO),
141
+ string(name: 'GITHUB_CHECK_SHA1', value: env.GIT_BASE_COMMIT) ])
142
+ }
157
143
  }
158
144
  }
159
- stage('Populate Test failures') {
160
- when {
161
- expression { return rubyTasksFailed }
162
- }
163
- steps {
164
- error('There were some failures when running the "Test" stage')
165
- }
166
- }
167
- stage('Integration Tests') {
168
- agent none
169
- when {
170
- beforeAgent true
145
+ }
146
+ stage('Benchmarks') {
147
+ options { skipDefaultCheckout() }
148
+ when {
149
+ beforeAgent true
150
+ allOf {
171
151
  anyOf {
172
- changeRequest()
173
- expression { return !params.Run_As_Master_Branch }
152
+ branch 'master'
153
+ branch "\\d+\\.\\d+"
154
+ branch "v\\d?"
155
+ tag pattern: 'v\\d+.*', comparator: "REGEXP"
156
+ expression { return params.Run_As_Master_Branch }
157
+ expression { return env.GITHUB_COMMENT?.contains('benchmark tests') }
174
158
  }
175
- }
176
- steps {
177
- log(level: 'INFO', text: 'Launching Async ITs')
178
- build(job: env.ITS_PIPELINE, propagate: false, wait: false,
179
- parameters: [string(name: 'AGENT_INTEGRATION_TEST', value: 'Ruby'),
180
- string(name: 'BUILD_OPTS', value: "--ruby-agent-version ${env.GIT_BASE_COMMIT} --ruby-agent-version-state ${env.GIT_BUILD_CAUSE} --ruby-agent-repo ${env.CHANGE_FORK?.trim() ?: 'elastic'}/${env.REPO}"),
181
- string(name: 'GITHUB_CHECK_NAME', value: env.GITHUB_CHECK_ITS_NAME),
182
- string(name: 'GITHUB_CHECK_REPO', value: env.REPO),
183
- string(name: 'GITHUB_CHECK_SHA1', value: env.GIT_BASE_COMMIT)]
184
- )
185
- githubNotify(context: "${env.GITHUB_CHECK_ITS_NAME}", description: "${env.GITHUB_CHECK_ITS_NAME} ...", status: 'PENDING', targetUrl: "${env.JENKINS_URL}search/?q=${env.ITS_PIPELINE.replaceAll('/','+')}")
159
+ expression { return params.bench_ci }
186
160
  }
187
161
  }
188
- stage('Release') {
189
- options { skipDefaultCheckout() }
190
- environment {
191
- RUBY_DOCKER_TAG = 'ruby:2.6'
192
- HOME = '/var/lib/jenkins'
193
- }
194
- when {
195
- beforeAgent true
196
- tag pattern: 'v\\d+.*', comparator: 'REGEXP'
162
+ stages {
163
+ stage('Clean Workspace') {
164
+ agent { label 'metal' }
165
+ steps {
166
+ echo "Cleaning Workspace"
167
+ }
168
+ post {
169
+ always {
170
+ cleanWs()
171
+ }
172
+ }
197
173
  }
198
- stages {
199
- stage('Release') {
200
- steps {
201
- withGithubNotify(context: 'Release') {
202
- deleteDir()
203
- unstash 'source'
174
+ /**
175
+ Run the benchmarks and store the results on ES.
176
+ The result JSON files are also archive into Jenkins.
177
+ */
178
+ stage('Run Benchmarks') {
179
+ steps {
180
+ withGithubNotify(context: 'Run Benchmarks') {
181
+ deleteDir()
182
+ unstash 'source'
183
+ dir("${BASE_DIR}"){
204
184
  script {
205
- dir(BASE_DIR){
206
- docker.image("${env.RUBY_DOCKER_TAG}").inside('-v /etc/passwd:/etc/passwd -v ${HOME}/.ssh:${HOME}/.ssh') {
207
- withEnv(["HOME=${env.WORKSPACE}/${env.BASE_DIR ?: ''}"]) {
208
- rubygemsLogin.withApi(secret: "${env.RELEASE_SECRET}") {
209
- sshagent(['f6c7695a-671e-4f4f-a331-acdce44ff9ba']) {
210
- sh '.ci/prepare-git-context.sh'
211
- sh 'gem install rake yard rspec'
212
- sh 'rake release'
213
- }
214
- }
215
- }
216
- }
185
+ def versions = readYaml(file: ".ci/.jenkins_ruby.yml")
186
+ def benchmarkTask = [:]
187
+ versions['RUBY_VERSION'].each{ v ->
188
+ benchmarkTask[v] = runBenchmark(v)
217
189
  }
190
+ parallel(benchmarkTask)
218
191
  }
219
192
  }
220
193
  }
221
194
  }
222
- stage('Opbeans') {
223
- environment {
224
- REPO_NAME = "${OPBEANS_REPO}"
195
+ }
196
+ }
197
+ }
198
+ stage('Release') {
199
+ options { skipDefaultCheckout() }
200
+ environment {
201
+ RUBY_DOCKER_TAG = 'ruby:2.6'
202
+ HOME = '/var/lib/jenkins'
203
+ }
204
+ when {
205
+ beforeAgent true
206
+ tag pattern: 'v\\d+.*', comparator: 'REGEXP'
207
+ }
208
+ stages {
209
+ stage('Release') {
210
+ steps {
211
+ deleteDir()
212
+ unstash 'source'
213
+ prepareRelease(){
214
+ sh 'rake release'
225
215
  }
226
- steps {
227
- deleteDir()
228
- dir("${OPBEANS_REPO}"){
229
- git credentialsId: 'f6c7695a-671e-4f4f-a331-acdce44ff9ba',
230
- url: "git@github.com:elastic/${OPBEANS_REPO}.git"
231
- sh script: ".ci/bump-version.sh ${env.BRANCH_NAME}", label: 'Bump version'
232
- // The opbeans pipeline will trigger a release for the master branch
233
- gitPush()
234
- // The opbeans pipeline will trigger a release for the release tag
235
- gitCreateTag(tag: "${env.BRANCH_NAME}")
216
+ }
217
+ }
218
+ stage('Update Branch') {
219
+ steps {
220
+ deleteDir()
221
+ unstash 'source'
222
+ prepareRelease(){
223
+ catchError(buildResult: 'SUCCESS', message: 'Update branch task failed', stageResult: 'UNSTABLE') {
224
+ sh 'rake release:update_branch'
236
225
  }
237
226
  }
238
227
  }
228
+ post {
229
+ unsuccessful {
230
+ emailext subject: "[${env.REPO}] Syncup post-release stage failed.", to: "${NOTIFY_TO}",
231
+ body: "Please go to ${env.BUILD_URL} to review the logs. Most likely you need to update the branch manually."
232
+ }
233
+ }
234
+ }
235
+ stage('Opbeans') {
236
+ environment {
237
+ REPO_NAME = "${OPBEANS_REPO}"
238
+ VERSION = "${env.BRANCH_NAME.replaceAll('^v', '')}"
239
+ }
240
+ steps {
241
+ deleteDir()
242
+ // Let's wait for the Gem to be available
243
+ sh label: 'Wait for gem', script: """#!/usr/bin/env bash
244
+ source /usr/local/bin/bash_standard_lib.sh
245
+ (retry 10 curl --silent --show-error --fail -I https://rubygems.org/gems/elastic-apm/versions/${env.VERSION})
246
+ """
247
+ dir("${OPBEANS_REPO}"){
248
+ git credentialsId: 'f6c7695a-671e-4f4f-a331-acdce44ff9ba',
249
+ url: "git@github.com:elastic/${OPBEANS_REPO}.git"
250
+ // It's required to transform the tag value to the gem version
251
+ sh script: ".ci/bump-version.sh ${env.VERSION}", label: 'Bump version'
252
+ // The opbeans pipeline will trigger a release for the master branch
253
+ gitPush()
254
+ // The opbeans pipeline will trigger a release for the release tag
255
+ gitCreateTag(tag: "${env.BRANCH_NAME}")
256
+ }
257
+ }
239
258
  }
240
259
  }
241
260
  }
242
- post {
243
- cleanup {
244
- notifyBuildResult()
245
- }
261
+ }
262
+ post {
263
+ cleanup {
264
+ notifyBuildResult()
246
265
  }
247
266
  }
267
+ }
248
268
 
249
269
  /**
250
270
  Run benchmarks for a Ruby version, then report the results to the Elasticsearch server.
@@ -256,26 +276,64 @@ def runBenchmark(version){
256
276
  // - docker.elastic.co/observability-ci/jruby:9.2-12-jdk to jruby-9.2-12-jdk
257
277
  // - jruby:9.1 to jruby-9.1
258
278
  def transformedVersion = version.replaceAll('.*/', '').replaceAll(':', '-')
259
- env.HOME = "${env.WORKSPACE}/${transformedVersion}"
260
- dir("${transformedVersion}"){
261
- deleteDir()
262
- unstash 'source'
263
- dir("${BASE_DIR}"){
264
- retry(2){
265
- sleep randomNumber(min:10, max: 30)
266
- dockerLogin(secret: "${DOCKER_SECRET}", registry: "${DOCKER_REGISTRY}")
279
+ withEnv(["HOME=${env.WORKSPACE}/${transformedVersion}"]){
280
+ dir("${transformedVersion}"){
281
+ deleteDir()
282
+ unstash 'source'
283
+ dir("${BASE_DIR}"){
284
+ retry(2){
285
+ sleep randomNumber(min:10, max: 30)
286
+ dockerLogin(secret: "${DOCKER_SECRET}", registry: "${DOCKER_REGISTRY}")
287
+ }
288
+ try{
289
+ sh """./spec/scripts/benchmarks.sh "${version}" "${REFERENCE_REPO}" """
290
+ } catch(e){
291
+ throw e
292
+ } finally {
293
+ archiveArtifacts(
294
+ allowEmptyArchive: true,
295
+ artifacts: "**/benchmark-${transformedVersion}.raw,**/benchmark-${transformedVersion}.error",
296
+ onlyIfSuccessful: false)
297
+ sendBenchmarks(file: "benchmark-${transformedVersion}.bulk",
298
+ index: "benchmark-ruby", archive: true)
299
+ }
267
300
  }
268
- try{
269
- sh "./spec/scripts/benchmarks.sh ${version}"
270
- } catch(e){
271
- throw e
272
- } finally {
273
- archiveArtifacts(
274
- allowEmptyArchive: true,
275
- artifacts: "**/benchmark-${transformedVersion}.raw,**/benchmark-${transformedVersion}.error",
276
- onlyIfSuccessful: false)
277
- sendBenchmarks(file: "benchmark-${transformedVersion}.bulk",
278
- index: "benchmark-ruby", archive: true)
301
+ }
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ class RubyParallelTaskGenerator extends DefaultParallelTaskGenerator {
308
+
309
+ public RubyParallelTaskGenerator(Map params){
310
+ super(params)
311
+ }
312
+
313
+ /**
314
+ build a clousure that launch and agent and execute the corresponding test script,
315
+ then store the results.
316
+ */
317
+ public Closure generateStep(x, y){
318
+ return {
319
+ steps.sleep steps.randomNumber(min:10, max: 30)
320
+ steps.node('linux && immutable'){
321
+ // Label is transformed to avoid using the internal docker registry in the x coordinate
322
+ // TODO: def label = "${tag}:${x?.drop(x?.lastIndexOf('/')+1)}#${y}"
323
+ def label = "${tag}:${x}#${y}"
324
+ try {
325
+ steps.runScript(label: label, ruby: x, framework: y)
326
+ saveResult(x, y, 1)
327
+ } catch(e){
328
+ saveResult(x, y, 0)
329
+ steps.error("${label} tests failed : ${e.toString()}\n")
330
+ } finally {
331
+ steps.junit(allowEmptyResults: false,
332
+ keepLongStdio: true,
333
+ testResults: "**/spec/junit-reports/**/ruby-agent-junit.xml")
334
+ steps.dir("${steps.env.BASE_DIR}"){
335
+ steps.archiveArtifacts(artifacts: 'coverage/matrix_results/', defaultExcludes: false)
336
+ steps.stash(name: steps.normalise("coverage-${x}-${y}"), includes: 'coverage/matrix_results/', allowEmpty: true)
279
337
  }
280
338
  }
281
339
  }
@@ -283,19 +341,79 @@ def runBenchmark(version){
283
341
  }
284
342
  }
285
343
 
286
- def runJob(rubyVersion){
287
- try {
288
- build( job: "apm-agent-ruby/apm-agent-ruby-downstream/${env.BRANCH_NAME}",
289
- parameters: [
290
- string(name: 'RUBY_VERSION', value: "${rubyVersion}"),
291
- string(name: 'BRANCH_SPECIFIER', value: "${env.GIT_BASE_COMMIT}")
292
- ],
293
- quietPeriod: 15
344
+ /**
345
+ Run all the tests for the given file with the frameworks to test
346
+ */
347
+ def runTests(frameworkFile) {
348
+ deleteDir()
349
+ unstash "source"
350
+ dir("${BASE_DIR}"){
351
+ rubyTasksGen = new RubyParallelTaskGenerator(
352
+ xKey: 'RUBY_VERSION',
353
+ yKey: 'FRAMEWORK',
354
+ xFile: ".ci/.jenkins_ruby.yml",
355
+ yFile: frameworkFile,
356
+ exclusionFile: ".ci/.jenkins_exclude.yml",
357
+ tag: "Ruby",
358
+ name: "Ruby",
359
+ steps: this
294
360
  )
295
- } catch(e) {
296
- rubyTasksFailed = true
297
- warnError('Test Failures') {
298
- error("Downstream job for '${rubyVersion}' failed")
361
+ def testTasks = rubyTasksGen.generateParallelTests()
362
+ parallel(testTasks)
363
+ }
364
+ }
365
+
366
+ /**
367
+ Run tests for a Ruby version and framework version.
368
+ */
369
+ def runScript(Map params = [:]){
370
+ def label = params.label
371
+ def ruby = params.ruby
372
+ def framework = params.framework
373
+ log(level: 'INFO', text: "${label}")
374
+ retry(2){
375
+ withEnv(["HOME=${env.WORKSPACE}", "PATH=${env.PATH}:${env.WORKSPACE}/bin"]) {
376
+ deleteDir()
377
+ unstash 'source'
378
+ dir("${BASE_DIR}"){
379
+ sleep randomNumber(min:10, max: 30)
380
+ dockerLogin(secret: "${DOCKER_SECRET}", registry: "${DOCKER_REGISTRY}")
381
+ sh("./spec/scripts/spec.sh ${ruby} ${framework}")
382
+ }
299
383
  }
300
384
  }
301
385
  }
386
+
387
+ def convergeCoverage() {
388
+ deleteDir()
389
+ unstash('source')
390
+ dir("${BASE_DIR}"){
391
+ rubyTasksGen.dumpMatrix('-')?.each {
392
+ unstash(normalise("coverage-${it}"))
393
+ }
394
+ sh(script: './spec/scripts/coverage_converge.sh')
395
+ cobertura coberturaReportFile: 'coverage/coverage.xml', onlyStable: false
396
+ }
397
+ }
398
+
399
+ def prepareRelease(Closure body){
400
+ dir("${env.BASE_DIR}"){
401
+ docker.image("${env.RUBY_DOCKER_TAG}").inside('-v ${REFERENCE_REPO}:${REFERENCE_REPO} -v /etc/passwd:/etc/passwd -v ${HOME}/.ssh:${HOME}/.ssh') {
402
+ withEnv(["HOME=${env.WORKSPACE}/${env.BASE_DIR ?: ''}"]) {
403
+ rubygemsLogin.withApi(secret: "${env.RELEASE_SECRET}") {
404
+ withGitRelease(credentialsId: '2a9602aa-ab9f-4e52-baf3-b71ca88469c7-UserAndToken') {
405
+ sh 'gem install rake yard rspec'
406
+ body()
407
+ }
408
+ }
409
+ }
410
+ }
411
+ }
412
+ }
413
+
414
+ // Transform the versions like:
415
+ // - docker.elastic.co/observability-ci/jruby:9.2-12-jdk to jruby-9.2-12-jdk
416
+ // - jruby:9.1 to jruby-9.1
417
+ def normalise(def what) {
418
+ return what.replaceAll('.*/', '').replaceAll(':', '-')
419
+ }