honeycomb-beeline 2.3.0 → 2.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0606efad889f46b53eaa00c4a4c2f0e134641ce9a2427f65cc79eaf138a840be
4
- data.tar.gz: 95449860c9a30558bdb512b498f93fe0d00beca14b89582555e0cf2479316f74
3
+ metadata.gz: 8dfad7bddebd49b8645b61389e74035626a0cc817d5fc7ea9e51ab17cb571584
4
+ data.tar.gz: eadf7a28b41ddb6437e0e5a2c0824c2a2cf67fbf36a95bc18f77ad03b4f74306
5
5
  SHA512:
6
- metadata.gz: 0cf79345b6b669d4e07d02035840f7ba05bb508c9185259c7d308afd7cf18cb9d44c5c1592b04e445cf025037756a9c8512bfd436ea2e4c1f52884db9a08dbe7
7
- data.tar.gz: 7e73b0970480db0173ef147102da4ea9511e920457feea7178b1b4fd03905b4929c3581d01ec050586241028b7ec7921df5b90d466c882ea57d97ca69c58d5dd
6
+ metadata.gz: 7c6204f46a27e4a3af3bf5d2d173fdb4d06f820ecf76dd2ed84d0de52aca83fb155190075b244ee6ab7e811c93927874ae51d36cc117b018de995ad5aeb76f40
7
+ data.tar.gz: 175c355b5a5833bfd68b17a281fc2d71f0321f7c708e339b03090b367d64d7a6c9294ed8afcc84d5f538b6c80644f9c26488475962903a2364bb6ab0e7ee93f8
@@ -3,6 +3,10 @@
3
3
  set -ux
4
4
 
5
5
  if [[ "$BUNDLE_GEMFILE" =~ (rails_41.gemfile|rails_42.gemfile)$ ]]; then
6
+ echo "Rails 4.1 and 4.2 require an old Bundler"
6
7
  gem uninstall -v '>= 2' -ax bundler
7
8
  gem install bundler -v '< 2'
9
+ else
10
+ echo "Get the latest Bundler"
11
+ gem update bundler
8
12
  fi
data/.circleci/config.yml CHANGED
@@ -6,7 +6,6 @@ commands:
6
6
  type: string
7
7
  gemfile:
8
8
  type: string
9
- default: Gemfile
10
9
  command:
11
10
  type: string
12
11
  default: bundle exec rake test
@@ -14,28 +13,68 @@ commands:
14
13
  - checkout
15
14
  - restore_cache:
16
15
  keys:
17
- - gems-v1-<< parameters.ruby-version >>-{{ checksum "Gemfile.lock" }}
16
+ - gems-v1-<< parameters.ruby-version >>-<< parameters.gemfile >>-{{ checksum "Gemfile.lock" }}
17
+ - gems-v1-<< parameters.ruby-version >>-<< parameters.gemfile >>
18
18
  - gems-v1-<< parameters.ruby-version >>
19
- - run: gem update bundler
20
- - run: BUNDLE_GEMFILE=<< parameters.gemfile >> ./.circleci/bundler_version.sh
21
- - run: BUNDLE_GEMFILE=<< parameters.gemfile >> bundle install --jobs=4 --retry=3 --path vendor/bundle
19
+ - run: .circleci/bundler_version.sh
20
+ - run: bundle config set --local path $HOME/project/vendor/bundle
21
+ - run: bundle install --jobs=4 --retry=3
22
+ - run: bundle clean --force
23
+ - run: bundle env
22
24
  - save_cache:
23
25
  paths:
24
26
  - ./vendor/bundle
25
- key: gems-v1-<< parameters.ruby-version >>-{{ checksum "Gemfile.lock" }}
26
- - run: BUNDLE_GEMFILE=<< parameters.gemfile >> << parameters.command >>
27
+ key: gems-v1-<< parameters.ruby-version >>-<< parameters.gemfile >>-{{ checksum "Gemfile.lock" }}
28
+ - run: << parameters.command >>
27
29
 
28
30
  jobs:
29
- publish:
31
+ build_artifacts:
30
32
  docker:
31
- - image: circleci/ruby:2.6
33
+ - image: circleci/ruby:2.6
32
34
  steps:
33
35
  - checkout
36
+ - run: mkdir -p ~/artifacts
37
+ - run: gem build honeycomb-beeline.gemspec
38
+ - run: cp honeycomb-beeline-*.gem ~/artifacts/
39
+ - persist_to_workspace:
40
+ root: ~/
41
+ paths:
42
+ - artifacts
43
+ - store_artifacts:
44
+ path: ~/artifacts
45
+
46
+ publish_rubygems:
47
+ docker:
48
+ - image: circleci/ruby:2.6
49
+ steps:
50
+ - attach_workspace:
51
+ at: ~/
52
+ - run:
53
+ name: "Artifacts being published"
54
+ command: |
55
+ echo "about to publish to tag ${CIRCLE_TAG}"
56
+ ls -l ~/artifacts/*
57
+ - checkout
34
58
  - run:
35
59
  name: Setup Rubygems
36
60
  command: bash .circleci/setup-rubygems.sh
37
- - run: gem build honeycomb-beeline.gemspec
38
- - run: gem push honeycomb-beeline-*.gem
61
+ - run: gem push ~/artifacts/honeycomb-beeline-*.gem
62
+
63
+ publish_github:
64
+ docker:
65
+ - image: cibuilds/github:0.13.0
66
+ steps:
67
+ - attach_workspace:
68
+ at: ~/
69
+ - run:
70
+ name: "Artifacts being published"
71
+ command: |
72
+ echo "about to publish to tag ${CIRCLE_TAG}"
73
+ ls -l ~/artifacts/*
74
+ - run:
75
+ name: "GHR Draft"
76
+ command: ghr -draft -n ${CIRCLE_TAG} -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${CIRCLE_TAG} ~/artifacts
77
+
39
78
  lint:
40
79
  parameters:
41
80
  ruby-version:
@@ -43,9 +82,12 @@ jobs:
43
82
  default: "2.6"
44
83
  docker:
45
84
  - image: circleci/ruby:<< parameters.ruby-version >>
85
+ environment:
86
+ BUNDLE_GEMFILE: ./Gemfile
46
87
  steps:
47
88
  - ruby:
48
89
  ruby-version: << parameters.ruby-version >>
90
+ gemfile: root
49
91
  command: bundle exec rake rubocop
50
92
  test:
51
93
  parameters:
@@ -55,11 +97,15 @@ jobs:
55
97
  type: string
56
98
  docker:
57
99
  - image: circleci/ruby:<< parameters.ruby-version >>
100
+ environment:
101
+ BUNDLE_GEMFILE: gemfiles/<< parameters.gemfile >>.gemfile
58
102
  steps:
59
103
  - ruby:
60
104
  ruby-version: << parameters.ruby-version >>
61
105
  gemfile: << parameters.gemfile >>
62
106
  command: bundle exec rake test
107
+ - store_test_results:
108
+ path: test/reports
63
109
 
64
110
  workflows:
65
111
  nightly:
@@ -73,62 +119,68 @@ workflows:
73
119
  jobs:
74
120
  - lint
75
121
  - test: &test
122
+ name: test-<< matrix.gemfile >>-ruby_<< matrix.ruby-version >>
76
123
  requires:
77
124
  - lint
78
125
  matrix:
79
126
  parameters:
80
127
  ruby-version: ["2.2", "2.3", "2.4", "2.5", "2.6", "2.7"]
81
128
  gemfile:
82
- - gemfiles/aws_2.gemfile
83
- - gemfiles/aws_3.gemfile
84
- - gemfiles/faraday_0.gemfile
85
- - gemfiles/faraday_1.gemfile
86
- - gemfiles/sequel4.gemfile
87
- - gemfiles/sequel5.gemfile
88
- - gemfiles/sinatra.gemfile
89
- - gemfiles/rack.gemfile
90
- - gemfiles/rails_41.gemfile
91
- - gemfiles/rails_42.gemfile
92
- - gemfiles/rails_5.gemfile
93
- - gemfiles/rails_51.gemfile
94
- - gemfiles/rails_52.gemfile
95
- - gemfiles/rails_6.gemfile
96
- - gemfiles/redis_3.gemfile
97
- - gemfiles/redis_4.gemfile
129
+ - aws_2
130
+ - aws_3
131
+ - faraday_0
132
+ - faraday_1
133
+ - sequel4
134
+ - sequel5
135
+ - sinatra
136
+ - rack
137
+ - rails_41
138
+ - rails_42
139
+ - rails_5
140
+ - rails_51
141
+ - rails_52
142
+ - rails_6
143
+ - rails_61
144
+ - redis_3
145
+ - redis_4
98
146
  exclude:
99
147
  - ruby-version: "2.2"
100
- gemfile: gemfiles/faraday_1.gemfile
148
+ gemfile: faraday_1
149
+ - ruby-version: "2.2"
150
+ gemfile: rails_52
101
151
  - ruby-version: "2.2"
102
- gemfile: gemfiles/rails_52.gemfile
152
+ gemfile: rails_6
153
+ - ruby-version: "2.3"
154
+ gemfile: rails_6
155
+ - ruby-version: "2.4"
156
+ gemfile: rails_6
103
157
  - ruby-version: "2.2"
104
- gemfile: gemfiles/rails_6.gemfile
158
+ gemfile: rails_61
105
159
  - ruby-version: "2.3"
106
- gemfile: gemfiles/rails_6.gemfile
160
+ gemfile: rails_61
107
161
  - ruby-version: "2.4"
108
- gemfile: gemfiles/rails_6.gemfile
162
+ gemfile: rails_61
109
163
  - ruby-version: "2.4"
110
- gemfile: gemfiles/rails_41.gemfile
164
+ gemfile: rails_41
111
165
  - ruby-version: "2.5"
112
- gemfile: gemfiles/rails_41.gemfile
166
+ gemfile: rails_41
113
167
  - ruby-version: "2.6"
114
- gemfile: gemfiles/rails_41.gemfile
168
+ gemfile: rails_41
115
169
  - ruby-version: "2.7"
116
- gemfile: gemfiles/rails_41.gemfile
170
+ gemfile: rails_41
117
171
  - ruby-version: "2.7"
118
- gemfile: gemfiles/rails_42.gemfile
172
+ gemfile: rails_42
119
173
  beeline:
120
174
  jobs:
121
175
  - lint:
122
- filters:
176
+ filters: &regular_filters
123
177
  tags:
124
178
  only: /.*/
125
179
  - test:
126
180
  <<: *test
127
- filters:
128
- tags:
129
- only: /.*/
130
- - publish:
131
- filters:
181
+ filters: *regular_filters
182
+ - build_artifacts:
183
+ filters: &tag_filters
132
184
  tags:
133
185
  only: /^v.*/
134
186
  branches:
@@ -136,3 +188,10 @@ workflows:
136
188
  requires:
137
189
  - lint
138
190
  - test
191
+ - publish_rubygems: &publish
192
+ filters: *tag_filters
193
+ requires:
194
+ - build_artifacts
195
+ - publish_github:
196
+ <<: *publish
197
+ context: Honeycomb Secrets for Public Repos
data/.github/CODEOWNERS CHANGED
@@ -2,4 +2,4 @@
2
2
  # This file controls who is tagged for review for any given pull request.
3
3
 
4
4
  # For anything not explicitly taken by someone else:
5
- * @honeycombio/integrations-team @martin308
5
+ * @honeycombio/telemetry-team @martin308
@@ -0,0 +1,15 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "bundler" # See documentation for possible values
9
+ directory: "/gemfiles/" # Location of package manifests
10
+ schedule:
11
+ interval: "weekly"
12
+ labels:
13
+ - "type: dependencies"
14
+ reviewers:
15
+ - "honeycombio/telemetry-team"
@@ -0,0 +1,14 @@
1
+ name: Apply project management flow
2
+ on:
3
+ issues:
4
+ types: [opened]
5
+ pull_request_target:
6
+ types: [opened]
7
+ jobs:
8
+ project-management:
9
+ runs-on: ubuntu-latest
10
+ name: Apply project management flow
11
+ steps:
12
+ - uses: honeycombio/oss-management-actions/projects@v1
13
+ with:
14
+ ghprojects-token: ${{ secrets.GHPROJECTS_TOKEN }}
@@ -0,0 +1,10 @@
1
+ name: Apply project labels
2
+ on: [issues, pull_request, label]
3
+ jobs:
4
+ apply-labels:
5
+ runs-on: ubuntu-latest
6
+ name: Apply common project labels
7
+ steps:
8
+ - uses: honeycombio/oss-management-actions/labels@v1
9
+ with:
10
+ github-token: ${{ secrets.GITHUB_TOKEN }}
data/.gitignore CHANGED
@@ -5,6 +5,7 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
+ /test/reports/
8
9
  /tmp/
9
10
  .idea/
10
11
 
data/.rspec CHANGED
@@ -1,3 +1,7 @@
1
+ <% if ENV['CI'] %>
2
+ --format RspecJunitFormatter
3
+ --out test/reports/result.xml
4
+ <% end %>
1
5
  --format documentation
2
6
  --color
3
7
  --require spec_helper
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 2.7.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,116 @@
1
+ # beeline-ruby changelog
2
+
3
+ ## 2.5.0 2021-07-16
4
+
5
+ ### Added
6
+
7
+ - Allow backtrace to be sent with errors (#160) | [@lirossarvet](https://github.com/lirossarvet)
8
+
9
+ ### Maintenance
10
+
11
+ - Updates Github Action Workflows (#159) | [@bdarfler](https://github.com/bdarfler)
12
+ - Adds dependabot label (#158) | [@bdarfler](https://github.com/bdarfler)
13
+ - Switches CODEOWNERS to telemetry-team (#157) | [@bdarfler](https://github.com/bdarfler)
14
+
15
+ ## 2.4.2 2021-06-25
16
+
17
+ ### Fixes
18
+
19
+ - Update Rails middleware to get status code even on raised error. (#153) [@lirossarvet](https://github.com/lirossarvet)
20
+ - Make Rails spec consistent with Honeycomb Railtie Initialization. (#154) [@robbkidd](https://github.com/robbkidd)
21
+ - CI Improvements (#155) [@robbkidd](https://github.com/robbkidd)
22
+ - Improve performance of Redis command serialization. (#146) [@ajvondrak](https://github.com/ajvondrak)
23
+
24
+ ## 2.4.1 2021-06-01
25
+
26
+ ### Fixes
27
+
28
+ - Updates Redis event-field filter to handle string keys in options in
29
+ addition to symbol keys. (#147) [@cupakromer](https://github.com/cupakromer)
30
+
31
+ ### Maintenance
32
+
33
+ - Expanded on the Rails 5.2 example. (#141) [@robbkidd](https://github.com/robbkidd)
34
+ - Added a test case for current behavior of event emitted for an
35
+ exception raised in Rails. (@132) [@vreynolds](https://github.com/vreynolds)
36
+
37
+ ## 2.4.0 2021-01-07
38
+ ### Added
39
+ - Add support for HTTP Accept-Encoding header (#125) [@irvingreid](https://github.com/irvingreid)
40
+ - Add with_field, with_trace_field wrapper methods (#51) [@ajvondrak](https://github.com/ajvondrak)
41
+
42
+ ## 2.3.0 2020-11-06
43
+ ### Improvements
44
+ - Custom trace header hooks (#117)
45
+ - Add rspec filter :focus for assisting with debugging tests (#120)
46
+ - Be more lenient in expected output from AWS gem (#119)
47
+
48
+ ## 2.2.0 2020-09-02
49
+ ### New things
50
+ - refactor parsers/propagators, add w3c and aws parsers and propagators (#104) [@katiebayes](https://github.com/katiebayes)
51
+
52
+ ### Tiny fix
53
+ - Adjusted a threshold that should resolve the occasional build failures (#107) [@katiebayes](https://github.com/katiebayes)
54
+
55
+ ## 2.1.2 2020-08-26
56
+ ### Improvements
57
+ - reference current span in start_span (#105) [@rintaun](https://github.com/rintaun)
58
+ - switch trace and span ids over to w3c-supported formats (#100) [@katiebayes](https://github.com/katiebayes)
59
+
60
+ ## 2.1.1 2020-07-28
61
+ ### Fixes
62
+ - Remove children after sending | #98 | [@martin308](https://github.com/martin308)
63
+
64
+ ## 2.1.0 2020-06-10
65
+ ### Features
66
+ - Adding X-Forwarded-For to instrumented fields | #91 | [@paulosman](https://github.com/paulosman)
67
+ - Add request.header.accept_language field | #94 | [@timcraft](https://github.com/timcraft)
68
+ - Support custom notifications based on a regular expression | #92 | [@mrchucho](https://github.com/mrchucho)
69
+
70
+ ### Fixes
71
+ - Properly pass options for Ruby 2.7 | #85 | [@terracatta](https://github.com/terracatta)
72
+ - Fix regex substitution for warden and empty? errors for Rack | #88 | [@irvingreid](https://github.com/irvingreid)
73
+
74
+ ## 2.0.0 2020-03-10
75
+ See [release notes](https://github.com/honeycombio/beeline-ruby/releases/tag/v2.0.0)
76
+
77
+ ## 1.3.0 2019-11-20
78
+ ### Features
79
+ - redis integration | #42 | [@ajvondrak](https://github.com/ajvondrak)
80
+
81
+ ## 1.2.0 2019-11-04
82
+ ### Features
83
+ - aws-sdk v2 & v3 integration | #40 | [@ajvondrak](https://github.com/ajvondrak)
84
+
85
+ ## 1.1.1 2019-10-10
86
+ ### Fixes
87
+ - Skip params when unavailable | #39 | [@martin308](https://github.com/martin308)
88
+
89
+ ## 1.1.0 2019-10-07
90
+ ### Features
91
+ - Split rails and railtie integrations | #35 | [@martin308](https://github.com/martin308)
92
+
93
+ ## 1.0.1 2019-09-03
94
+ ### Fixes
95
+ - Set sample_hook and presend_hook on child spans | #26 | [@orangejulius](https://github.com/orangejulius)
96
+ - No-op if no client found in Faraday integration | #27 | [@Sergio-Mira](https://github.com/Sergio-Mira)
97
+
98
+ ## 1.0.0 2019-07-23
99
+ Version 1 is a milestone release. A complete re-write and modernization of Honeycomb's Ruby support.
100
+ See UPGRADING.md for migrating from v0.8.0 and see https://docs.honeycomb.io for full documentation.
101
+
102
+ ## 0.8.0 2019-05-06
103
+ ### Enhancements
104
+ - Expose event to #span block | #17 | [@eternal44](https://github.com/eternal44)
105
+
106
+ ## 0.7.0 2019-03-13
107
+ ### Enhancements
108
+ - Remove default inclusion of Sequel instrumentation | #12 | [@martin308](https://github.com/martin308)
109
+
110
+ ## 0.6.0 2018-11-29
111
+ ### Enhancements
112
+ - Tracing API and cross-process tracing | #4 | [@samstokes](https://github.com/samstokes)
113
+
114
+ ## 0.5.0 2018-11-29
115
+ ### Enhancements
116
+ - Improved rails support | #3 | [@samstokes](https://github.com/samstokes)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honeycomb-beeline (2.3.0)
4
+ honeycomb-beeline (2.5.0)
5
5
  libhoney (~> 1.14, >= 1.14.2)
6
6
 
7
7
  GEM
@@ -29,6 +29,7 @@ GEM
29
29
  docile (1.3.2)
30
30
  domain_name (0.5.20190701)
31
31
  unf (>= 0.0.5, < 1.0.0)
32
+ excon (0.82.0)
32
33
  ffi (1.12.2)
33
34
  ffi-compiler (1.0.1)
34
35
  ffi (>= 1.0.0)
@@ -39,16 +40,17 @@ GEM
39
40
  http-cookie (~> 1.0)
40
41
  http-form_data (~> 2.2)
41
42
  http-parser (~> 1.2.0)
42
- http-cookie (1.0.3)
43
+ http-cookie (1.0.4)
43
44
  domain_name (~> 0.5)
44
45
  http-form_data (2.3.0)
45
- http-parser (1.2.1)
46
+ http-parser (1.2.3)
46
47
  ffi-compiler (>= 1.0, < 2.0)
47
48
  iniparse (1.5.0)
48
49
  jaro_winkler (1.5.4)
49
50
  json (2.3.1)
50
- libhoney (1.14.5)
51
+ libhoney (1.18.0)
51
52
  addressable (~> 2.0)
53
+ excon
52
54
  http (>= 2.0, < 5.0)
53
55
  method_source (0.9.2)
54
56
  overcommit (0.46.0)
@@ -79,6 +81,8 @@ GEM
79
81
  diff-lcs (>= 1.2.0, < 2.0)
80
82
  rspec-support (~> 3.9.0)
81
83
  rspec-support (3.9.3)
84
+ rspec_junit_formatter (0.4.1)
85
+ rspec-core (>= 2, < 4, != 2.12.0)
82
86
  rubocop (0.68.1)
83
87
  jaro_winkler (~> 1.5.1)
84
88
  parallel (~> 1.10)
@@ -124,6 +128,7 @@ DEPENDENCIES
124
128
  pry-byebug (~> 3.6.0)
125
129
  rake
126
130
  rspec (~> 3.0)
131
+ rspec_junit_formatter
127
132
  rubocop (< 0.69)
128
133
  rubocop-performance (< 1.3.0)
129
134
  simplecov
@@ -131,4 +136,4 @@ DEPENDENCIES
131
136
  webmock
132
137
 
133
138
  BUNDLED WITH
134
- 2.1.4
139
+ 2.2.21
data/UPGRADING.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Upgrade Guide
2
2
 
3
+ ## 1.0.0 - 2.0.0
4
+
5
+ 1. See release notes: https://github.com/honeycombio/beeline-ruby/releases/tag/v2.0.0
6
+ 1. This update requires no code changes, but you must be aware of certain instrumentation changes. New fields will be added to your dataset and other fields will be removed.
7
+ 1. ActionController::Parameters will now result in extra fields, or nested json, depending on your unfurl settings.
8
+ 1. aws.params are now exploded into separate fields.
9
+ 1. request.error becomes error.
10
+ 1. request.error_detail becomes error_detail
11
+ 1. request.protocol becomes request.scheme
12
+
3
13
  ## 0.8.0 - 1.0.0
4
14
 
5
15
  1. If you have a web application, remove beeline configuration from the `config.ru` file
@@ -48,6 +48,7 @@ Gem::Specification.new do |spec|
48
48
  spec.add_development_dependency "pry-byebug", "~> 3.6.0"
49
49
  spec.add_development_dependency "rake"
50
50
  spec.add_development_dependency "rspec", "~> 3.0"
51
+ spec.add_development_dependency "rspec_junit_formatter"
51
52
  spec.add_development_dependency "rubocop", "< 0.69"
52
53
  spec.add_development_dependency "rubocop-performance", "< 1.3.0"
53
54
  spec.add_development_dependency "simplecov"
@@ -26,7 +26,8 @@ module Honeycomb
26
26
  attr_reader :client
27
27
 
28
28
  def_delegators :@client, :libhoney, :start_span, :add_field,
29
- :add_field_to_trace, :current_span, :current_trace
29
+ :add_field_to_trace, :current_span, :current_trace,
30
+ :with_field, :with_trace_field
30
31
 
31
32
  def configure
32
33
  Configuration.new.tap do |config|
@@ -3,7 +3,7 @@
3
3
  module Honeycomb
4
4
  module Beeline
5
5
  NAME = "honeycomb-beeline".freeze
6
- VERSION = "2.3.0".freeze
6
+ VERSION = "2.5.0".freeze
7
7
  USER_AGENT_SUFFIX = "#{NAME}/#{VERSION}".freeze
8
8
  end
9
9
  end
@@ -38,6 +38,7 @@ module Honeycomb
38
38
  parser_hook: configuration.http_trace_parser_hook,
39
39
  propagation_hook: configuration.http_trace_propagation_hook,
40
40
  }
41
+ @error_backtrace_limit = configuration.error_backtrace_limit.to_i
41
42
 
42
43
  configuration.after_initialize(self)
43
44
 
@@ -47,16 +48,7 @@ module Honeycomb
47
48
  end
48
49
 
49
50
  def start_span(name:, serialized_trace: nil, **fields)
50
- if context.current_trace.nil?
51
- Trace.new(serialized_trace: serialized_trace,
52
- builder: libhoney.builder,
53
- context: context,
54
- **@additional_trace_options)
55
- else
56
- context.current_span.create_child
57
- end
58
-
59
- current_span = context.current_span
51
+ current_span = new_span_for_context(serialized_trace: serialized_trace)
60
52
 
61
53
  fields.each do |key, value|
62
54
  current_span.add_field(key, value)
@@ -69,8 +61,8 @@ module Honeycomb
69
61
  begin
70
62
  yield current_span
71
63
  rescue StandardError => e
72
- current_span.add_field("error", e.class.name)
73
- current_span.add_field("error_detail", e.message)
64
+ add_exception_data(current_span, e)
65
+
74
66
  raise e
75
67
  ensure
76
68
  current_span.send
@@ -89,8 +81,49 @@ module Honeycomb
89
81
  context.current_span.trace.add_field("app.#{key}", value)
90
82
  end
91
83
 
84
+ def with_field(key)
85
+ yield.tap { |value| add_field(key, value) }
86
+ end
87
+
88
+ def with_trace_field(key)
89
+ yield.tap { |value| add_field_to_trace(key, value) }
90
+ end
91
+
92
92
  private
93
93
 
94
- attr_reader :context
94
+ attr_reader :context, :error_backtrace_limit
95
+
96
+ def new_span_for_context(serialized_trace:)
97
+ if context.current_trace.nil?
98
+ Trace.new(
99
+ serialized_trace: serialized_trace,
100
+ builder: libhoney.builder,
101
+ context: context,
102
+ **@additional_trace_options,
103
+ )
104
+ else
105
+ context.current_span.create_child
106
+ end
107
+
108
+ context.current_span
109
+ end
110
+
111
+ def add_exception_data(span, exception)
112
+ span.add_field("error", exception.class.name)
113
+ span.add_field("error_detail", exception.message)
114
+
115
+ return if error_backtrace_limit <= 0
116
+
117
+ span.add_field(
118
+ "error_backtrace",
119
+ exception
120
+ .backtrace
121
+ .take(error_backtrace_limit)
122
+ .join("\n")
123
+ .encode("UTF-8", invalid: :replace, undef: :replace, replace: "�"),
124
+ )
125
+ span.add_field("error_backtrace_limit", error_backtrace_limit)
126
+ span.add_field("error_backtrace_total_length", exception.backtrace.length)
127
+ end
95
128
  end
96
129
  end
@@ -12,12 +12,14 @@ module Honeycomb
12
12
  :debug
13
13
 
14
14
  attr_writer :service_name, :client, :host_name
15
+ attr_reader :error_backtrace_limit
15
16
 
16
17
  def initialize
17
18
  @write_key = ENV["HONEYCOMB_WRITEKEY"]
18
19
  @dataset = ENV["HONEYCOMB_DATASET"]
19
20
  @service_name = ENV["HONEYCOMB_SERVICE"]
20
21
  @debug = ENV.key?("HONEYCOMB_DEBUG")
22
+ @error_backtrace_limit = 0
21
23
  @client = nil
22
24
  end
23
25
 
@@ -25,6 +27,10 @@ module Honeycomb
25
27
  @service_name || dataset
26
28
  end
27
29
 
30
+ def error_backtrace_limit=(val)
31
+ @error_backtrace_limit = Integer(val)
32
+ end
33
+
28
34
  def client
29
35
  options = {}.tap do |o|
30
36
  o[:writekey] = write_key
@@ -17,6 +17,7 @@ module Honeycomb
17
17
  ["HTTP_X_FORWARDED_PROTO", "request.header.x_forwarded_proto"],
18
18
  ["HTTP_X_FORWARDED_PORT", "request.header.x_forwarded_port"],
19
19
  ["HTTP_ACCEPT", "request.header.accept"],
20
+ ["HTTP_ACCEPT_ENCODING", "request.header.accept_encoding"],
20
21
  ["HTTP_ACCEPT_LANGUAGE", "request.header.accept_language"],
21
22
  ["CONTENT_TYPE", "request.header.content_type"],
22
23
  ["HTTP_USER_AGENT", "request.header.user_agent"],
@@ -47,11 +48,12 @@ module Honeycomb
47
48
  span.add_field("request.secure", req.ssl?)
48
49
  span.add_field("request.xhr", req.xhr?)
49
50
 
50
- status, headers, body = app.call(env)
51
-
52
- add_package_information(env, &add_field)
53
-
54
- extract_user_information(env, &add_field)
51
+ begin
52
+ status, headers, body = call_with_hook(env, span, &add_field)
53
+ ensure
54
+ add_package_information(env, &add_field)
55
+ extract_user_information(env, &add_field)
56
+ end
55
57
 
56
58
  span.add_field("response.status_code", status)
57
59
  span.add_field("response.content_type", headers["Content-Type"])
@@ -71,6 +73,12 @@ module Honeycomb
71
73
  end
72
74
  end
73
75
 
76
+ private
77
+
78
+ def call_with_hook(env, _span, &_add_field)
79
+ app.call(env)
80
+ end
81
+
74
82
  # Rack middleware
75
83
  class Middleware
76
84
  include Rack
@@ -89,6 +89,16 @@ module Honeycomb
89
89
  include Rack
90
90
  include Warden
91
91
  include Rails
92
+
93
+ def call_with_hook(env, span, &_add_field)
94
+ super
95
+ rescue StandardError => e
96
+ wrapped = ActionDispatch::ExceptionWrapper.new(nil, e)
97
+
98
+ span.add_field "response.status_code", wrapped.status_code
99
+
100
+ raise e
101
+ end
92
102
  end
93
103
  end
94
104
  end
@@ -159,7 +159,17 @@ module Honeycomb
159
159
  # * :logger - just some Ruby object, not useful
160
160
  # * :_parsed - implementation detail
161
161
  def ignore?(option)
162
- %i[url password logger _parsed].include?(option)
162
+ # Redis options may be symbol or string keys.
163
+ #
164
+ # This normalizes `option` using `to_sym` as benchmarking on Ruby MRI
165
+ # v2.6.6 and v2.7.3 has shown that was faster compared to `to_s`.
166
+ # However, `nil` does not support `to_sym`. This uses a guard clause to
167
+ # handle the `nil` case because this is still faster than safe
168
+ # navigation. Also this lib still supports Ruby 2.2.0; which does not
169
+ # include safe navigation.
170
+ return true unless option
171
+
172
+ %i[url password logger _parsed].include?(option.to_sym)
163
173
  end
164
174
 
165
175
  def format(cmd)
@@ -177,16 +187,6 @@ module Honeycomb
177
187
  args.map! { "[sanitized]" }
178
188
  end
179
189
 
180
- def prettify(arg)
181
- quotes = false
182
- pretty = "".dup
183
- arg.to_s.each_char do |c|
184
- quotes ||= needs_quotes?(c)
185
- pretty << escape(c)
186
- end
187
- quotes ? "\"#{pretty}\"" : pretty
188
- end
189
-
190
190
  # This aims to replicate the algorithms used by redis-cli.
191
191
  #
192
192
  # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L940-L1067
@@ -194,54 +194,15 @@ module Honeycomb
194
194
  #
195
195
  # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L878-L907
196
196
  # The redis-cli printing algorithm
197
- def escape(char)
198
- return escape_with_backslash(char) if escape_with_backslash?(char)
199
- return escape_with_hex_codes(char) if escape_with_hex_codes?(char)
200
-
201
- char
202
- end
203
-
204
- # A lookup table for backslash-escaped characters.
205
- #
206
- # This is used by {#escape_with_backslash?} and {#escape_with_backslash}
207
- # to replicate the hard-coded `case` statements in redis-cli. As of this
208
- # writing, Redis recognizes a handful of standard C escape sequences,
209
- # like "\n" for newlines.
210
- #
211
- # Because {#prettify} will output double quoted strings if any escaping
212
- # is needed, this table must additionally consider the double-quote to be
213
- # a backslash-escaped character. For example, instead of generating
214
- #
215
- # '"hello"'
216
- #
217
- # we'll generate
218
- #
219
- # "\"hello\""
220
- #
221
- # even though redis-cli would technically recognize the single-quoted
222
- # version.
223
- #
224
- # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L888-L896
225
- # The redis-cli algorithm for outputting standard escape sequences
226
- BACKSLASHES = {
227
- "\\" => "\\\\",
228
- '"' => '\\"',
229
- "\n" => "\\n",
230
- "\r" => "\\r",
231
- "\t" => "\\t",
232
- "\a" => "\\a",
233
- "\b" => "\\b",
234
- }.freeze
235
-
236
- def escape_with_backslash?(char)
237
- BACKSLASHES.key?(char)
238
- end
239
-
240
- def escape_with_backslash(char)
241
- BACKSLASHES.fetch(char, char)
197
+ def prettify(arg)
198
+ pretty = arg.to_s.dup
199
+ pretty.encode!("UTF-8", "binary", fallback: ->(c) { hex(c) })
200
+ pretty.gsub!(NEEDS_BACKSLASH, BACKSLASH)
201
+ pretty.gsub!(NEEDS_HEX) { |c| hex(c) }
202
+ pretty =~ NEEDS_QUOTES ? "\"#{pretty}\"" : pretty
242
203
  end
243
204
 
244
- # Do we need to hex-encode this character?
205
+ # A regular expression matching characters that need to be hex-encoded.
245
206
  #
246
207
  # This replicates the C isprint() function that redis-cli uses to decide
247
208
  # whether to escape a character in hexadecimal notation, "\xhh". Any
@@ -277,18 +238,95 @@ module Honeycomb
277
238
  # escape it.
278
239
  #
279
240
  # What's more, Ruby's Regexp#=~ method will blow up if the string does
280
- # not have a valid encoding (e.g., in UTF-8). In this case, though,
281
- # {#escape_with_hex_codes} can still convert the bytes that make up the
282
- # invalid character into a hex code. So we preemptively check for
283
- # invalidly-encoded characters before testing the above match.
241
+ # not have a valid encoding (e.g., in UTF-8). We handle this case
242
+ # separately, though, using String#encode! with a :fallback option to
243
+ # hex-encode invalid UTF-8 byte sequences with {#hex}.
284
244
  #
285
245
  # @see https://ruby-doc.org/core-2.6.5/Regexp.html
286
246
  # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L878-L880
287
247
  # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L898-L901
288
248
  # @see https://www.justinweiss.com/articles/3-steps-to-fix-encoding-problems-in-ruby/
289
- def escape_with_hex_codes?(char)
290
- !char.valid_encoding? || char =~ /[^[:print:]&&[:ascii:]]/
291
- end
249
+ NEEDS_HEX = /[^[:print:]&&[:ascii:]]/.freeze
250
+
251
+ # A regular expression for characters that need to be backslash-escaped.
252
+ #
253
+ # Any match of this regexp will be substituted according to the
254
+ # {BACKSLASH} table. This includes standard C escape sequences (newlines,
255
+ # tabs, etc) as well as a couple special considerations:
256
+ #
257
+ # 1. Because {#prettify} will output double quoted strings if any
258
+ # escaping is needed, we must match double quotes (") so they'll be
259
+ # replaced by escaped quotes (\").
260
+ #
261
+ # 2. Backslashes themselves get backslash-escaped, so \ becomes \\.
262
+ # However, strings with invalid UTF-8 encoding will blow up when we
263
+ # try to use String#gsub!, so {#prettify} must first use
264
+ # String#encode! to scrub out invalid characters. It does this by
265
+ # replacing invalid bytes with hex-encoded escape sequences using
266
+ # {#hex}. This will insert sequences like \xhh, which contains a
267
+ # backslash that we *don't* want to escape.
268
+ #
269
+ # Unfortunately, this regexp can't really distinguish between
270
+ # backslashes in the original input vs backslashes resulting from the
271
+ # UTF-8 fallback. We make an effort by using a negative lookahead.
272
+ # That way, only backslashes that *aren't* followed by x + hex digit +
273
+ # hex digit will be escaped.
274
+ NEEDS_BACKSLASH = /["\n\r\t\a\b]|\\(?!x\h\h)/.freeze
275
+
276
+ # A lookup table for backslash-escaped characters.
277
+ #
278
+ # This is used by {#prettify} to replicate the hard-coded `case`
279
+ # statements in redis-cli. As of this writing, Redis recognizes a handful
280
+ # of standard C escape sequences, like "\n" for newlines.
281
+ #
282
+ # Because {#prettify} will output double quoted strings if any escaping
283
+ # is needed, this table must additionally consider the double-quote to be
284
+ # a backslash-escaped character. For example, instead of generating
285
+ #
286
+ # '"hello"'
287
+ #
288
+ # we'll generate
289
+ #
290
+ # "\"hello\""
291
+ #
292
+ # even though redis-cli would technically recognize the single-quoted
293
+ # version.
294
+ #
295
+ # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L888-L896
296
+ # The redis-cli algorithm for outputting standard escape sequences
297
+ BACKSLASH = {
298
+ "\\" => "\\\\",
299
+ '"' => '\\"',
300
+ "\n" => "\\n",
301
+ "\r" => "\\r",
302
+ "\t" => "\\t",
303
+ "\a" => "\\a",
304
+ "\b" => "\\b",
305
+ }.freeze
306
+
307
+ # If the final escaped string needs quotes, it will match this regexp.
308
+ #
309
+ # The overall string returned by {#prettify} should only be quoted if at
310
+ # least one of the following holds:
311
+ #
312
+ # 1. The string contains an escape sequence, broadly demarcated by a
313
+ # backslash. This includes standard escape sequences like "\n" and
314
+ # "\t" as well as hex-encoded bytes using the "\x" escape sequence.
315
+ # Since {#prettify} uses double quotes on its output string, we must
316
+ # also force quotes if the string itself contains a literal
317
+ # double quote. This double quote behavior is handled tacitly by the
318
+ # {NEEDS_BACKSLASH} + {BACKSLASH} replacement.
319
+ #
320
+ # 2. The string contains a single quote. Since redis-cli recognizes
321
+ # single-quoted strings, we want to wrap the {#prettify} output in
322
+ # double quotes so that the literal single quote character isn't
323
+ # mistaken as the delimiter of a new string.
324
+ #
325
+ # 3. The string contains any whitespace characters. If the {#prettify}
326
+ # output weren't wrapped in quotes, whitespace would act as a
327
+ # separator between arguments to the Redis command. To group things
328
+ # together, we need to quote the string.
329
+ NEEDS_QUOTES = /[\\'\s]/.freeze
292
330
 
293
331
  # Hex-encodes a (presumably non-printable or non-ASCII) character.
294
332
  #
@@ -316,38 +354,9 @@ module Honeycomb
316
354
  # @see https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap07.html
317
355
  # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L878-L880
318
356
  # @see https://github.com/antirez/redis/blob/0f026af185e918a9773148f6ceaa1b084662be88/src/sds.c#L898-L901
319
- def escape_with_hex_codes(char)
357
+ def hex(char)
320
358
  char.bytes.map { |b| Kernel.format("\\x%02x", b) }.join
321
359
  end
322
-
323
- def escape?(char)
324
- escape_with_backslash?(char) || escape_with_hex_codes?(char)
325
- end
326
-
327
- # Should this character cause {#prettify} to wrap its output in quotes?
328
- #
329
- # The overall string returned by {#prettify} should only be quoted if at
330
- # least one of the following holds:
331
- #
332
- # 1. The string contains a character that needs to be escaped. This
333
- # includes standard backslash escape sequences (like "\n" and "\t") as
334
- # well as hex-encoded bytes using the "\x" escape sequence. Since
335
- # {#prettify} uses double quotes on its output string, we must also
336
- # force quotes if the string itself contains a literal double quote.
337
- # This double quote behavior is handled tacitly by {BACKSLASHES}.
338
- #
339
- # 2. The string contains a single quote. Since redis-cli recognizes
340
- # single-quoted strings, we want to wrap the {#prettify} output in
341
- # double quotes so that the literal single quote character isn't
342
- # mistaken as the delimiter of a new string.
343
- #
344
- # 3. The string contains any whitespace characters. If the {#prettify}
345
- # output weren't wrapped in quotes, whitespace would act as a
346
- # separator between arguments to the Redis command. To group things
347
- # together, we need to quote the string.
348
- def needs_quotes?(char)
349
- escape?(char) || char == "'" || char =~ /\s/
350
- end
351
360
  end
352
361
  end
353
362
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeycomb-beeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Holman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-06 00:00:00.000000000 Z
11
+ date: 2021-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libhoney
@@ -156,6 +156,20 @@ dependencies:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
158
  version: '3.0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: rspec_junit_formatter
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
159
173
  - !ruby/object:Gem::Dependency
160
174
  name: rubocop
161
175
  requirement: !ruby/object:Gem::Requirement
@@ -238,12 +252,17 @@ files:
238
252
  - ".circleci/setup-rubygems.sh"
239
253
  - ".editorconfig"
240
254
  - ".github/CODEOWNERS"
255
+ - ".github/dependabot.yml"
256
+ - ".github/workflows/add-to-project.yml"
257
+ - ".github/workflows/apply-labels.yml"
241
258
  - ".gitignore"
242
259
  - ".overcommit.yml"
243
260
  - ".rspec"
244
261
  - ".rubocop.yml"
245
262
  - ".ruby-version"
263
+ - ".tool-versions"
246
264
  - Appraisals
265
+ - CHANGELOG.md
247
266
  - CODE_OF_CONDUCT.md
248
267
  - CONTRIBUTORS.md
249
268
  - Gemfile
@@ -303,7 +322,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
303
322
  - !ruby/object:Gem::Version
304
323
  version: '0'
305
324
  requirements: []
306
- rubygems_version: 3.0.3
325
+ rubygems_version: 3.0.3.1
307
326
  signing_key:
308
327
  specification_version: 4
309
328
  summary: Instrument your Ruby apps with Honeycomb