elastic-apm 2.3.1 → 2.4.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 +4 -4
- data/CHANGELOG.md +17 -1
- data/CONTRIBUTING.md +93 -0
- data/Gemfile +3 -1
- data/Jenkinsfile +264 -0
- data/README.md +1 -1
- data/bench/report.rb +5 -32
- data/docs/configuration.asciidoc +13 -1
- data/docs/custom-instrumentation.asciidoc +1 -1
- data/docs/supported-technologies.asciidoc +7 -6
- data/lib/elastic_apm/config.rb +3 -1
- data/lib/elastic_apm/context_builder.rb +14 -6
- data/lib/elastic_apm/deprecations.rb +7 -4
- data/lib/elastic_apm/instrumenter.rb +4 -5
- data/lib/elastic_apm/metrics/cpu_mem.rb +27 -12
- data/lib/elastic_apm/opentracing.rb +4 -12
- data/lib/elastic_apm/span.rb +12 -18
- data/lib/elastic_apm/trace_context.rb +40 -23
- data/lib/elastic_apm/transaction.rb +9 -22
- data/lib/elastic_apm/transport/connection.rb +13 -1
- data/lib/elastic_apm/transport/filters.rb +1 -5
- data/lib/elastic_apm/transport/filters/secrets_filter.rb +9 -9
- data/lib/elastic_apm/version.rb +1 -1
- metadata +5 -4
- data/lib/elastic_apm/transport/filters/request_body_filter.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3fb435d6ad1fd7a4e60cadedf93d9058da43310444e2fe4751d340a8a0eb7ed
|
4
|
+
data.tar.gz: 7e4a452a0ef34cd1d91bb5b9e1e74cd4c14a2d66ed4fe85ee5317682077c193b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad0a3ea9273288644640513a82db7baf1ed5c89f5ff4c1e57246d08d6baa8796d854263170afa887edbc5ab1ce2d73a5d73b8e6d367c58f56efd4d830e4c9be4
|
7
|
+
data.tar.gz: 0410ba02cd8c06b473fcb428900a5ed4d1eeae16134f187cde4525139edd669e75122cbe7b98d0a98a1639df4863d07d429dd6a3b27696604385e4703edaacb4
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,23 @@ 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
|
-
##
|
7
|
+
## 2.4.0 (2019-02-27)
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Added option to specify a custom server CA certificate ([#315](https://github.com/elastic/apm-agent-ruby/pull/315))
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
|
15
|
+
- **NB:** Default value of option `capture_body` flipped to `false` to align with other agents. Set `capture_body: true` in your configuration to get them back. ([#324](https://github.com/elastic/apm-agent-ruby/pull/324))
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- Reading CPU stats from `/proc/stat` on RHEL ([#312](https://github.com/elastic/apm-agent-ruby/pull/312))
|
20
|
+
- Change TraceContext to differentiate between `id` and `parent_id` ([#326](https://github.com/elastic/apm-agent-ruby/pull/326))
|
21
|
+
- `capture_body` will now force encode text bodies to utf-8 when possible ([#332](https://github.com/elastic/apm-agent-ruby/pull/332))
|
22
|
+
|
23
|
+
## 2.3.1 (2019-01-31)
|
8
24
|
|
9
25
|
### Added
|
10
26
|
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Contributing to the APM Agent
|
2
|
+
|
3
|
+
The APM Agent is open source and we love to receive contributions from our community — you!
|
4
|
+
|
5
|
+
There are many ways to contribute,
|
6
|
+
from writing tutorials or blog posts,
|
7
|
+
improving the documentation,
|
8
|
+
submitting bug reports and feature requests or writing code.
|
9
|
+
|
10
|
+
You can get in touch with us through [Discuss](https://discuss.elastic.co/c/apm),
|
11
|
+
feedback and ideas are always welcome.
|
12
|
+
|
13
|
+
## Code contributions
|
14
|
+
|
15
|
+
If you have a bugfix or new feature that you would like to contribute,
|
16
|
+
please find or open an issue about it first.
|
17
|
+
Talk about what you would like to do.
|
18
|
+
It may be that somebody is already working on it,
|
19
|
+
or that there are particular issues that you should know about before implementing the change.
|
20
|
+
|
21
|
+
### Submitting your changes
|
22
|
+
|
23
|
+
Generally, we require that you test any code you are adding or modifying.
|
24
|
+
Once your changes are ready to submit for review:
|
25
|
+
|
26
|
+
1. Sign the Contributor License Agreement
|
27
|
+
|
28
|
+
Please make sure you have signed our [Contributor License Agreement](https://www.elastic.co/contributor-agreement/).
|
29
|
+
We are not asking you to assign copyright to us,
|
30
|
+
but to give us the right to distribute your code without restriction.
|
31
|
+
We ask this of all contributors in order to assure our users of the origin and continuing existence of the code.
|
32
|
+
You only need to sign the CLA once.
|
33
|
+
|
34
|
+
2. Test your changes
|
35
|
+
|
36
|
+
Run the test suite to make sure that nothing is broken.
|
37
|
+
See [testing](#testing) for details.
|
38
|
+
|
39
|
+
3. Rebase your changes
|
40
|
+
|
41
|
+
Update your local repository with the most recent code from the main repo,
|
42
|
+
and rebase your branch on top of the latest master branch.
|
43
|
+
We prefer your initial changes to be squashed into a single commit.
|
44
|
+
Later,
|
45
|
+
if we ask you to make changes,
|
46
|
+
add them as separate commits.
|
47
|
+
This makes them easier to review.
|
48
|
+
As a final step before merging we will either ask you to squash all commits yourself or we'll do it for you.
|
49
|
+
|
50
|
+
4. Submit a pull request
|
51
|
+
|
52
|
+
Push your local changes to your forked copy of the repository and [submit a pull request](https://help.github.com/articles/using-pull-requests).
|
53
|
+
In the pull request,
|
54
|
+
choose a title which sums up the changes that you have made,
|
55
|
+
and in the body provide more details about what your changes do.
|
56
|
+
Also mention the number of the issue where discussion has taken place,
|
57
|
+
eg "Closes #123".
|
58
|
+
|
59
|
+
5. Be patient
|
60
|
+
|
61
|
+
We might not be able to review your code as fast as we would like to,
|
62
|
+
but we'll do our best to dedicate it the attention it deserves.
|
63
|
+
Your effort is much appreciated!
|
64
|
+
|
65
|
+
### Workflow
|
66
|
+
|
67
|
+
All feature development and most bug fixes hit the master branch first.
|
68
|
+
Pull requests should be reviewed by someone with commit access.
|
69
|
+
Once approved, the author of the pull request,
|
70
|
+
or reviewer if the author does not have commit access,
|
71
|
+
should "Squash and merge".
|
72
|
+
|
73
|
+
### Testing
|
74
|
+
|
75
|
+
To do a full test run, use either `bundle exec rspec` or `rake spec`. Individual specs should also run as expected. The Mongo test needs a Mongo instance running, but will start one itself if Docker is installed.
|
76
|
+
|
77
|
+
To test other platform, use the Docker setup and scripts like `spec.sh RUBY FRAMEWORK`.
|
78
|
+
|
79
|
+
```sh
|
80
|
+
$ spec/scripts/spec.sh ruby-2.6 rails-5.2
|
81
|
+
```
|
82
|
+
|
83
|
+
### Releasing
|
84
|
+
|
85
|
+
To release a new version:
|
86
|
+
|
87
|
+
1. Update `VERSION` in `lib/elastic_apm/version.rb` according to the changes (major, minor, patch).
|
88
|
+
2. Update `CHANGELOG.md` to reflect the new version -- change _Unreleased_ section to _Version (release date)_.
|
89
|
+
3. Run `rake release`. This will...
|
90
|
+
1. Tag the current commit as new version.
|
91
|
+
2. Push the tag to GitHub.
|
92
|
+
3. Build the gem and upload to Rubygems (local user needs to be signed in and authorized.)
|
93
|
+
4. Update `2.x` branch to be at released commit and push it to GitHub.
|
data/Gemfile
CHANGED
@@ -22,6 +22,8 @@ gem 'opentracing', require: nil
|
|
22
22
|
gem 'rake', require: nil
|
23
23
|
gem 'sequel', require: nil
|
24
24
|
gem 'sidekiq', require: nil
|
25
|
+
gem 'simplecov', require: false, group: :test
|
26
|
+
gem 'simplecov-cobertura', require: false, group: :test
|
25
27
|
gem 'yard', require: nil
|
26
28
|
gem 'yarjuf'
|
27
29
|
|
@@ -43,7 +45,7 @@ else
|
|
43
45
|
gem framework
|
44
46
|
end
|
45
47
|
|
46
|
-
unless version
|
48
|
+
unless version =~ /^(master|6)/
|
47
49
|
gem 'delayed_job', require: nil
|
48
50
|
end
|
49
51
|
|
data/Jenkinsfile
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
#!/usr/bin/env groovy
|
2
|
+
@Library('apm@v1.0.7') _
|
3
|
+
|
4
|
+
import co.elastic.matrix.*
|
5
|
+
import groovy.transform.Field
|
6
|
+
|
7
|
+
/**
|
8
|
+
This is the parallel tasks generator,
|
9
|
+
it is need as field to store the results of the tests.
|
10
|
+
*/
|
11
|
+
@Field def rubyTasksGen
|
12
|
+
|
13
|
+
pipeline {
|
14
|
+
agent any
|
15
|
+
environment {
|
16
|
+
BASE_DIR="src/github.com/elastic/apm-agent-ruby"
|
17
|
+
PIPELINE_LOG_LEVEL='INFO'
|
18
|
+
NOTIFY_TO = credentials('notify-to')
|
19
|
+
JOB_GCS_BUCKET = credentials('gcs-bucket')
|
20
|
+
}
|
21
|
+
options {
|
22
|
+
timeout(time: 2, unit: 'HOURS')
|
23
|
+
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20', daysToKeepStr: '30'))
|
24
|
+
timestamps()
|
25
|
+
ansiColor('xterm')
|
26
|
+
disableResume()
|
27
|
+
durabilityHint('PERFORMANCE_OPTIMIZED')
|
28
|
+
}
|
29
|
+
triggers {
|
30
|
+
issueCommentTrigger('.*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
|
31
|
+
}
|
32
|
+
parameters {
|
33
|
+
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.')
|
34
|
+
booleanParam(name: 'doc_ci', defaultValue: true, description: 'Enable build docs.')
|
35
|
+
booleanParam(name: 'bench_ci', defaultValue: true, description: 'Enable run benchmarks.')
|
36
|
+
}
|
37
|
+
stages {
|
38
|
+
/**
|
39
|
+
Checkout the code and stash it, to use it on other stages.
|
40
|
+
*/
|
41
|
+
stage('Checkout') {
|
42
|
+
agent { label 'flyweight' }
|
43
|
+
options { skipDefaultCheckout() }
|
44
|
+
steps {
|
45
|
+
deleteDir()
|
46
|
+
gitCheckout(basedir: "${BASE_DIR}")
|
47
|
+
stash allowEmpty: true, name: 'source', useDefaultExcludes: false
|
48
|
+
}
|
49
|
+
}
|
50
|
+
/**
|
51
|
+
Execute unit tests.
|
52
|
+
*/
|
53
|
+
stage('Test') {
|
54
|
+
agent { label 'flyweight' }
|
55
|
+
options { skipDefaultCheckout() }
|
56
|
+
steps {
|
57
|
+
deleteDir()
|
58
|
+
unstash "source"
|
59
|
+
dir("${BASE_DIR}"){
|
60
|
+
script {
|
61
|
+
rubyTasksGen = new RubyParallelTaskGenerator(
|
62
|
+
xKey: 'RUBY_VERSION',
|
63
|
+
yKey: 'FRAMEWORK',
|
64
|
+
xFile: "./spec/.jenkins_ruby.yml",
|
65
|
+
yFile: "./spec/.jenkins_framework.yml",
|
66
|
+
exclusionFile: "./spec/.jenkins_exclude.yml",
|
67
|
+
tag: "Ruby",
|
68
|
+
name: "Ruby",
|
69
|
+
steps: this
|
70
|
+
)
|
71
|
+
def mapPatallelTasks = rubyTasksGen.generateParallelTests()
|
72
|
+
parallel(mapPatallelTasks)
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
stage('Benchmarks') {
|
78
|
+
options { skipDefaultCheckout() }
|
79
|
+
when {
|
80
|
+
beforeAgent true
|
81
|
+
allOf {
|
82
|
+
anyOf {
|
83
|
+
not {
|
84
|
+
changeRequest()
|
85
|
+
}
|
86
|
+
branch 'master'
|
87
|
+
branch "\\d+\\.\\d+"
|
88
|
+
branch "v\\d?"
|
89
|
+
tag "v\\d+\\.\\d+\\.\\d+*"
|
90
|
+
expression { return params.Run_As_Master_Branch }
|
91
|
+
}
|
92
|
+
expression { return params.bench_ci }
|
93
|
+
}
|
94
|
+
}
|
95
|
+
stages {
|
96
|
+
stage('Clean Workspace') {
|
97
|
+
agent { label 'metal' }
|
98
|
+
steps {
|
99
|
+
echo "Cleaning Workspace"
|
100
|
+
}
|
101
|
+
post {
|
102
|
+
always {
|
103
|
+
cleanWs()
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
/**
|
108
|
+
Run the benchmarks and store the results on ES.
|
109
|
+
The result JSON files are also archive into Jenkins.
|
110
|
+
*/
|
111
|
+
stage('Run Benchmarks') {
|
112
|
+
agent { label 'linux && immutable' }
|
113
|
+
steps {
|
114
|
+
deleteDir()
|
115
|
+
unstash 'source'
|
116
|
+
dir("${BASE_DIR}"){
|
117
|
+
script {
|
118
|
+
def versions = readYaml(file: "./spec/.jenkins_ruby.yml")
|
119
|
+
def benchmarkTask = [:]
|
120
|
+
versions['RUBY_VERSION'].each{ v ->
|
121
|
+
benchmarkTask[v] = runBenchmark(v)
|
122
|
+
}
|
123
|
+
parallel(benchmarkTask)
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
/**
|
131
|
+
Build the documentation.
|
132
|
+
*/
|
133
|
+
stage('Documentation') {
|
134
|
+
agent { label 'linux && immutable' }
|
135
|
+
options { skipDefaultCheckout() }
|
136
|
+
when {
|
137
|
+
beforeAgent true
|
138
|
+
allOf {
|
139
|
+
anyOf {
|
140
|
+
not {
|
141
|
+
changeRequest()
|
142
|
+
}
|
143
|
+
branch 'master'
|
144
|
+
branch "\\d+\\.\\d+"
|
145
|
+
branch "v\\d?"
|
146
|
+
tag "v\\d+\\.\\d+\\.\\d+*"
|
147
|
+
expression { return params.Run_As_Master_Branch }
|
148
|
+
}
|
149
|
+
expression { return params.doc_ci }
|
150
|
+
}
|
151
|
+
}
|
152
|
+
steps {
|
153
|
+
deleteDir()
|
154
|
+
unstash 'source'
|
155
|
+
buildDocs(docsDir: "${BASE_DIR}/docs", archive: true)
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
post {
|
160
|
+
always{
|
161
|
+
script{
|
162
|
+
if(rubyTasksGen?.results){
|
163
|
+
writeJSON(file: 'results.json', json: toJSON(rubyTasksGen.results), pretty: 2)
|
164
|
+
def mapResults = ["Ruby": rubyTasksGen.results]
|
165
|
+
def processor = new ResultsProcessor()
|
166
|
+
processor.processResults(mapResults)
|
167
|
+
archiveArtifacts allowEmptyArchive: true, artifacts: 'results.json,results.html', defaultExcludes: false
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
success {
|
172
|
+
echoColor(text: '[SUCCESS]', colorfg: 'green', colorbg: 'default')
|
173
|
+
}
|
174
|
+
aborted {
|
175
|
+
echoColor(text: '[ABORTED]', colorfg: 'magenta', colorbg: 'default')
|
176
|
+
}
|
177
|
+
failure {
|
178
|
+
echoColor(text: '[FAILURE]', colorfg: 'red', colorbg: 'default')
|
179
|
+
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "${NOTIFY_TO}", sendToIndividuals: false])
|
180
|
+
}
|
181
|
+
unstable {
|
182
|
+
echoColor(text: '[UNSTABLE]', colorfg: 'yellow', colorbg: 'default')
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
/**
|
188
|
+
Parallel task generator for the integration tests.
|
189
|
+
*/
|
190
|
+
class RubyParallelTaskGenerator extends DefaultParallelTaskGenerator {
|
191
|
+
|
192
|
+
public RubyParallelTaskGenerator(Map params){
|
193
|
+
super(params)
|
194
|
+
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
build a clousure that launch and agent and execute the corresponding test script,
|
198
|
+
then store the results.
|
199
|
+
*/
|
200
|
+
public Closure generateStep(x, y){
|
201
|
+
return {
|
202
|
+
steps.node('linux && immutable'){
|
203
|
+
def label = "${tag}:${x}#${y}"
|
204
|
+
try {
|
205
|
+
steps.runScript(label: label, ruby: x, framework: y)
|
206
|
+
saveResult(x, y, 1)
|
207
|
+
} catch(e){
|
208
|
+
saveResult(x, y, 0)
|
209
|
+
error("${label} tests failed : ${e.toString()}\n")
|
210
|
+
} finally {
|
211
|
+
steps.junit(allowEmptyResults: false,
|
212
|
+
keepLongStdio: true,
|
213
|
+
testResults: "**/spec/ruby-agent-junit.xml")
|
214
|
+
steps.codecov(repo: 'apm-agent-ruby', basedir: "${steps.env.BASE_DIR}")
|
215
|
+
}
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
/**
|
222
|
+
Run tests for a Ruby version and framework version.
|
223
|
+
*/
|
224
|
+
def runScript(Map params = [:]){
|
225
|
+
def label = params.label
|
226
|
+
def ruby = params.ruby
|
227
|
+
def framework = params.framework
|
228
|
+
log(level: 'INFO', text: "${label}")
|
229
|
+
env.HOME = "${env.WORKSPACE}"
|
230
|
+
env.PATH = "${env.PATH}:${env.WORKSPACE}/bin"
|
231
|
+
deleteDir()
|
232
|
+
unstash 'source'
|
233
|
+
dir("${BASE_DIR}"){
|
234
|
+
retry(2){
|
235
|
+
sleep randomNumber(min:10, max: 30)
|
236
|
+
sh("./spec/scripts/spec.sh ${ruby} ${framework}")
|
237
|
+
}
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
/**
|
242
|
+
Run benchmarks for a Ruby version, then report the results to the Elasticsearch server.
|
243
|
+
*/
|
244
|
+
def runBenchmark(version){
|
245
|
+
return {
|
246
|
+
node('metal'){
|
247
|
+
env.HOME = "${env.WORKSPACE}/${version}"
|
248
|
+
dir("${version}"){
|
249
|
+
deleteDir()
|
250
|
+
unstash 'source'
|
251
|
+
dir("${BASE_DIR}"){
|
252
|
+
try{
|
253
|
+
sh "./spec/scripts/benchmarks.sh ${version}"
|
254
|
+
} catch(e){
|
255
|
+
throw e
|
256
|
+
} finally {
|
257
|
+
sendBenchmarks(file: "benchmark-${version}.bulk",
|
258
|
+
index: "benchmark-ruby", archive: true)
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# elastic-apm
|
2
2
|
## Elastic APM agent for ♦️Ruby
|
3
3
|
|
4
|
-
[](https://apm-ci.elastic.co/job/elastic+apm-agent-ruby+master/) [](https://rubygems.org/gems/elastic-apm)
|
4
|
+
[](https://apm-ci.elastic.co/job/elastic+apm-agent-ruby+master/) [](https://rubygems.org/gems/elastic-apm) [](https://codecov.io/gh/elastic/apm-agent-ruby)
|
5
5
|
|
6
6
|
The official Rubygem for [Elastic][] [APM][].
|
7
7
|
|
data/bench/report.rb
CHANGED
@@ -5,33 +5,10 @@ Encoding.default_external = 'utf-8'
|
|
5
5
|
|
6
6
|
require 'time'
|
7
7
|
require 'bundler/setup'
|
8
|
-
require 'faraday'
|
9
8
|
require 'json'
|
10
9
|
|
11
|
-
ELASTICSEARCH_URL = ENV.fetch('CLOUD_ADDR') { '' }.chomp
|
12
|
-
if ELASTICSEARCH_URL == ''
|
13
|
-
puts 'ELASTICSEARCH_URL missing, exiting ...'
|
14
|
-
exit 1
|
15
|
-
else
|
16
|
-
# DEBUG
|
17
|
-
# puts ELASTICSEARCH_URL.gsub(/:[^\/]+(.*)@/) do |m|
|
18
|
-
# ":#{Array.new(m.length - 2).map { '*' }.join}@"
|
19
|
-
# end
|
20
|
-
end
|
21
|
-
|
22
|
-
CONN = Faraday.new(url: ELASTICSEARCH_URL) do |f|
|
23
|
-
# f.response :logger
|
24
|
-
f.adapter Faraday.default_adapter
|
25
|
-
end
|
26
|
-
|
27
|
-
healthcheck = CONN.get('/microbenchmark*/_search')
|
28
|
-
if healthcheck.status != 200
|
29
|
-
puts healthcheck.body.to_s
|
30
|
-
exit 1
|
31
|
-
end
|
32
|
-
|
33
10
|
input = STDIN.read.split("\n")
|
34
|
-
puts input
|
11
|
+
STDERR.puts input
|
35
12
|
|
36
13
|
titles = input.grep(/^===/).map { |t| t.gsub(/^=== /, '') }
|
37
14
|
counts = input.grep(/^Count: /).map { |a| a.gsub(/^Count: /, '').to_i }
|
@@ -60,14 +37,10 @@ payloads = titles.zip(averages, counts).map do |(title, avg, count)|
|
|
60
37
|
}
|
61
38
|
end.compact
|
62
39
|
|
63
|
-
puts '=== Reporting to ES'
|
64
|
-
puts payloads.inspect
|
40
|
+
STDERR.puts '=== Reporting to ES'
|
41
|
+
STDERR.puts payloads.inspect
|
65
42
|
|
66
43
|
payloads.each do |payload|
|
67
|
-
|
68
|
-
|
69
|
-
req.body = payload.to_json
|
70
|
-
end
|
71
|
-
|
72
|
-
puts result.body unless (200...300).include?(result.status)
|
44
|
+
puts '{ "index" : { "_index" : "benchmark-ruby", "_type" : "_doc" } }'
|
45
|
+
puts payload.to_json
|
73
46
|
end
|
data/docs/configuration.asciidoc
CHANGED
@@ -129,7 +129,7 @@ WARNING: Secret tokens only provide any real security if your APM server use TLS
|
|
129
129
|
|
130
130
|
Maximum amount of objects kept in queue, before sending to APM Server.
|
131
131
|
|
132
|
-
If you hit this limit you either have to increase the agent's
|
132
|
+
If you hit this limit you either have to increase the agent's
|
133
133
|
<<config-pool-size,worker pool size>> or it could mean the agent has trouble
|
134
134
|
connecting to APM Server. The <<config-log-path,logs>> should tell you what
|
135
135
|
went wrong.
|
@@ -512,6 +512,18 @@ Set it to `0` to disable stack trace collection for all spans.
|
|
512
512
|
|
513
513
|
It has to be provided in *<<config-format-duration, duration format>>*.
|
514
514
|
|
515
|
+
[float]
|
516
|
+
[[config-ssl-ca-cert]]
|
517
|
+
==== `server_ca_cert`
|
518
|
+
|
519
|
+
[options="header"]
|
520
|
+
|============
|
521
|
+
| Environment | `Config` key | Default | Example
|
522
|
+
| `ELASTIC_APM_SERVER_CA_CERT` | `server_ca_cert` | `nil` | `'/path/to/ca.pem'`
|
523
|
+
|============
|
524
|
+
|
525
|
+
The path to a custom CA certificate for connecting to APM Server.
|
526
|
+
|
515
527
|
[float]
|
516
528
|
[[config-transaction-max-spans]]
|
517
529
|
==== `transaction_max_spans`
|
@@ -53,11 +53,11 @@ See <<getting-started-rack>>.
|
|
53
53
|
|
54
54
|
We automatically instrument database actions using:
|
55
55
|
|
56
|
-
- ActiveRecord
|
57
|
-
- Elasticsearch
|
58
|
-
- Mongo
|
59
|
-
- Redis
|
60
|
-
- Sequel
|
56
|
+
- ActiveRecord (v4.2+)
|
57
|
+
- Elasticsearch (v0.9+)
|
58
|
+
- Mongo (v2.1+)
|
59
|
+
- Redis (v3.1+)
|
60
|
+
- Sequel (v4.35+)
|
61
61
|
|
62
62
|
[float]
|
63
63
|
[[supported-technologies-http]]
|
@@ -67,4 +67,5 @@ We automatically instrument and add support for distributed tracing to external
|
|
67
67
|
requests using these libraries:
|
68
68
|
|
69
69
|
- `net/http`
|
70
|
-
- Http.rb
|
70
|
+
- Http.rb (v0.6+)
|
71
|
+
- Faraday (v0.2.1+)
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -22,7 +22,7 @@ module ElasticAPM
|
|
22
22
|
api_buffer_size: 256,
|
23
23
|
api_request_size: '750kb',
|
24
24
|
api_request_time: '10s',
|
25
|
-
capture_body:
|
25
|
+
capture_body: false,
|
26
26
|
capture_headers: true,
|
27
27
|
capture_env: true,
|
28
28
|
current_user_email_method: :email,
|
@@ -81,6 +81,7 @@ module ElasticAPM
|
|
81
81
|
'ELASTIC_APM_LOG_PATH' => 'log_path',
|
82
82
|
'ELASTIC_APM_METRICS_INTERVAL' => [:int, 'metrics_interval'],
|
83
83
|
'ELASTIC_APM_POOL_SIZE' => [:int, 'pool_size'],
|
84
|
+
'ELASTIC_APM_SERVER_CA_CERT' => 'server_ca_cert',
|
84
85
|
'ELASTIC_APM_SERVICE_NAME' => 'service_name',
|
85
86
|
'ELASTIC_APM_SERVICE_VERSION' => 'service_version',
|
86
87
|
'ELASTIC_APM_SOURCE_LINES_ERROR_APP_FRAMES' =>
|
@@ -156,6 +157,7 @@ module ElasticAPM
|
|
156
157
|
attr_accessor :logger
|
157
158
|
attr_accessor :metrics_interval
|
158
159
|
attr_accessor :pool_size
|
160
|
+
attr_accessor :server_ca_cert
|
159
161
|
attr_accessor :service_name
|
160
162
|
attr_accessor :service_version
|
161
163
|
attr_accessor :source_lines_error_app_frames
|
@@ -3,6 +3,9 @@
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
5
|
class ContextBuilder
|
6
|
+
MAX_BODY_LENGTH = 2048
|
7
|
+
SKIPPED = '[SKIPPED]'
|
8
|
+
|
6
9
|
def initialize(config)
|
7
10
|
@config = config
|
8
11
|
end
|
@@ -29,7 +32,7 @@ module ElasticAPM
|
|
29
32
|
request.method = req.request_method
|
30
33
|
request.url = Context::Request::Url.new(req)
|
31
34
|
|
32
|
-
request.body = get_body(req)
|
35
|
+
request.body = config.capture_body? ? get_body(req) : SKIPPED
|
33
36
|
|
34
37
|
headers, env = get_headers_and_env(rack_env)
|
35
38
|
request.headers = headers if config.capture_headers?
|
@@ -40,11 +43,16 @@ module ElasticAPM
|
|
40
43
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
41
44
|
|
42
45
|
def get_body(req)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
case req.media_type
|
47
|
+
when 'application/x-www-form-urlencoded'
|
48
|
+
req.POST
|
49
|
+
when 'multipart/form-data'
|
50
|
+
req.POST
|
51
|
+
else
|
52
|
+
body = req.body.read
|
53
|
+
req.body.rewind
|
54
|
+
body.byteslice(0, MAX_BODY_LENGTH).force_encoding('utf-8')
|
55
|
+
end
|
48
56
|
end
|
49
57
|
|
50
58
|
def rails_req?(env)
|
@@ -4,14 +4,17 @@ module ElasticAPM
|
|
4
4
|
# @api private
|
5
5
|
module Deprecations
|
6
6
|
def deprecate(name, replacement = nil)
|
7
|
+
alias_name = "#{name.to_s.chomp('=')}__deprecated_"
|
8
|
+
alias_name += '=' if name.to_s.end_with?('=')
|
9
|
+
|
7
10
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
8
|
-
alias :"#{
|
11
|
+
alias :"#{alias_name}" :"#{name}"
|
9
12
|
|
10
13
|
def #{name}(*args, &block)
|
11
14
|
warn "[ElasticAPM] [DEPRECATED] `#{name}' is being removed. " \
|
12
|
-
|
13
|
-
|
14
|
-
#{
|
15
|
+
"#{replacement && "See `#{replacement}'."}" \
|
16
|
+
"\nCalled from \#{caller.first}"
|
17
|
+
send("#{alias_name}", *args, &block)
|
15
18
|
end
|
16
19
|
RUBY
|
17
20
|
end
|
@@ -152,13 +152,12 @@ module ElasticAPM
|
|
152
152
|
parent = current_span || transaction
|
153
153
|
|
154
154
|
span = Span.new(
|
155
|
-
name,
|
156
|
-
type,
|
155
|
+
name: name,
|
157
156
|
transaction_id: transaction.id,
|
158
|
-
|
157
|
+
trace_context: trace_context || parent.trace_context.child,
|
158
|
+
type: type,
|
159
159
|
context: context,
|
160
|
-
stacktrace_builder: stacktrace_builder
|
161
|
-
trace_context: trace_context || parent.trace_context.child
|
160
|
+
stacktrace_builder: stacktrace_builder
|
162
161
|
)
|
163
162
|
|
164
163
|
if backtrace && config.span_frames_min_duration?
|
@@ -124,6 +124,19 @@ module ElasticAPM
|
|
124
124
|
class ProcStat
|
125
125
|
attr_reader :total, :usage
|
126
126
|
|
127
|
+
CPU_FIELDS = %i[
|
128
|
+
user
|
129
|
+
nice
|
130
|
+
system
|
131
|
+
idle
|
132
|
+
iowait
|
133
|
+
irq
|
134
|
+
softirq
|
135
|
+
steal
|
136
|
+
guest
|
137
|
+
guest_nice
|
138
|
+
].freeze
|
139
|
+
|
127
140
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
128
141
|
def read!
|
129
142
|
stat =
|
@@ -133,20 +146,22 @@ module ElasticAPM
|
|
133
146
|
.split
|
134
147
|
.map(&:to_i)[1..-1]
|
135
148
|
|
136
|
-
|
137
|
-
|
149
|
+
values =
|
150
|
+
CPU_FIELDS.each_with_index.each_with_object({}) do |(key, i), v|
|
151
|
+
v[key] = stat[i] || 0
|
152
|
+
end
|
138
153
|
|
139
154
|
@total =
|
140
|
-
user +
|
141
|
-
nice +
|
142
|
-
system +
|
143
|
-
idle +
|
144
|
-
iowait +
|
145
|
-
irq +
|
146
|
-
softirq +
|
147
|
-
steal
|
148
|
-
|
149
|
-
@usage = @total - (idle + iowait)
|
155
|
+
values[:user] +
|
156
|
+
values[:nice] +
|
157
|
+
values[:system] +
|
158
|
+
values[:idle] +
|
159
|
+
values[:iowait] +
|
160
|
+
values[:irq] +
|
161
|
+
values[:softirq] +
|
162
|
+
values[:steal]
|
163
|
+
|
164
|
+
@usage = @total - (values[:idle] + values[:iowait])
|
150
165
|
|
151
166
|
self
|
152
167
|
end
|
@@ -93,28 +93,20 @@ module ElasticAPM
|
|
93
93
|
|
94
94
|
# @api private
|
95
95
|
class SpanContext
|
96
|
-
def initialize(
|
96
|
+
def initialize(trace_context:, baggage: nil)
|
97
97
|
if baggage
|
98
98
|
ElasticAPM.agent.config.logger.warn(
|
99
99
|
'Baggage is not supported by ElasticAPM'
|
100
100
|
)
|
101
101
|
end
|
102
102
|
|
103
|
-
@
|
104
|
-
@trace_id = trace_id
|
105
|
-
@trace_context =
|
106
|
-
ElasticAPM::TraceContext.new(trace_id: trace_id, span_id: id)
|
103
|
+
@trace_context = trace_context
|
107
104
|
end
|
108
105
|
|
109
|
-
attr_accessor :
|
106
|
+
attr_accessor :trace_context
|
110
107
|
|
111
108
|
def self.from_trace_context(trace_context)
|
112
|
-
new(
|
113
|
-
trace_id: trace_context.trace_id,
|
114
|
-
id: trace_context.span_id
|
115
|
-
).tap do |span_context|
|
116
|
-
span_context.trace_context = trace_context
|
117
|
-
end
|
109
|
+
new(trace_context: trace_context)
|
118
110
|
end
|
119
111
|
end
|
120
112
|
|
data/lib/elastic_apm/span.rb
CHANGED
@@ -1,48 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'securerandom'
|
4
|
+
require 'forwardable'
|
4
5
|
|
5
6
|
require 'elastic_apm/span/context'
|
6
7
|
|
7
8
|
module ElasticAPM
|
8
9
|
# @api private
|
9
10
|
class Span
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
def_delegators :@trace_context, :trace_id, :parent_id, :id
|
14
|
+
|
10
15
|
DEFAULT_TYPE = 'custom'
|
11
16
|
|
12
17
|
# rubocop:disable Metrics/ParameterLists
|
13
18
|
def initialize(
|
14
|
-
name
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
name:,
|
20
|
+
transaction_id:,
|
21
|
+
trace_context:,
|
22
|
+
type: nil,
|
18
23
|
context: nil,
|
19
|
-
stacktrace_builder: nil
|
20
|
-
trace_context: nil
|
24
|
+
stacktrace_builder: nil
|
21
25
|
)
|
22
26
|
@name = name
|
23
27
|
@type = type || DEFAULT_TYPE
|
24
28
|
|
25
29
|
@transaction_id = transaction_id
|
26
|
-
|
27
|
-
@parent_id = parent_id
|
28
|
-
@trace_context = trace_context || TraceContext.for_span
|
30
|
+
@trace_context = trace_context
|
29
31
|
|
30
32
|
@context = context || Span::Context.new
|
31
33
|
@stacktrace_builder = stacktrace_builder
|
32
34
|
end
|
33
35
|
# rubocop:enable Metrics/ParameterLists
|
34
36
|
|
35
|
-
attr_accessor :name, :type, :original_backtrace, :
|
37
|
+
attr_accessor :name, :type, :original_backtrace, :trace_context
|
36
38
|
attr_reader :context, :stacktrace, :duration, :timestamp, :transaction_id
|
37
39
|
|
38
|
-
def id
|
39
|
-
trace_context&.span_id
|
40
|
-
end
|
41
|
-
|
42
|
-
def trace_id
|
43
|
-
trace_context&.trace_id
|
44
|
-
end
|
45
|
-
|
46
40
|
# life cycle
|
47
41
|
|
48
42
|
def start(timestamp = Util.micros)
|
@@ -3,56 +3,47 @@
|
|
3
3
|
module ElasticAPM
|
4
4
|
# @api private
|
5
5
|
class TraceContext
|
6
|
+
extend Deprecations
|
6
7
|
class InvalidTraceparentHeader < StandardError; end
|
7
8
|
|
8
9
|
VERSION = '00'
|
9
10
|
HEX_REGEX = /[^[:xdigit:]]/.freeze
|
10
11
|
|
12
|
+
TRACE_ID_LENGTH = 16
|
13
|
+
ID_LENGTH = 8
|
14
|
+
|
11
15
|
def initialize(
|
12
16
|
version: VERSION,
|
13
17
|
trace_id: nil,
|
14
18
|
span_id: nil,
|
19
|
+
id: nil,
|
15
20
|
recorded: true
|
16
21
|
)
|
17
22
|
@version = version
|
18
|
-
@trace_id = trace_id
|
19
|
-
|
23
|
+
@trace_id = trace_id || hex(TRACE_ID_LENGTH)
|
24
|
+
# TODO: rename to parent_id with next major version bump
|
25
|
+
@parent_id = span_id
|
26
|
+
@id = id || hex(ID_LENGTH)
|
20
27
|
@recorded = recorded
|
21
28
|
end
|
22
29
|
|
23
|
-
attr_accessor :version, :trace_id, :
|
30
|
+
attr_accessor :version, :id, :trace_id, :parent_id, :recorded
|
24
31
|
|
25
32
|
alias :recorded? :recorded
|
26
33
|
|
27
|
-
def self.for_transaction(sampled: true)
|
28
|
-
new.tap do |t|
|
29
|
-
t.trace_id = SecureRandom.hex(16)
|
30
|
-
t.span_id = SecureRandom.hex(8)
|
31
|
-
t.recorded = sampled
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.for_span
|
36
|
-
new.tap do |t|
|
37
|
-
t.trace_id = SecureRandom.hex(16)
|
38
|
-
t.span_id = SecureRandom.hex(8)
|
39
|
-
t.recorded = true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
34
|
# rubocop:disable Metrics/AbcSize
|
44
35
|
def self.parse(header)
|
45
36
|
raise InvalidTraceparentHeader unless header.length == 55
|
46
37
|
raise InvalidTraceparentHeader unless header[0..1] == VERSION
|
47
38
|
|
48
39
|
new.tap do |t|
|
49
|
-
t.version, t.trace_id, t.
|
40
|
+
t.version, t.trace_id, t.parent_id, t.flags =
|
50
41
|
header.split('-').tap do |values|
|
51
42
|
values[-1] = Util.hex_to_bits(values[-1])
|
52
43
|
end
|
53
44
|
|
54
45
|
raise InvalidTraceparentHeader if HEX_REGEX =~ t.trace_id
|
55
|
-
raise InvalidTraceparentHeader if HEX_REGEX =~ t.
|
46
|
+
raise InvalidTraceparentHeader if HEX_REGEX =~ t.parent_id
|
56
47
|
end
|
57
48
|
end
|
58
49
|
# rubocop:enable Metrics/AbcSize
|
@@ -71,12 +62,38 @@ module ElasticAPM
|
|
71
62
|
format('%02x', flags.to_i(2))
|
72
63
|
end
|
73
64
|
|
65
|
+
def ensure_parent_id
|
66
|
+
@parent_id ||= hex(ID_LENGTH)
|
67
|
+
end
|
68
|
+
|
74
69
|
def child
|
75
|
-
dup.tap
|
70
|
+
dup.tap do |tc|
|
71
|
+
tc.parent_id = tc.id
|
72
|
+
tc.id = hex(ID_LENGTH)
|
73
|
+
end
|
76
74
|
end
|
77
75
|
|
78
76
|
def to_header
|
79
|
-
format('%s-%s-%s-%s', version, trace_id,
|
77
|
+
format('%s-%s-%s-%s', version, trace_id, id, hex_flags)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @deprecated Use parent_id instead
|
81
|
+
def span_id
|
82
|
+
@parent_id
|
83
|
+
end
|
84
|
+
|
85
|
+
# @deprecated Use parent_id instead
|
86
|
+
def span_id=(span_id)
|
87
|
+
@parent_id = span_id
|
88
|
+
end
|
89
|
+
|
90
|
+
deprecate :span_id, :parent_id
|
91
|
+
deprecate :span_id=, :parent_id=
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def hex(len)
|
96
|
+
SecureRandom.hex(len)
|
80
97
|
end
|
81
98
|
end
|
82
99
|
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'securerandom'
|
4
|
+
require 'forwardable'
|
4
5
|
|
5
6
|
module ElasticAPM
|
6
7
|
# @api private
|
7
8
|
class Transaction
|
8
9
|
extend Deprecations
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
def_delegators :@trace_context,
|
13
|
+
:trace_id, :parent_id, :id, :ensure_parent_id
|
9
14
|
|
10
15
|
DEFAULT_TYPE = 'custom'
|
11
16
|
|
12
|
-
# rubocop:disable Metrics/ParameterLists
|
17
|
+
# rubocop:disable Metrics/ParameterLists
|
13
18
|
def initialize(
|
14
19
|
name = nil,
|
15
20
|
type = nil,
|
@@ -26,28 +31,19 @@ module ElasticAPM
|
|
26
31
|
@context = context || Context.new # TODO: Lazy generate this?
|
27
32
|
Util.reverse_merge!(@context.tags, tags) if tags
|
28
33
|
|
29
|
-
|
30
|
-
@parent_id = trace_context.span_id
|
31
|
-
@trace_context = trace_context
|
32
|
-
else
|
33
|
-
@trace_context = TraceContext.for_transaction(sampled: sampled)
|
34
|
-
end
|
34
|
+
@trace_context = trace_context || TraceContext.new(recorded: sampled)
|
35
35
|
|
36
36
|
@started_spans = 0
|
37
37
|
@dropped_spans = 0
|
38
38
|
|
39
39
|
@notifications = [] # for AS::Notifications
|
40
40
|
end
|
41
|
-
# rubocop:enable Metrics/ParameterLists
|
41
|
+
# rubocop:enable Metrics/ParameterLists
|
42
42
|
|
43
43
|
attr_accessor :name, :type, :result
|
44
44
|
|
45
45
|
attr_reader :context, :duration, :started_spans, :dropped_spans,
|
46
|
-
:timestamp, :trace_context, :notifications
|
47
|
-
|
48
|
-
def id
|
49
|
-
trace_context.span_id
|
50
|
-
end
|
46
|
+
:timestamp, :trace_context, :notifications
|
51
47
|
|
52
48
|
def sampled?
|
53
49
|
@sampled
|
@@ -63,10 +59,6 @@ module ElasticAPM
|
|
63
59
|
|
64
60
|
deprecate :done?, :stopped?
|
65
61
|
|
66
|
-
def trace_id
|
67
|
-
trace_context&.trace_id
|
68
|
-
end
|
69
|
-
|
70
62
|
# life cycle
|
71
63
|
|
72
64
|
def start(timestamp = Util.micros)
|
@@ -86,11 +78,6 @@ module ElasticAPM
|
|
86
78
|
self
|
87
79
|
end
|
88
80
|
|
89
|
-
def ensure_parent_id
|
90
|
-
@parent_id ||= SecureRandom.hex(8)
|
91
|
-
@parent_id
|
92
|
-
end
|
93
|
-
|
94
81
|
# spans
|
95
82
|
|
96
83
|
def inc_started_spans!
|
@@ -28,6 +28,7 @@ module ElasticAPM
|
|
28
28
|
}.freeze
|
29
29
|
GZIP_HEADERS = HEADERS.merge('Content-Encoding' => 'gzip').freeze
|
30
30
|
|
31
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
31
32
|
def initialize(config, metadata)
|
32
33
|
@config = config
|
33
34
|
@metadata = metadata.to_json
|
@@ -41,10 +42,16 @@ module ElasticAPM
|
|
41
42
|
headers['Authorization'] = "Bearer #{token}"
|
42
43
|
end
|
43
44
|
|
45
|
+
if config.use_ssl? && config.server_ca_cert
|
46
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
47
|
+
@ssl_context.ca_file = config.server_ca_cert
|
48
|
+
end
|
49
|
+
|
44
50
|
@client = HTTP.headers(headers).persistent(@url)
|
45
51
|
|
46
52
|
@mutex = Mutex.new
|
47
53
|
end
|
54
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
48
55
|
|
49
56
|
def write(str)
|
50
57
|
return if @config.disable_send
|
@@ -109,7 +116,12 @@ module ElasticAPM
|
|
109
116
|
@conn_thread = Thread.new do
|
110
117
|
begin
|
111
118
|
@connected = true
|
112
|
-
|
119
|
+
|
120
|
+
resp = @client.post(
|
121
|
+
@url,
|
122
|
+
body: @rd,
|
123
|
+
ssl_context: @ssl_context
|
124
|
+
).flush
|
113
125
|
rescue Exception => e
|
114
126
|
@connection_error = e
|
115
127
|
ensure
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'elastic_apm/transport/filters/request_body_filter'
|
4
3
|
require 'elastic_apm/transport/filters/secrets_filter'
|
5
4
|
|
6
5
|
module ElasticAPM
|
@@ -14,10 +13,7 @@ module ElasticAPM
|
|
14
13
|
# @api private
|
15
14
|
class Container
|
16
15
|
def initialize(config)
|
17
|
-
@filters = {
|
18
|
-
request_body: RequestBodyFilter.new(config),
|
19
|
-
secrets: SecretsFilter.new(config)
|
20
|
-
}
|
16
|
+
@filters = { secrets: SecretsFilter.new(config) }
|
21
17
|
end
|
22
18
|
|
23
19
|
def add(key, filter)
|
@@ -28,21 +28,21 @@ module ElasticAPM
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def call(payload)
|
31
|
-
strip_from payload
|
32
|
-
strip_from payload
|
33
|
-
strip_from payload
|
34
|
-
strip_from payload
|
31
|
+
strip_from! payload.dig(:transaction, :context, :request, :headers)
|
32
|
+
strip_from! payload.dig(:transaction, :context, :response, :headers)
|
33
|
+
strip_from! payload.dig(:error, :context, :request, :headers)
|
34
|
+
strip_from! payload.dig(:error, :context, :response, :headers)
|
35
|
+
strip_from! payload.dig(:transaction, :context, :request, :body)
|
35
36
|
|
36
37
|
payload
|
37
38
|
end
|
38
39
|
|
39
|
-
def strip_from(
|
40
|
-
return unless
|
41
|
-
return unless (headers = event.dig(*path))
|
40
|
+
def strip_from!(obj)
|
41
|
+
return unless obj && obj.is_a?(Hash)
|
42
42
|
|
43
|
-
|
43
|
+
obj.each do |k, v|
|
44
44
|
if filter_key?(k) || filter_value?(v)
|
45
|
-
|
45
|
+
obj[k] = FILTERED
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
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.
|
4
|
+
version: 2.4.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: 2019-
|
11
|
+
date: 2019-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -51,7 +51,9 @@ files:
|
|
51
51
|
- ".rubocop.yml"
|
52
52
|
- CHANGELOG.md
|
53
53
|
- CODE_OF_CONDUCT.md
|
54
|
+
- CONTRIBUTING.md
|
54
55
|
- Gemfile
|
56
|
+
- Jenkinsfile
|
55
57
|
- LICENSE
|
56
58
|
- README.md
|
57
59
|
- Rakefile
|
@@ -145,7 +147,6 @@ files:
|
|
145
147
|
- lib/elastic_apm/transport/base.rb
|
146
148
|
- lib/elastic_apm/transport/connection.rb
|
147
149
|
- lib/elastic_apm/transport/filters.rb
|
148
|
-
- lib/elastic_apm/transport/filters/request_body_filter.rb
|
149
150
|
- lib/elastic_apm/transport/filters/secrets_filter.rb
|
150
151
|
- lib/elastic_apm/transport/serializers.rb
|
151
152
|
- lib/elastic_apm/transport/serializers/context_serializer.rb
|
@@ -181,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
182
|
- !ruby/object:Gem::Version
|
182
183
|
version: '0'
|
183
184
|
requirements: []
|
184
|
-
rubygems_version: 3.0.
|
185
|
+
rubygems_version: 3.0.1
|
185
186
|
signing_key:
|
186
187
|
specification_version: 4
|
187
188
|
summary: The official Elastic APM agent for Ruby
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ElasticAPM
|
4
|
-
module Transport
|
5
|
-
module Filters
|
6
|
-
# @api private
|
7
|
-
class RequestBodyFilter
|
8
|
-
FILTERED = '[FILTERED]'
|
9
|
-
|
10
|
-
def initialize(config)
|
11
|
-
@config = config
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(payload)
|
15
|
-
strip_body_from payload[:transaction]
|
16
|
-
strip_body_from payload[:error]
|
17
|
-
|
18
|
-
payload
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def strip_body_from(payload)
|
24
|
-
return unless payload
|
25
|
-
return unless (request = payload.dig(:context, :request))
|
26
|
-
request[:body] = FILTERED
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|