dogstatsd-ruby 4.1.0 → 4.6.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 +4 -4
- data/README.md +40 -63
- data/lib/datadog/statsd.rb +177 -64
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d521571f811d6206670773db4ac3808c02513d8761445ecf917f831578e2614
|
4
|
+
data.tar.gz: 97d68494f8520a777569dc8f7b3c04070152aa0924edabc67ffa0ae1f16cb615
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f43fb9314373873b5d436824a3cae0a5dc0ef4fcc2a458b8a98b98dbd8b12cb28d3b32293436451829a53da8cb70f17c6104aa64403cfb6000822e59a74ca29a
|
7
|
+
data.tar.gz: a796456e38da22047d952b7a1bebaf1f923a0847c29a9e7548020c8b658144e729133e7e90a16453d0f48a815353734523870e2e391371d8699f1d6574bd8379
|
data/README.md
CHANGED
@@ -1,95 +1,72 @@
|
|
1
|
+
# dogstatsd-ruby
|
1
2
|
|
2
|
-
dogstatsd-ruby
|
3
|
-
==============
|
3
|
+
A client for DogStatsD, an extension of the StatsD metric server for Datadog. Full API documentation is available in [DogStatsD-ruby rubydoc](https://www.rubydoc.info/github/DataDog/dogstatsd-ruby/master/Datadog/Statsd).
|
4
4
|
|
5
|
-
|
5
|
+
[](http://travis-ci.org/DataDog/dogstatsd-ruby)
|
6
6
|
|
7
|
-
[
|
7
|
+
See [CHANGELOG.md](CHANGELOG.md) for changes. To suggest a feature, report a bug, or general discussion, [open an issue](http://github.com/DataDog/dogstatsd-ruby/issues/).
|
8
8
|
|
9
|
-
|
10
|
-
-----------------
|
9
|
+
## Installation
|
11
10
|
|
12
11
|
First install the library:
|
13
12
|
|
14
|
-
|
13
|
+
```
|
14
|
+
gem install dogstatsd-ruby
|
15
|
+
```
|
16
|
+
|
17
|
+
## Configuration
|
15
18
|
|
16
|
-
|
19
|
+
To instantiate a DogStatsd client:
|
17
20
|
|
18
|
-
```
|
19
|
-
#
|
21
|
+
```ruby
|
22
|
+
# Import the library
|
20
23
|
require 'datadog/statsd'
|
21
24
|
|
22
|
-
# Create a
|
25
|
+
# Create a DogStatsD client instance.
|
23
26
|
statsd = Datadog::Statsd.new('localhost', 8125)
|
24
|
-
|
25
|
-
# you could also create a statsd class if you need a drop in replacement
|
26
|
-
# class Statsd < Datadog::Statsd
|
27
|
-
# end
|
28
|
-
|
29
|
-
# Increment a counter.
|
30
|
-
statsd.increment('page.views')
|
31
|
-
|
32
|
-
# Record a gauge 50% of the time.
|
33
|
-
statsd.gauge('users.online', 123, :sample_rate=>0.5)
|
34
|
-
|
35
|
-
# Sample a histogram
|
36
|
-
statsd.histogram('file.upload.size', 1234)
|
37
|
-
|
38
|
-
# Time a block of code
|
39
|
-
statsd.time('page.render') do
|
40
|
-
render_page('home.html')
|
41
|
-
end
|
42
|
-
|
43
|
-
# Send several metrics at the same time
|
44
|
-
# All metrics will be buffered and sent in one packet when the block completes
|
45
|
-
statsd.batch do |s|
|
46
|
-
s.increment('page.views')
|
47
|
-
s.gauge('users.online', 123)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Tag a metric.
|
51
|
-
statsd.histogram('query.time', 10, :tags => ["version:1"])
|
52
|
-
|
53
|
-
# Auto-close socket after end of block
|
54
|
-
Datadog::Statsd.open('localhost', 8125) do |s|
|
55
|
-
s.increment('page.views')
|
56
|
-
end
|
57
27
|
```
|
58
28
|
|
59
|
-
|
29
|
+
Find a list of all the available options for your DogStatsD Client in the [DogStatsD-ruby rubydoc](https://www.rubydoc.info/github/DataDog/dogstatsd-ruby/master/Datadog/Statsd) or in the [Datadog public DogStatsD documentation](https://docs.datadoghq.com/developers/dogstatsd/?tab=go#client-instantiation-parameters).
|
60
30
|
|
61
|
-
|
31
|
+
### Origin detection over UDP
|
62
32
|
|
63
|
-
|
64
|
-
# Post a simple message
|
65
|
-
statsd.event("There might be a storm tomorrow", "A friend warned me earlier.")
|
33
|
+
Origin detection is a method to detect which pod DogStatsD packets are coming from in order to add the pod's tags to the tag list.
|
66
34
|
|
67
|
-
|
68
|
-
|
35
|
+
To enable origin detection over UDP, add the following lines to your application manifest
|
36
|
+
```yaml
|
37
|
+
env:
|
38
|
+
- name: DD_ENTITY_ID
|
39
|
+
valueFrom:
|
40
|
+
fieldRef:
|
41
|
+
fieldPath: metadata.uid
|
69
42
|
```
|
43
|
+
The DogStatsD client attaches an internal tag, `entity_id`. The value of this tag is the content of the `DD_ENTITY_ID` environment variable, which is the pod’s UID.
|
70
44
|
|
45
|
+
## Usage
|
71
46
|
|
47
|
+
In order to use DogStatsD metrics, events, and Service Checks the Agent must be [running and available](https://docs.datadoghq.com/developers/dogstatsd/?tab=ruby).
|
72
48
|
|
73
|
-
|
74
|
-
-------------
|
49
|
+
### Metrics
|
75
50
|
|
76
|
-
|
77
|
-
[here](http://www.rubydoc.info/github/DataDog/dogstatsd-ruby/master/frames).
|
51
|
+
After the client is created, you can start sending custom metrics to Datadog. See the dedicated [Metric Submission: DogStatsD documentation](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby) to see how to submit all supported metric types to Datadog with working code examples:
|
78
52
|
|
53
|
+
* [Submit a COUNT metric](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#count).
|
54
|
+
* [Submit a GAUGE metric](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#gauge).
|
55
|
+
* [Submit a SET metric](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#set)
|
56
|
+
* [Submit a HISTOGRAM metric](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#histogram)
|
57
|
+
* [Submit a DISTRIBUTION metric](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#distribution)
|
79
58
|
|
80
|
-
|
81
|
-
--------
|
59
|
+
Some options are suppported when submitting metrics, like [applying a Sample Rate to your metrics](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#metric-submission-options) or [tagging your metrics with your custom tags](https://docs.datadoghq.com/developers/metrics/dogstatsd_metrics_submission/?tab=ruby#metric-tagging). Find all the available functions to report metrics in the [DogStatsD-ruby rubydoc](https://www.rubydoc.info/github/DataDog/dogstatsd-ruby/master/Datadog/Statsd).
|
82
60
|
|
83
|
-
|
84
|
-
[here](http://github.com/DataDog/dogstatsd-ruby/issues/).
|
61
|
+
### Events
|
85
62
|
|
63
|
+
After the client is created, you can start sending events to your Datadog Event Stream. See the dedicated [Event Submission: DogStatsD documentation](https://docs.datadoghq.com/developers/events/dogstatsd/?tab=ruby) to see how to submit an event to Datadog your Event Stream.
|
86
64
|
|
87
|
-
|
88
|
-
----------------------------
|
65
|
+
### Service Checks
|
89
66
|
|
67
|
+
After the client is created, you can start sending Service Checks to Datadog. See the dedicated [Service Check Submission: DogStatsD documentation](https://docs.datadoghq.com/developers/service_checks/dogstatsd_service_checks_submission/?tab=ruby) to see how to submit a Service Check to Datadog.
|
90
68
|
|
91
|
-
Credits
|
92
|
-
-------
|
69
|
+
## Credits
|
93
70
|
|
94
71
|
dogstatsd-ruby is forked from Rien Henrichs [original Statsd
|
95
72
|
client](https://github.com/reinh/statsd).
|
data/lib/datadog/statsd.rb
CHANGED
@@ -20,6 +20,56 @@ require 'socket'
|
|
20
20
|
module Datadog
|
21
21
|
class Statsd
|
22
22
|
|
23
|
+
class Telemetry
|
24
|
+
attr_accessor :metrics
|
25
|
+
attr_accessor :events
|
26
|
+
attr_accessor :service_checks
|
27
|
+
attr_accessor :bytes_sent
|
28
|
+
attr_accessor :bytes_dropped
|
29
|
+
attr_accessor :packets_sent
|
30
|
+
attr_accessor :packets_dropped
|
31
|
+
attr_reader :estimate_max_size
|
32
|
+
|
33
|
+
def initialize(disabled, tags)
|
34
|
+
@disabled = disabled
|
35
|
+
@tags = tags
|
36
|
+
reset
|
37
|
+
|
38
|
+
# estimate_max_size is an estimation or the maximum size of the
|
39
|
+
# telemetry payload. Since we don't want our packet to go over
|
40
|
+
# 'max_buffer_bytes', we have to adjust with the size of the telemetry
|
41
|
+
# (and any tags used). The telemetry payload size will change depending
|
42
|
+
# on the actual value of metrics: metrics received, packet dropped,
|
43
|
+
# etc. This is why we add a 63bytes margin: 9 bytes for each of the 7
|
44
|
+
# telemetry metrics.
|
45
|
+
@estimate_max_size = @disabled ? 0 : flush().length + 9 * 7
|
46
|
+
end
|
47
|
+
|
48
|
+
def reset
|
49
|
+
@metrics = 0
|
50
|
+
@events = 0
|
51
|
+
@service_checks = 0
|
52
|
+
@bytes_sent = 0
|
53
|
+
@bytes_dropped = 0
|
54
|
+
@packets_sent = 0
|
55
|
+
@packets_dropped = 0
|
56
|
+
end
|
57
|
+
|
58
|
+
def flush
|
59
|
+
return '' if @disabled
|
60
|
+
|
61
|
+
# using shorthand syntax to reduce the garbage collection
|
62
|
+
return %Q(
|
63
|
+
datadog.dogstatsd.client.metrics:#{@metrics}|#{COUNTER_TYPE}|##{@tags}
|
64
|
+
datadog.dogstatsd.client.events:#{@events}|#{COUNTER_TYPE}|##{@tags}
|
65
|
+
datadog.dogstatsd.client.service_checks:#{@service_checks}|#{COUNTER_TYPE}|##{@tags}
|
66
|
+
datadog.dogstatsd.client.bytes_sent:#{@bytes_sent}|#{COUNTER_TYPE}|##{@tags}
|
67
|
+
datadog.dogstatsd.client.bytes_dropped:#{@bytes_dropped}|#{COUNTER_TYPE}|##{@tags}
|
68
|
+
datadog.dogstatsd.client.packets_sent:#{@packets_sent}|#{COUNTER_TYPE}|##{@tags}
|
69
|
+
datadog.dogstatsd.client.packets_dropped:#{@packets_dropped}|#{COUNTER_TYPE}|##{@tags})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
23
73
|
class Connection
|
24
74
|
DEFAULT_HOST = '127.0.0.1'
|
25
75
|
DEFAULT_PORT = 8125
|
@@ -33,36 +83,30 @@ module Datadog
|
|
33
83
|
# DogStatsd unix socket path. Not used by default.
|
34
84
|
attr_reader :socket_path
|
35
85
|
|
36
|
-
def initialize(
|
37
|
-
@
|
38
|
-
|
39
|
-
|
40
|
-
|
86
|
+
def initialize(telemetry)
|
87
|
+
@telemetry = telemetry
|
88
|
+
end
|
89
|
+
|
90
|
+
# Close the underlying socket
|
91
|
+
def close
|
92
|
+
@socket && @socket.close
|
41
93
|
end
|
42
94
|
|
43
95
|
def write(message)
|
44
96
|
@logger.debug { "Statsd: #{message}" } if @logger
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
socket.sendmsg_nonblock(message)
|
49
|
-
end
|
50
|
-
rescue StandardError => boom
|
51
|
-
# Give up on this socket if it looks like it is bad
|
52
|
-
bad_socket = !@socket_path.nil? && (
|
53
|
-
boom.is_a?(Errno::ECONNREFUSED) ||
|
54
|
-
boom.is_a?(Errno::ECONNRESET) ||
|
55
|
-
boom.is_a?(Errno::ENOENT)
|
56
|
-
)
|
57
|
-
if bad_socket
|
58
|
-
@socket = nil
|
59
|
-
return
|
60
|
-
end
|
97
|
+
payload = message + @telemetry.flush()
|
98
|
+
send_message(payload)
|
61
99
|
|
100
|
+
@telemetry.reset
|
101
|
+
@telemetry.bytes_sent += payload.length
|
102
|
+
@telemetry.packets_sent += 1
|
103
|
+
rescue StandardError => boom
|
62
104
|
# Try once to reconnect if the socket has been closed
|
63
105
|
retries ||= 1
|
64
|
-
if retries <= 1 &&
|
65
|
-
|
106
|
+
if retries <= 1 &&
|
107
|
+
(boom.is_a?(Errno::ENOTCONN) or
|
108
|
+
boom.is_a?(Errno::ECONNREFUSED) or
|
109
|
+
boom.is_a?(IOError) && boom.message =~ /closed stream/i)
|
66
110
|
retries += 1
|
67
111
|
begin
|
68
112
|
@socket = connect
|
@@ -72,31 +116,63 @@ module Datadog
|
|
72
116
|
end
|
73
117
|
end
|
74
118
|
|
119
|
+
@telemetry.bytes_dropped += payload.length
|
120
|
+
@telemetry.packets_dropped += 1
|
75
121
|
@logger.error { "Statsd: #{boom.class} #{boom}" } if @logger
|
76
122
|
nil
|
77
123
|
end
|
78
124
|
|
79
|
-
# Close the underlying socket
|
80
|
-
def close
|
81
|
-
@socket && @socket.close
|
82
|
-
end
|
83
|
-
|
84
125
|
private
|
85
126
|
|
86
127
|
def socket
|
87
128
|
@socket ||= connect
|
88
129
|
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class UDPConnection < Connection
|
133
|
+
def initialize(host, port, logger, telemetry)
|
134
|
+
super(telemetry)
|
135
|
+
@host = host || ENV.fetch('DD_AGENT_HOST', nil) || DEFAULT_HOST
|
136
|
+
@port = port || ENV.fetch('DD_DOGSTATSD_PORT', nil) || DEFAULT_PORT
|
137
|
+
@logger = logger
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
89
141
|
|
90
142
|
def connect
|
91
|
-
|
92
|
-
|
93
|
-
socket.connect(@host, @port)
|
94
|
-
else
|
95
|
-
socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
|
96
|
-
socket.connect(Socket.pack_sockaddr_un(@socket_path))
|
97
|
-
end
|
143
|
+
socket = UDPSocket.new
|
144
|
+
socket.connect(@host, @port)
|
98
145
|
socket
|
99
146
|
end
|
147
|
+
|
148
|
+
def send_message(message)
|
149
|
+
socket.send(message, 0)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
class UDSConnection < Connection
|
154
|
+
class BadSocketError < StandardError; end
|
155
|
+
|
156
|
+
def initialize(socket_path, logger, telemetry)
|
157
|
+
super(telemetry)
|
158
|
+
@socket_path = socket_path
|
159
|
+
@logger = logger
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def connect
|
165
|
+
socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
|
166
|
+
socket.connect(Socket.pack_sockaddr_un(@socket_path))
|
167
|
+
socket
|
168
|
+
end
|
169
|
+
|
170
|
+
def send_message(message)
|
171
|
+
socket.sendmsg_nonblock(message)
|
172
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ENOENT => e
|
173
|
+
@socket = nil
|
174
|
+
raise BadSocketError, "#{e.class}: #{e}"
|
175
|
+
end
|
100
176
|
end
|
101
177
|
|
102
178
|
class Batch
|
@@ -173,7 +249,8 @@ module Datadog
|
|
173
249
|
CRITICAL = 2
|
174
250
|
UNKNOWN = 3
|
175
251
|
|
176
|
-
|
252
|
+
DEFAULT_BUFFER_SIZE = 8 * 1_024
|
253
|
+
MAX_EVENT_SIZE = 8 * 1_024
|
177
254
|
|
178
255
|
COUNTER_TYPE = 'c'.freeze
|
179
256
|
GAUGE_TYPE = 'g'.freeze
|
@@ -181,7 +258,7 @@ module Datadog
|
|
181
258
|
DISTRIBUTION_TYPE = 'd'.freeze
|
182
259
|
TIMING_TYPE = 'ms'.freeze
|
183
260
|
SET_TYPE = 's'.freeze
|
184
|
-
VERSION = "4.
|
261
|
+
VERSION = "4.6.0".freeze
|
185
262
|
|
186
263
|
# A namespace to prepend to all statsd calls. Defaults to no namespace.
|
187
264
|
attr_reader :namespace
|
@@ -195,35 +272,60 @@ module Datadog
|
|
195
272
|
# Maximum buffer size in bytes before it is flushed
|
196
273
|
attr_reader :max_buffer_bytes
|
197
274
|
|
275
|
+
# Default sample rate
|
276
|
+
attr_reader :sample_rate
|
277
|
+
|
198
278
|
# Connection
|
199
279
|
attr_reader :connection
|
200
280
|
|
201
281
|
# @param [String] host your statsd host
|
202
282
|
# @param [Integer] port your statsd port
|
203
283
|
# @option [String] namespace set a namespace to be prepended to every metric name
|
204
|
-
# @option [Array<String
|
205
|
-
# @option [
|
284
|
+
# @option [Array<String>|Hash] tags tags to be added to every metric
|
285
|
+
# @option [Logger] logger for debugging
|
206
286
|
# @option [Integer] max_buffer_bytes max bytes to buffer when using #batch
|
207
287
|
# @option [String] socket_path unix socket path
|
288
|
+
# @option [Float] default sample rate if not overridden
|
208
289
|
def initialize(
|
209
290
|
host = nil,
|
210
291
|
port = nil,
|
211
292
|
namespace: nil,
|
212
293
|
tags: nil,
|
213
|
-
max_buffer_bytes:
|
294
|
+
max_buffer_bytes: DEFAULT_BUFFER_SIZE,
|
214
295
|
socket_path: nil,
|
215
|
-
logger: nil
|
296
|
+
logger: nil,
|
297
|
+
sample_rate: nil,
|
298
|
+
disable_telemetry: false
|
216
299
|
)
|
217
|
-
|
300
|
+
unless tags.nil? or tags.is_a? Array or tags.is_a? Hash
|
301
|
+
raise ArgumentError, 'tags must be a Array<String> or a Hash'
|
302
|
+
end
|
303
|
+
|
304
|
+
tags = tag_hash_to_array(tags) if tags.is_a? Hash
|
305
|
+
@tags = (tags || []).compact.map! {|tag| escape_tag_content(tag)}
|
306
|
+
|
307
|
+
# append the entity id to tags if DD_ENTITY_ID env var is not nil
|
308
|
+
@tags << 'dd.internal.entity_id:' + escape_tag_content(ENV.fetch('DD_ENTITY_ID', nil)) unless ENV.fetch('DD_ENTITY_ID', nil).nil?
|
309
|
+
|
310
|
+
# init telemetry
|
311
|
+
transport_type = socket_path.nil? ? "udp": "uds"
|
312
|
+
telemetry_tags = (["client:ruby", "client_version:#{VERSION}", "client_transport:#{transport_type}"] + @tags).join(COMMA).freeze
|
313
|
+
@telemetry = Telemetry.new(disable_telemetry, telemetry_tags)
|
314
|
+
|
315
|
+
if socket_path.nil?
|
316
|
+
@connection = UDPConnection.new(host, port, logger, @telemetry)
|
317
|
+
else
|
318
|
+
@connection = UDSConnection.new(socket_path, logger, @telemetry)
|
319
|
+
end
|
218
320
|
@logger = logger
|
219
321
|
|
220
322
|
@namespace = namespace
|
221
323
|
@prefix = @namespace ? "#{@namespace}.".freeze : nil
|
222
324
|
|
223
|
-
|
224
|
-
@tags = (tags || []).compact.map! {|tag| escape_tag_content(tag)}
|
325
|
+
@sample_rate = sample_rate
|
225
326
|
|
226
|
-
|
327
|
+
# we reduce max_buffer_bytes by a the rough estimate of the telemetry payload
|
328
|
+
@batch = Batch.new(@connection, (max_buffer_bytes - @telemetry.estimate_max_size))
|
227
329
|
end
|
228
330
|
|
229
331
|
# yield a new instance to a block and close it when done
|
@@ -307,9 +409,6 @@ module Datadog
|
|
307
409
|
end
|
308
410
|
|
309
411
|
# Sends a value to be tracked as a distribution to the statsd server.
|
310
|
-
# Note: Distributions are a beta feature of Datadog and not generally
|
311
|
-
# available. Distributions must be specifically enabled for your
|
312
|
-
# organization.
|
313
412
|
#
|
314
413
|
# @param [String] stat stat name.
|
315
414
|
# @param [Numeric] value distribution value.
|
@@ -378,13 +477,14 @@ module Datadog
|
|
378
477
|
# @param [String] name Service check name
|
379
478
|
# @param [String] status Service check status.
|
380
479
|
# @param [Hash] opts the additional data about the service check
|
381
|
-
# @option opts [Integer, nil] :timestamp (nil) Assign a timestamp to the
|
382
|
-
# @option opts [String, nil] :hostname (nil) Assign a hostname to the
|
480
|
+
# @option opts [Integer, String, nil] :timestamp (nil) Assign a timestamp to the service check. Default is now when none
|
481
|
+
# @option opts [String, nil] :hostname (nil) Assign a hostname to the service check.
|
383
482
|
# @option opts [Array<String>, nil] :tags (nil) An array of tags
|
384
483
|
# @option opts [String, nil] :message (nil) A message to associate with this service check status
|
385
484
|
# @example Report a critical service check status
|
386
485
|
# $statsd.service_check('my.service.check', Statsd::CRITICAL, :tags=>['urgent'])
|
387
486
|
def service_check(name, status, opts=EMPTY_OPTIONS)
|
487
|
+
@telemetry.service_checks += 1
|
388
488
|
send_stat format_service_check(name, status, opts)
|
389
489
|
end
|
390
490
|
|
@@ -395,9 +495,9 @@ module Datadog
|
|
395
495
|
# it will be grouped with other events that don't have an event type.
|
396
496
|
#
|
397
497
|
# @param [String] title Event title
|
398
|
-
# @param [String] text Event text. Supports
|
498
|
+
# @param [String] text Event text. Supports newlines (+\n+)
|
399
499
|
# @param [Hash] opts the additional data about the event
|
400
|
-
# @option opts [Integer, nil] :date_happened (nil) Assign a timestamp to the event. Default is now when none
|
500
|
+
# @option opts [Integer, String, nil] :date_happened (nil) Assign a timestamp to the event. Default is now when none
|
401
501
|
# @option opts [String, nil] :hostname (nil) Assign a hostname to the event.
|
402
502
|
# @option opts [String, nil] :aggregation_key (nil) Assign an aggregation key to the event, to group it with some others
|
403
503
|
# @option opts [String, nil] :priority ('normal') Can be "normal" or "low"
|
@@ -407,6 +507,7 @@ module Datadog
|
|
407
507
|
# @example Report an awful event:
|
408
508
|
# $statsd.event('Something terrible happened', 'The end is near if we do nothing', :alert_type=>'warning', :tags=>['end_of_times','urgent'])
|
409
509
|
def event(title, text, opts=EMPTY_OPTIONS)
|
510
|
+
@telemetry.events += 1
|
410
511
|
send_stat format_event(title, text, opts)
|
411
512
|
end
|
412
513
|
|
@@ -457,7 +558,11 @@ module Datadog
|
|
457
558
|
escaped_message = escape_service_check_message(message)
|
458
559
|
sc_string << "|m:#{escaped_message}"
|
459
560
|
else
|
460
|
-
|
561
|
+
if key == :timestamp && opts[key].is_a?(Integer)
|
562
|
+
value = opts[key]
|
563
|
+
else
|
564
|
+
value = remove_pipes(opts[key])
|
565
|
+
end
|
461
566
|
sc_string << "|#{shorthand_key}#{value}"
|
462
567
|
end
|
463
568
|
end
|
@@ -467,13 +572,20 @@ module Datadog
|
|
467
572
|
def format_event(title, text, opts=EMPTY_OPTIONS)
|
468
573
|
escaped_title = escape_event_content(title)
|
469
574
|
escaped_text = escape_event_content(text)
|
470
|
-
event_string_data = "_e{#{escaped_title.
|
575
|
+
event_string_data = "_e{#{escaped_title.bytesize},#{escaped_text.bytesize}}:#{escaped_title}|#{escaped_text}".dup
|
471
576
|
|
472
577
|
# We construct the string to be sent by adding '|key:value' parts to it when needed
|
473
578
|
# All pipes ('|') in the metadata are removed. Title and Text can keep theirs
|
474
579
|
OPTS_KEYS.each do |key, shorthand_key|
|
475
580
|
if key != :tags && opts[key]
|
476
|
-
value
|
581
|
+
# :date_happened is the only key where the value is an Integer
|
582
|
+
# To not break backwards compatibility, we still accept a String
|
583
|
+
if key == :date_happened && opts[key].is_a?(Integer)
|
584
|
+
value = opts[key]
|
585
|
+
# All other keys only have String values
|
586
|
+
else
|
587
|
+
value = remove_pipes(opts[key])
|
588
|
+
end
|
477
589
|
event_string_data << "|#{shorthand_key}:#{value}"
|
478
590
|
end
|
479
591
|
end
|
@@ -483,12 +595,13 @@ module Datadog
|
|
483
595
|
event_string_data << "|##{tags_string}"
|
484
596
|
end
|
485
597
|
|
486
|
-
raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.
|
598
|
+
raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.bytesize > MAX_EVENT_SIZE
|
487
599
|
event_string_data
|
488
600
|
end
|
489
601
|
|
490
602
|
def tags_as_string(opts)
|
491
603
|
if tag_arr = opts[:tags]
|
604
|
+
tag_arr = tag_hash_to_array(tag_arr) if tag_arr.is_a? Hash
|
492
605
|
tag_arr = tag_arr.map { |tag| escape_tag_content(tag) }
|
493
606
|
tag_arr = tags + tag_arr # @tags are normalized when set, so not need to normalize them again
|
494
607
|
else
|
@@ -497,6 +610,10 @@ module Datadog
|
|
497
610
|
tag_arr.join(COMMA) unless tag_arr.empty?
|
498
611
|
end
|
499
612
|
|
613
|
+
def tag_hash_to_array(tag_hash)
|
614
|
+
tag_hash.to_a.map {|pair| pair.compact.join(":")}
|
615
|
+
end
|
616
|
+
|
500
617
|
def escape_event_content(msg)
|
501
618
|
msg.gsub NEW_LINE, ESC_NEW_LINE
|
502
619
|
end
|
@@ -516,8 +633,9 @@ module Datadog
|
|
516
633
|
end
|
517
634
|
|
518
635
|
def send_stats(stat, delta, type, opts=EMPTY_OPTIONS)
|
519
|
-
|
520
|
-
|
636
|
+
@telemetry.metrics += 1
|
637
|
+
sample_rate = opts[:sample_rate] || @sample_rate || 1
|
638
|
+
if sample_rate == 1 or rand <= sample_rate
|
521
639
|
full_stat = ''.dup
|
522
640
|
full_stat << @prefix if @prefix
|
523
641
|
|
@@ -543,17 +661,12 @@ module Datadog
|
|
543
661
|
full_stat << '#'.freeze
|
544
662
|
full_stat << tags_string
|
545
663
|
end
|
546
|
-
|
547
664
|
send_stat(full_stat)
|
548
665
|
end
|
549
666
|
end
|
550
667
|
|
551
668
|
def send_stat(message)
|
552
|
-
|
553
|
-
@batch.add message
|
554
|
-
else
|
555
|
-
@connection.write(message)
|
556
|
-
end
|
669
|
+
@batch.open? ? @batch.add(message) : @connection.write(message)
|
557
670
|
end
|
558
671
|
end
|
559
672
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dogstatsd-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rein Henrichs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A Ruby DogStastd client
|
14
14
|
email: code@datadoghq.com
|
@@ -21,10 +21,14 @@ files:
|
|
21
21
|
- LICENSE.txt
|
22
22
|
- README.md
|
23
23
|
- lib/datadog/statsd.rb
|
24
|
-
homepage:
|
24
|
+
homepage: https://github.com/DataDog/dogstatsd-ruby
|
25
25
|
licenses:
|
26
26
|
- MIT
|
27
|
-
metadata:
|
27
|
+
metadata:
|
28
|
+
bug_tracker_uri: https://github.com/DataDog/dogstatsd-ruby/issues
|
29
|
+
changelog_uri: https://github.com/DataDog/dogstatsd-ruby/blob/v4.6.0/CHANGELOG.md
|
30
|
+
documentation_uri: https://www.rubydoc.info/gems/dogstatsd-ruby/4.6.0
|
31
|
+
source_code_uri: https://github.com/DataDog/dogstatsd-ruby/tree/v4.6.0
|
28
32
|
post_install_message:
|
29
33
|
rdoc_options: []
|
30
34
|
require_paths:
|
@@ -40,7 +44,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
44
|
- !ruby/object:Gem::Version
|
41
45
|
version: '0'
|
42
46
|
requirements: []
|
43
|
-
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.7.10
|
44
49
|
signing_key:
|
45
50
|
specification_version: 4
|
46
51
|
summary: A Ruby DogStatsd client
|