libhoney 1.17.0 → 1.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +2 -0
- data/.github/CODEOWNERS +1 -1
- data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- data/.github/ISSUE_TEMPLATE/question-discussion.md +14 -0
- data/.github/ISSUE_TEMPLATE/security-vulnerability-report.md +22 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- data/.github/dependabot.yml +15 -0
- data/.github/workflows/add-to-project.yml +14 -0
- data/.github/workflows/apply-labels.yml +10 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -2
- data/CHANGELOG.md +44 -1
- data/CODE_OF_CONDUCT.md +5 -0
- data/CONTRIBUTING.md +3 -0
- data/CONTRIBUTORS +1 -0
- data/OSSMETADATA +1 -0
- data/README.md +5 -1
- data/RELEASING.md +11 -0
- data/SECURITY.md +3 -0
- data/SUPPORT.md +3 -0
- data/lib/libhoney/client.rb +96 -31
- data/lib/libhoney/experimental_transmission.rb +107 -0
- data/lib/libhoney/mock_transmission.rb +1 -1
- data/lib/libhoney/null_transmission.rb +2 -0
- data/lib/libhoney/queueing/LICENSE.txt +23 -0
- data/lib/libhoney/queueing/sized_queue_with_timeout.rb +176 -0
- data/lib/libhoney/queueing.rb +1 -0
- data/lib/libhoney/response.rb +10 -2
- data/lib/libhoney/transmission.rb +129 -56
- data/lib/libhoney/version.rb +1 -1
- data/libhoney.gemspec +6 -3
- metadata +71 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e193211937c61bf221e8610d7324c173d90aefa2f5d08f706c0ea56dcbb1d971
|
4
|
+
data.tar.gz: d235e368e4f1dc9b11a5a489fdff04c734a7804d57925394f515ac92a11ef0bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cbf429690cb10522b488f631be5b726e6973e3b1d73b660ac28f3d8186e7b88b392c6736252dc9e2a77bb2fb78a70bf8e678653edb12c8405a45bd693ec0e28
|
7
|
+
data.tar.gz: 9b318c534cdeac671ea52e880ce9e8e047bc2b730eb9ab7e020c111dbfaedc19083cd152e8e506b3422ef36c3d9e719b87ac661d871bf8cd13d5c24d5b5d19fb
|
data/.circleci/config.yml
CHANGED
data/.github/CODEOWNERS
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Let us know if something is not working as expected
|
4
|
+
title: ''
|
5
|
+
labels: 'type: bug'
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
<!---
|
11
|
+
Thank you for taking the time to report bugs!
|
12
|
+
|
13
|
+
We love code snippets and links to repositories that reproduce the issue, but understand if you don't have the time to add them. We'll do our best with the info you provide, and might ask follow-up questions.
|
14
|
+
|
15
|
+
Please see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.
|
16
|
+
--->
|
17
|
+
|
18
|
+
**Versions**
|
19
|
+
|
20
|
+
- Ruby:
|
21
|
+
- Libhoney:
|
22
|
+
|
23
|
+
**Steps to reproduce**
|
24
|
+
|
25
|
+
1.
|
26
|
+
|
27
|
+
**Additional context**
|
@@ -0,0 +1,25 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: 'type: enhancement'
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
<!---
|
11
|
+
Thank you for contributing an idea to this project!
|
12
|
+
|
13
|
+
Please see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.
|
14
|
+
--->
|
15
|
+
|
16
|
+
**Is your feature request related to a problem? Please describe.**
|
17
|
+
|
18
|
+
|
19
|
+
**Describe the solution you'd like**
|
20
|
+
|
21
|
+
|
22
|
+
**Describe alternatives you've considered**
|
23
|
+
|
24
|
+
|
25
|
+
**Additional context**
|
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
name: Question/Discussion
|
3
|
+
about: General question about how things work or a discussion
|
4
|
+
title: ''
|
5
|
+
labels: 'type: discussion'
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
<!---
|
11
|
+
Thank you for taking the time to say hello!
|
12
|
+
|
13
|
+
Please see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.
|
14
|
+
--->
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
name: Security vulnerability report
|
3
|
+
about: Let us know if you discover a security vulnerability
|
4
|
+
title: ''
|
5
|
+
labels: 'type: security'
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
<!---
|
11
|
+
Thank you for taking the time to report security vulnerabilities!
|
12
|
+
|
13
|
+
Please see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.
|
14
|
+
--->
|
15
|
+
**Versions**
|
16
|
+
|
17
|
+
- Ruby:
|
18
|
+
- Libhoney:
|
19
|
+
|
20
|
+
**Description**
|
21
|
+
|
22
|
+
(Please include any relevant CVE advisory links)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<!--
|
2
|
+
Thank you for contributing to the project! 💜
|
3
|
+
Please make sure to:
|
4
|
+
- Chat with us first if this is a big change
|
5
|
+
- Open a new issue (or comment on an existing one)
|
6
|
+
- We want to make sure you don't spend time implementing something we might have to say No to
|
7
|
+
- Add unit tests
|
8
|
+
- Mention any relevant issues in the PR description (e.g. "Fixes #123")
|
9
|
+
|
10
|
+
Please see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.
|
11
|
+
-->
|
12
|
+
|
13
|
+
## Which problem is this PR solving?
|
14
|
+
|
15
|
+
-
|
16
|
+
|
17
|
+
## Short description of the changes
|
18
|
+
|
19
|
+
-
|
20
|
+
|
@@ -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: "/" # 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
data/.rubocop.yml
CHANGED
@@ -9,17 +9,19 @@ Style/Documentation:
|
|
9
9
|
Lint/RescueException:
|
10
10
|
Exclude:
|
11
11
|
- 'lib/libhoney/transmission.rb'
|
12
|
+
- 'lib/libhoney/experimental_transmission.rb'
|
12
13
|
|
13
14
|
Metrics/BlockLength:
|
14
15
|
Max: 35
|
15
16
|
|
16
17
|
Metrics/ClassLength:
|
17
|
-
Max:
|
18
|
+
Max: 300
|
18
19
|
Exclude:
|
20
|
+
- lib/libhoney/transmission.rb # Should this remain so large?
|
19
21
|
- test/*
|
20
22
|
|
21
23
|
Metrics/MethodLength:
|
22
|
-
Max:
|
24
|
+
Max: 45
|
23
25
|
Exclude:
|
24
26
|
- lib/libhoney/transmission.rb
|
25
27
|
- test/*
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,49 @@
|
|
1
1
|
# libhoney-rb changelog
|
2
2
|
|
3
|
-
##
|
3
|
+
## [1.21.0] - 2021-09-23
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Include Ruby runtime info in user agent (#105) | [robbkidd](https://github.com/robbkidd)
|
8
|
+
|
9
|
+
### Maintenance
|
10
|
+
|
11
|
+
- Update http requirement from >= 2.0, < 5.0 to >= 2.0, < 6.0 (#100)
|
12
|
+
- Update spy requirement to accept any 1.x release (#102)
|
13
|
+
- Update rake requirement from ~> 12.3 to ~> 13.0 (#101)
|
14
|
+
- Add issue and PR templates (#99)
|
15
|
+
- Add OSS lifecycle badge (#98)
|
16
|
+
- Add community health files (#97)
|
17
|
+
|
18
|
+
## 1.20.0
|
19
|
+
|
20
|
+
### Fixes
|
21
|
+
|
22
|
+
- Handle Timeout::Error in TransmissionClient (#95) | [Adam Pohorecki](https://github.com/psyho)
|
23
|
+
|
24
|
+
## 1.19.0
|
25
|
+
|
26
|
+
### Improvements
|
27
|
+
|
28
|
+
- add a test_helper, Minitest reporters, & store test results in CI (#88)
|
29
|
+
- add experimental transmission with new sized-and-timed queue (#87)
|
30
|
+
|
31
|
+
### Fixes
|
32
|
+
|
33
|
+
- Process single-error responses from the Batch API (#89)
|
34
|
+
|
35
|
+
## 1.18.0
|
36
|
+
|
37
|
+
### Improvements
|
38
|
+
|
39
|
+
- replace HTTP client library to reduce external dependencies (#81)
|
40
|
+
|
41
|
+
### Deprecations
|
42
|
+
|
43
|
+
- `Libhoney::Client.new(proxy_config: _)`: the `proxy_config` parameter for client
|
44
|
+
creation will no longer accept an Array in the next major version. The recommended
|
45
|
+
way to configure the client for operation behind forwarding web proxies is to set
|
46
|
+
http/https/no_proxy environment variables appropriately.
|
4
47
|
|
5
48
|
## 1.17.0
|
6
49
|
|
data/CODE_OF_CONDUCT.md
ADDED
data/CONTRIBUTING.md
ADDED
data/CONTRIBUTORS
CHANGED
data/OSSMETADATA
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
osslifecycle=maintenance
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
# libhoney
|
1
|
+
# libhoney
|
2
|
+
|
3
|
+
[![OSS Lifecycle](https://img.shields.io/osslifecycle/honeycombio/libhoney-rb)](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md)
|
4
|
+
[![CircleCI Build Status](https://circleci.com/gh/honeycombio/libhoney-rb.svg?style=svg)](https://circleci.com/gh/honeycombio/libhoney-rb)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/libhoney.svg)](https://badge.fury.io/rb/libhoney)
|
2
6
|
|
3
7
|
Ruby gem for sending events to [Honeycomb](https://www.honeycomb.io), a service for debugging your software in production.
|
4
8
|
|
data/RELEASING.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Releasing
|
2
|
+
|
3
|
+
- Update the version number in `lib/libhoney/version.rb`.
|
4
|
+
- Run `bundle lock`.
|
5
|
+
- Confirm the version number update appears in `Gemfile.lock`
|
6
|
+
- Update `CHANGELOG.md` with the changes since the last release.
|
7
|
+
- Commit changes, push, and open a release preparation pull request for review.
|
8
|
+
- Once the pull request is merged, fetch the updated `main` branch.
|
9
|
+
- Apply a tag for the new version on the merged commit: vX.Y.Z, for example v1.1.2.
|
10
|
+
- Push the new version tag up to the project repository to kick off build and artifact publishing to GitHub and the Gems registry.
|
11
|
+
- Publish the draft release in GitHub.
|
data/SECURITY.md
ADDED
data/SUPPORT.md
ADDED
data/lib/libhoney/client.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
require 'addressable/uri'
|
1
2
|
require 'time'
|
2
3
|
require 'json'
|
3
|
-
require 'http'
|
4
4
|
require 'forwardable'
|
5
5
|
|
6
6
|
require 'libhoney/null_transmission'
|
@@ -46,11 +46,22 @@ module Libhoney
|
|
46
46
|
# Honeycomb query engine will interpret it as representative of 10 events)
|
47
47
|
# @param api_host [String] defaults to +API_HOST+, override to change the
|
48
48
|
# destination for these Honeycomb events.
|
49
|
-
# @param transmission [Object] transport used to actually send events. If nil (the default),
|
49
|
+
# @param transmission [Class, Object, nil] transport used to actually send events. If nil (the default),
|
50
|
+
# will be initialized with a {TransmissionClient}. If Class--for example, {MockTransmissionClient}--will attempt
|
51
|
+
# to create a new instance of that class with {TransmissionClient}'s usual parameters. If Object, checks
|
52
|
+
# that the instance passed in implements the Transmission interface (responds to :add and :close). If the
|
53
|
+
# check does not succeed, a no-op NullTransmission will be used instead.
|
50
54
|
# @param block_on_send [Boolean] if more than pending_work_capacity events are written, block sending further events
|
51
55
|
# @param block_on_responses [Boolean] if true, block if there is no thread reading from the response queue
|
52
56
|
# @param pending_work_capacity [Fixnum] defaults to 1000. If the queue of
|
53
57
|
# pending events exceeds 1000, this client will start dropping events.
|
58
|
+
# @param proxy_config [String, Array, nil] proxy connection information
|
59
|
+
# nil: (default, recommended) connection proxying will be determined from any http_proxy, https_proxy, and no_proxy environment
|
60
|
+
# variables set for the process.
|
61
|
+
# String: the value must be the URI for connecting to a forwarding web proxy. Must be parsable by stdlib URI.
|
62
|
+
# Array: (deprecated, removal in v2.0) the value must have one and at most four elements: e.g. ['host', port, 'username', 'password'].
|
63
|
+
# The assumption is that the TCP connection will be tunneled via HTTP, so the assumed scheme is 'http://'
|
64
|
+
# 'host' is required. 'port' is optional (default:80), unless a 'username' is included. 'password' is optional.
|
54
65
|
# rubocop:disable Metrics/ParameterLists
|
55
66
|
def initialize(writekey: nil,
|
56
67
|
dataset: nil,
|
@@ -81,17 +92,6 @@ module Libhoney
|
|
81
92
|
@builder.sample_rate = sample_rate
|
82
93
|
@builder.api_host = api_host
|
83
94
|
|
84
|
-
@transmission = transmission
|
85
|
-
if !@transmission && !(writekey && dataset)
|
86
|
-
# if no writekey or dataset are configured, and we didn't override the
|
87
|
-
# transmission (e.g. to a MockTransmissionClient), that's almost
|
88
|
-
# certainly a misconfiguration, even though it's possible to override
|
89
|
-
# them on a per-event basis. So let's handle the misconfiguration
|
90
|
-
# early rather than potentially throwing thousands of exceptions at runtime.
|
91
|
-
warn "#{self.class.name}: no #{writekey ? 'dataset' : 'writekey'} configured, disabling sending events"
|
92
|
-
@transmission = NullTransmissionClient.new
|
93
|
-
end
|
94
|
-
|
95
95
|
@user_agent_addition = user_agent_addition
|
96
96
|
|
97
97
|
@block_on_send = block_on_send
|
@@ -101,8 +101,8 @@ module Libhoney
|
|
101
101
|
@max_concurrent_batches = max_concurrent_batches
|
102
102
|
@pending_work_capacity = pending_work_capacity
|
103
103
|
@responses = SizedQueue.new(2 * @pending_work_capacity)
|
104
|
-
@
|
105
|
-
@
|
104
|
+
@proxy_config = parse_proxy_config(proxy_config)
|
105
|
+
@transmission = setup_transmission(transmission, writekey, dataset)
|
106
106
|
end
|
107
107
|
|
108
108
|
attr_reader :block_on_send, :block_on_responses, :max_batch_size,
|
@@ -190,22 +190,6 @@ module Libhoney
|
|
190
190
|
# @param event [Event] the event to send to honeycomb
|
191
191
|
# @api private
|
192
192
|
def send_event(event)
|
193
|
-
@lock.synchronize do
|
194
|
-
transmission_client_params = {
|
195
|
-
max_batch_size: @max_batch_size,
|
196
|
-
send_frequency: @send_frequency,
|
197
|
-
max_concurrent_batches: @max_concurrent_batches,
|
198
|
-
pending_work_capacity: @pending_work_capacity,
|
199
|
-
responses: @responses,
|
200
|
-
block_on_send: @block_on_send,
|
201
|
-
block_on_responses: @block_on_responses,
|
202
|
-
user_agent_addition: @user_agent_addition,
|
203
|
-
proxy_config: @proxy_config
|
204
|
-
}
|
205
|
-
|
206
|
-
@transmission ||= TransmissionClient.new(**transmission_client_params)
|
207
|
-
end
|
208
|
-
|
209
193
|
@transmission.add(event)
|
210
194
|
end
|
211
195
|
|
@@ -224,5 +208,86 @@ module Libhoney
|
|
224
208
|
def should_drop(sample_rate)
|
225
209
|
rand(1..sample_rate) != 1
|
226
210
|
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
##
|
215
|
+
# Parameters to pass to a transmission based on client config.
|
216
|
+
#
|
217
|
+
def transmission_client_params
|
218
|
+
{
|
219
|
+
max_batch_size: @max_batch_size,
|
220
|
+
send_frequency: @send_frequency,
|
221
|
+
max_concurrent_batches: @max_concurrent_batches,
|
222
|
+
pending_work_capacity: @pending_work_capacity,
|
223
|
+
responses: @responses,
|
224
|
+
block_on_send: @block_on_send,
|
225
|
+
block_on_responses: @block_on_responses,
|
226
|
+
user_agent_addition: @user_agent_addition,
|
227
|
+
proxy_config: @proxy_config
|
228
|
+
}
|
229
|
+
end
|
230
|
+
|
231
|
+
def setup_transmission(transmission, writekey, dataset)
|
232
|
+
# if a provided transmission can add and close, we'll assume the user
|
233
|
+
# has provided a working transmission with a customized configuration
|
234
|
+
return transmission if quacks_like_a_transmission?(transmission)
|
235
|
+
|
236
|
+
if !(writekey && dataset) # rubocop:disable Style/NegatedIf
|
237
|
+
# if no writekey or dataset are configured, and we didn't override the
|
238
|
+
# transmission (e.g. to a MockTransmissionClient), that's almost
|
239
|
+
# certainly a misconfiguration, even though it's possible to override
|
240
|
+
# them on a per-event basis. So let's handle the misconfiguration
|
241
|
+
# early rather than potentially throwing thousands of exceptions at runtime.
|
242
|
+
warn "#{self.class.name}: no #{writekey ? 'dataset' : 'writekey'} configured, disabling sending events"
|
243
|
+
return NullTransmissionClient.new
|
244
|
+
end
|
245
|
+
|
246
|
+
case transmission
|
247
|
+
when NilClass # the default value for new clients
|
248
|
+
return TransmissionClient.new(**transmission_client_params)
|
249
|
+
when Class
|
250
|
+
# if a class has been provided, attempt to instantiate it with parameters given to the client
|
251
|
+
t = transmission.new(**transmission_client_params)
|
252
|
+
if quacks_like_a_transmission?(t) # rubocop:disable Style/GuardClause
|
253
|
+
return t
|
254
|
+
else
|
255
|
+
warn "#{t.class.name}: does not appear to behave like a transmission, disabling sending events"
|
256
|
+
return NullTransmissionClient.new
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def quacks_like_a_transmission?(transmission)
|
262
|
+
transmission.respond_to?(:add) && transmission.respond_to?(:close)
|
263
|
+
end
|
264
|
+
|
265
|
+
# @api private
|
266
|
+
def parse_proxy_config(config)
|
267
|
+
case config
|
268
|
+
when nil then nil
|
269
|
+
when String
|
270
|
+
URI.parse(config)
|
271
|
+
when Array
|
272
|
+
warn <<-WARNING
|
273
|
+
DEPRECATION WARNING: #{self.class.name} the proxy_config parameter will require a String value, not an Array in libhoney 2.0.
|
274
|
+
To resolve:
|
275
|
+
+ recommended: set http/https_proxy environment variables, which take precedence over any option set here, then remove proxy_config parameter from client initialization
|
276
|
+
+ set proxy_config to a String containing the forwarding proxy URI (only used if http/https_proxy are not set)
|
277
|
+
WARNING
|
278
|
+
host, port, user, password = config
|
279
|
+
|
280
|
+
parsed_config = URI::HTTP.build(host: host, port: port).tap do |uri|
|
281
|
+
uri.userinfo = "#{user}:#{password}" if user
|
282
|
+
end
|
283
|
+
redacted_config = parsed_config.dup.tap do |uri|
|
284
|
+
uri.password = 'REDACTED' unless uri.password.nil? || uri.password.empty?
|
285
|
+
end
|
286
|
+
warn "The array config given has been assumed to mean: #{redacted_config}"
|
287
|
+
parsed_config
|
288
|
+
end
|
289
|
+
rescue URI::Error => e
|
290
|
+
warn "#{self.class.name}: unable to parse proxy_config. Detail: #{e.class}: #{e.message}"
|
291
|
+
end
|
227
292
|
end
|
228
293
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'libhoney/queueing'
|
2
|
+
require 'libhoney/transmission'
|
3
|
+
|
4
|
+
module Libhoney
|
5
|
+
##
|
6
|
+
# An experimental variant of the standard {TransmissionClient} that uses
|
7
|
+
# a custom implementation of a sized queue whose pop/push methods support
|
8
|
+
# a timeout internally.
|
9
|
+
#
|
10
|
+
# @example Use this transmission with the Ruby Beeline
|
11
|
+
# require 'libhoney/experimental_transmission'
|
12
|
+
#
|
13
|
+
# Honeycomb.configure do |config|
|
14
|
+
# config.client = Libhoney::Client.new(
|
15
|
+
# writekey: ENV["HONEYCOMB_WRITE_KEY"],
|
16
|
+
# dataset: ENV.fetch("HONEYCOMB_DATASET", "awesome_sauce"),
|
17
|
+
# transmission: Libhoney::ExperimentalTransmissionClient
|
18
|
+
# )
|
19
|
+
# ...
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
#
|
24
|
+
class ExperimentalTransmissionClient < TransmissionClient
|
25
|
+
def add(event)
|
26
|
+
return unless event_valid(event)
|
27
|
+
|
28
|
+
begin
|
29
|
+
# if block_on_send is true, never timeout the wait to enqueue an event
|
30
|
+
# otherwise, timeout the wait immediately and if the queue is full, we'll
|
31
|
+
# have a ThreadError raised because we could not add to the queue.
|
32
|
+
timeout = @block_on_send ? :never : 0
|
33
|
+
@batch_queue.enq(event, timeout)
|
34
|
+
rescue Libhoney::Queueing::SizedQueueWithTimeout::PushTimedOut
|
35
|
+
# happens if the queue was full and block_on_send = false.
|
36
|
+
warn "#{self.class.name}: batch queue full, dropping event." if %w[debug trace].include?(ENV['LOG_LEVEL'])
|
37
|
+
end
|
38
|
+
|
39
|
+
ensure_threads_running
|
40
|
+
end
|
41
|
+
|
42
|
+
def batch_loop
|
43
|
+
next_send_time = Time.now + @send_frequency
|
44
|
+
batched_events = Hash.new do |h, key|
|
45
|
+
h[key] = []
|
46
|
+
end
|
47
|
+
|
48
|
+
loop do
|
49
|
+
begin
|
50
|
+
# an event on the batch_queue
|
51
|
+
# 1. pops out and is truthy
|
52
|
+
# 2. gets included in the current batch
|
53
|
+
# 3. while waits for another event
|
54
|
+
while (event = @batch_queue.pop(@send_frequency))
|
55
|
+
key = [event.api_host, event.writekey, event.dataset]
|
56
|
+
batched_events[key] << event
|
57
|
+
end
|
58
|
+
|
59
|
+
# a nil on the batch_queue
|
60
|
+
# 1. pops out and is falsy
|
61
|
+
# 2. ends the event-popping while do..end
|
62
|
+
# 3. breaks the loop
|
63
|
+
# 4. flushes the current batch
|
64
|
+
# 5. ends the batch_loop
|
65
|
+
break
|
66
|
+
|
67
|
+
# a timeout expiration waiting for an event
|
68
|
+
# 1. skips the break and is rescued
|
69
|
+
# 2. triggers the ensure to flush the current batch
|
70
|
+
# 3. begins the loop again with an updated next_send_time
|
71
|
+
rescue Libhoney::Queueing::SizedQueueWithTimeout::PopTimedOut => e
|
72
|
+
warn "#{self.class.name}: ⏱ " + e.message if %w[trace].include?(ENV['LOG_LEVEL'])
|
73
|
+
|
74
|
+
# any exception occurring in this loop should not take down the actual
|
75
|
+
# instrumented Ruby process, so handle here and log that there is trouble
|
76
|
+
rescue Exception => e
|
77
|
+
warn "#{self.class.name}: 💥 " + e.message if %w[debug trace].include?(ENV['LOG_LEVEL'])
|
78
|
+
warn e.backtrace.join("\n").to_s if ['trace'].include?(ENV['LOG_LEVEL'])
|
79
|
+
|
80
|
+
# regardless of the exception, figure out whether enough time has passed to
|
81
|
+
# send the current batched events, if so, send them and figure out the next send time
|
82
|
+
# before going back to the top of the loop
|
83
|
+
ensure
|
84
|
+
next_send_time = flush_batched_events(batched_events) if Time.now > next_send_time
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# don't need to capture the next_send_time here because the batch_loop is exiting
|
89
|
+
# for some reason (probably transmission.close)
|
90
|
+
flush_batched_events(batched_events)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def setup_batch_queue
|
96
|
+
# override super()'s @batch_queue = SizedQueue.new(); use our SizedQueueWithTimeout:
|
97
|
+
# + block on adding events to the batch_queue when queue is full and @block_on_send is true
|
98
|
+
# + the queue knows how to limit size and how to time-out pushes and pops
|
99
|
+
@batch_queue = Libhoney::Queueing::SizedQueueWithTimeout.new(@pending_work_capacity)
|
100
|
+
warn "⚠️🐆 #{self.class.name} in use! It may drop data, consume all your memory, or cause skin irritation."
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_user_agent(user_agent_addition)
|
104
|
+
super("(exp-transmission) #{user_agent_addition}".strip)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2021 Honeycomb
|
2
|
+
Copyright (c) 2013 Avdi Grimm
|
3
|
+
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|