dogstatsd-ruby 4.2.0 → 4.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.
- checksums.yaml +4 -4
- data/README.md +28 -4
- data/lib/datadog/statsd.rb +91 -49
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25baf4b0dc57e8ed9a79bd2115224f22de9097200ccf4931b54fbb1e40905363
|
4
|
+
data.tar.gz: a51c91dc366316b6edbadc64eb5e7383b6b100c9a2a859eb9bc31b9bef9ec7e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 225ef009dcb475534ec746d9eaa6e8b156ad7b50291c2894ba9171806bc91231150510a65a47ec754dbf519f80fe7381c589d34f35e983519fb8e991347e1a12
|
7
|
+
data.tar.gz: e8609033506332625db4a6655adceacfb7fd1b85346020c1582dd032815ea56158d46442cecafd40fdd7bf098745e41ab1e70323b323ff63dd8bb43be3be8b88
|
data/README.md
CHANGED
@@ -28,9 +28,10 @@ statsd = Datadog::Statsd.new('localhost', 8125)
|
|
28
28
|
|
29
29
|
# Increment a counter.
|
30
30
|
statsd.increment('page.views')
|
31
|
+
statsd.increment('messages.count', by: 2, tags: ['kind:incoming'])
|
31
32
|
|
32
33
|
# Record a gauge 50% of the time.
|
33
|
-
statsd.gauge('users.online', 123, :
|
34
|
+
statsd.gauge('users.online', 123, sample_rate: 0.5)
|
34
35
|
|
35
36
|
# Sample a histogram
|
36
37
|
statsd.histogram('file.upload.size', 1234)
|
@@ -48,7 +49,10 @@ statsd.batch do |s|
|
|
48
49
|
end
|
49
50
|
|
50
51
|
# Tag a metric.
|
51
|
-
statsd.histogram('query.time', 10, :
|
52
|
+
statsd.histogram('query.time', 10, tags: ['version:1'])
|
53
|
+
|
54
|
+
# Tag a metric by passing in a Hash
|
55
|
+
statsd.histogram('query.time', 10, :tags => {version: 1})
|
52
56
|
|
53
57
|
# Auto-close socket after end of block
|
54
58
|
Datadog::Statsd.open('localhost', 8125) do |s|
|
@@ -62,14 +66,34 @@ Aggregation in the stream is made on hostname/event_type/source_type/aggregation
|
|
62
66
|
|
63
67
|
``` ruby
|
64
68
|
# Post a simple message
|
65
|
-
statsd.event(
|
69
|
+
statsd.event('There might be a storm tomorrow', 'A friend warned me earlier.')
|
66
70
|
|
67
71
|
# Cry for help
|
68
|
-
statsd.event(
|
72
|
+
statsd.event(
|
73
|
+
'SO MUCH SNOW',
|
74
|
+
"Started yesterday and it won't stop !!",
|
75
|
+
alert_type: 'error',
|
76
|
+
tags: ['urgent', 'endoftheworld']
|
77
|
+
)
|
69
78
|
```
|
70
79
|
|
71
80
|
|
72
81
|
|
82
|
+
Origin detection over UDP
|
83
|
+
-------------
|
84
|
+
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.
|
85
|
+
|
86
|
+
To enable origin detection over UDP, add the following lines to your application manifest
|
87
|
+
```yaml
|
88
|
+
env:
|
89
|
+
- name: DD_ENTITY_ID
|
90
|
+
valueFrom:
|
91
|
+
fieldRef:
|
92
|
+
fieldPath: metadata.uid
|
93
|
+
```
|
94
|
+
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.
|
95
|
+
|
96
|
+
|
73
97
|
Documentation
|
74
98
|
-------------
|
75
99
|
|
data/lib/datadog/statsd.rb
CHANGED
@@ -33,32 +33,15 @@ module Datadog
|
|
33
33
|
# DogStatsd unix socket path. Not used by default.
|
34
34
|
attr_reader :socket_path
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
@
|
39
|
-
@socket_path = socket_path
|
40
|
-
@logger = logger
|
36
|
+
# Close the underlying socket
|
37
|
+
def close
|
38
|
+
@socket && @socket.close
|
41
39
|
end
|
42
40
|
|
43
41
|
def write(message)
|
44
42
|
@logger.debug { "Statsd: #{message}" } if @logger
|
45
|
-
|
46
|
-
socket.send(message, 0)
|
47
|
-
else
|
48
|
-
socket.sendmsg_nonblock(message)
|
49
|
-
end
|
43
|
+
send_message(message)
|
50
44
|
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
|
61
|
-
|
62
45
|
# Try once to reconnect if the socket has been closed
|
63
46
|
retries ||= 1
|
64
47
|
if retries <= 1 && boom.is_a?(Errno::ENOTCONN) or
|
@@ -76,27 +59,55 @@ module Datadog
|
|
76
59
|
nil
|
77
60
|
end
|
78
61
|
|
79
|
-
# Close the underlying socket
|
80
|
-
def close
|
81
|
-
@socket && @socket.close
|
82
|
-
end
|
83
|
-
|
84
62
|
private
|
85
63
|
|
86
64
|
def socket
|
87
65
|
@socket ||= connect
|
88
66
|
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class UDPConnection < Connection
|
70
|
+
def initialize(host, port, logger)
|
71
|
+
@host = host || ENV.fetch('DD_AGENT_HOST', nil) || DEFAULT_HOST
|
72
|
+
@port = port || ENV.fetch('DD_DOGSTATSD_PORT', nil) || DEFAULT_PORT
|
73
|
+
@logger = logger
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
89
77
|
|
90
78
|
def connect
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
79
|
+
socket = UDPSocket.new
|
80
|
+
socket.connect(@host, @port)
|
81
|
+
socket
|
82
|
+
end
|
83
|
+
|
84
|
+
def send_message(message)
|
85
|
+
socket.send(message, 0)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class UDSConnection < Connection
|
90
|
+
class BadSocketError < StandardError; end
|
91
|
+
|
92
|
+
def initialize(socket_path, logger)
|
93
|
+
@socket_path = socket_path
|
94
|
+
@logger = logger
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def connect
|
100
|
+
socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
|
101
|
+
socket.connect(Socket.pack_sockaddr_un(@socket_path))
|
98
102
|
socket
|
99
103
|
end
|
104
|
+
|
105
|
+
def send_message(message)
|
106
|
+
socket.sendmsg_nonblock(message)
|
107
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ENOENT => e
|
108
|
+
@socket = nil
|
109
|
+
raise BadSocketError, "#{e.class}: #{e}"
|
110
|
+
end
|
100
111
|
end
|
101
112
|
|
102
113
|
class Batch
|
@@ -181,7 +192,7 @@ module Datadog
|
|
181
192
|
DISTRIBUTION_TYPE = 'd'.freeze
|
182
193
|
TIMING_TYPE = 'ms'.freeze
|
183
194
|
SET_TYPE = 's'.freeze
|
184
|
-
VERSION = "4.
|
195
|
+
VERSION = "4.4.0".freeze
|
185
196
|
|
186
197
|
# A namespace to prepend to all statsd calls. Defaults to no namespace.
|
187
198
|
attr_reader :namespace
|
@@ -195,16 +206,20 @@ module Datadog
|
|
195
206
|
# Maximum buffer size in bytes before it is flushed
|
196
207
|
attr_reader :max_buffer_bytes
|
197
208
|
|
209
|
+
# Default sample rate
|
210
|
+
attr_reader :sample_rate
|
211
|
+
|
198
212
|
# Connection
|
199
213
|
attr_reader :connection
|
200
214
|
|
201
215
|
# @param [String] host your statsd host
|
202
216
|
# @param [Integer] port your statsd port
|
203
217
|
# @option [String] namespace set a namespace to be prepended to every metric name
|
204
|
-
# @option [Array<String
|
205
|
-
# @option [
|
218
|
+
# @option [Array<String>|Hash] tags tags to be added to every metric
|
219
|
+
# @option [Logger] logger for debugging
|
206
220
|
# @option [Integer] max_buffer_bytes max bytes to buffer when using #batch
|
207
221
|
# @option [String] socket_path unix socket path
|
222
|
+
# @option [Float] default sample rate if not overridden
|
208
223
|
def initialize(
|
209
224
|
host = nil,
|
210
225
|
port = nil,
|
@@ -212,15 +227,26 @@ module Datadog
|
|
212
227
|
tags: nil,
|
213
228
|
max_buffer_bytes: 8192,
|
214
229
|
socket_path: nil,
|
215
|
-
logger: nil
|
230
|
+
logger: nil,
|
231
|
+
sample_rate: nil
|
216
232
|
)
|
217
|
-
|
233
|
+
if socket_path.nil?
|
234
|
+
@connection = UDPConnection.new(host, port, logger)
|
235
|
+
else
|
236
|
+
@connection = UDSConnection.new(socket_path, logger)
|
237
|
+
end
|
218
238
|
@logger = logger
|
219
239
|
|
220
240
|
@namespace = namespace
|
221
241
|
@prefix = @namespace ? "#{@namespace}.".freeze : nil
|
222
242
|
|
223
|
-
|
243
|
+
@sample_rate = sample_rate
|
244
|
+
|
245
|
+
unless tags.nil? or tags.is_a? Array or tags.is_a? Hash
|
246
|
+
raise ArgumentError, 'tags must be a Array<String> or a Hash'
|
247
|
+
end
|
248
|
+
|
249
|
+
tags = tag_hash_to_array(tags) if tags.is_a? Hash
|
224
250
|
@tags = (tags || []).compact.map! {|tag| escape_tag_content(tag)}
|
225
251
|
|
226
252
|
# append the entity id to tags if DD_ENTITY_ID env var is not nil
|
@@ -381,8 +407,8 @@ module Datadog
|
|
381
407
|
# @param [String] name Service check name
|
382
408
|
# @param [String] status Service check status.
|
383
409
|
# @param [Hash] opts the additional data about the service check
|
384
|
-
# @option opts [Integer, nil] :timestamp (nil) Assign a timestamp to the
|
385
|
-
# @option opts [String, nil] :hostname (nil) Assign a hostname to the
|
410
|
+
# @option opts [Integer, String, nil] :timestamp (nil) Assign a timestamp to the service check. Default is now when none
|
411
|
+
# @option opts [String, nil] :hostname (nil) Assign a hostname to the service check.
|
386
412
|
# @option opts [Array<String>, nil] :tags (nil) An array of tags
|
387
413
|
# @option opts [String, nil] :message (nil) A message to associate with this service check status
|
388
414
|
# @example Report a critical service check status
|
@@ -398,9 +424,9 @@ module Datadog
|
|
398
424
|
# it will be grouped with other events that don't have an event type.
|
399
425
|
#
|
400
426
|
# @param [String] title Event title
|
401
|
-
# @param [String] text Event text. Supports
|
427
|
+
# @param [String] text Event text. Supports newlines (+\n+)
|
402
428
|
# @param [Hash] opts the additional data about the event
|
403
|
-
# @option opts [Integer, nil] :date_happened (nil) Assign a timestamp to the event. Default is now when none
|
429
|
+
# @option opts [Integer, String, nil] :date_happened (nil) Assign a timestamp to the event. Default is now when none
|
404
430
|
# @option opts [String, nil] :hostname (nil) Assign a hostname to the event.
|
405
431
|
# @option opts [String, nil] :aggregation_key (nil) Assign an aggregation key to the event, to group it with some others
|
406
432
|
# @option opts [String, nil] :priority ('normal') Can be "normal" or "low"
|
@@ -460,7 +486,11 @@ module Datadog
|
|
460
486
|
escaped_message = escape_service_check_message(message)
|
461
487
|
sc_string << "|m:#{escaped_message}"
|
462
488
|
else
|
463
|
-
|
489
|
+
if key == :timestamp && opts[key].is_a?(Integer)
|
490
|
+
value = opts[key]
|
491
|
+
else
|
492
|
+
value = remove_pipes(opts[key])
|
493
|
+
end
|
464
494
|
sc_string << "|#{shorthand_key}#{value}"
|
465
495
|
end
|
466
496
|
end
|
@@ -470,13 +500,20 @@ module Datadog
|
|
470
500
|
def format_event(title, text, opts=EMPTY_OPTIONS)
|
471
501
|
escaped_title = escape_event_content(title)
|
472
502
|
escaped_text = escape_event_content(text)
|
473
|
-
event_string_data = "_e{#{escaped_title.
|
503
|
+
event_string_data = "_e{#{escaped_title.bytesize},#{escaped_text.bytesize}}:#{escaped_title}|#{escaped_text}".dup
|
474
504
|
|
475
505
|
# We construct the string to be sent by adding '|key:value' parts to it when needed
|
476
506
|
# All pipes ('|') in the metadata are removed. Title and Text can keep theirs
|
477
507
|
OPTS_KEYS.each do |key, shorthand_key|
|
478
508
|
if key != :tags && opts[key]
|
479
|
-
value
|
509
|
+
# :date_happened is the only key where the value is an Integer
|
510
|
+
# To not break backwards compatibility, we still accept a String
|
511
|
+
if key == :date_happened && opts[key].is_a?(Integer)
|
512
|
+
value = opts[key]
|
513
|
+
# All other keys only have String values
|
514
|
+
else
|
515
|
+
value = remove_pipes(opts[key])
|
516
|
+
end
|
480
517
|
event_string_data << "|#{shorthand_key}:#{value}"
|
481
518
|
end
|
482
519
|
end
|
@@ -486,12 +523,13 @@ module Datadog
|
|
486
523
|
event_string_data << "|##{tags_string}"
|
487
524
|
end
|
488
525
|
|
489
|
-
raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.
|
526
|
+
raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.bytesize > MAX_EVENT_SIZE
|
490
527
|
event_string_data
|
491
528
|
end
|
492
529
|
|
493
530
|
def tags_as_string(opts)
|
494
531
|
if tag_arr = opts[:tags]
|
532
|
+
tag_arr = tag_hash_to_array(tag_arr) if tag_arr.is_a? Hash
|
495
533
|
tag_arr = tag_arr.map { |tag| escape_tag_content(tag) }
|
496
534
|
tag_arr = tags + tag_arr # @tags are normalized when set, so not need to normalize them again
|
497
535
|
else
|
@@ -500,6 +538,10 @@ module Datadog
|
|
500
538
|
tag_arr.join(COMMA) unless tag_arr.empty?
|
501
539
|
end
|
502
540
|
|
541
|
+
def tag_hash_to_array(tag_hash)
|
542
|
+
tag_hash.to_a.map {|pair| pair.compact.join(":")}
|
543
|
+
end
|
544
|
+
|
503
545
|
def escape_event_content(msg)
|
504
546
|
msg.gsub NEW_LINE, ESC_NEW_LINE
|
505
547
|
end
|
@@ -519,8 +561,8 @@ module Datadog
|
|
519
561
|
end
|
520
562
|
|
521
563
|
def send_stats(stat, delta, type, opts=EMPTY_OPTIONS)
|
522
|
-
sample_rate = opts[:sample_rate] || 1
|
523
|
-
if sample_rate == 1 or rand
|
564
|
+
sample_rate = opts[:sample_rate] || @sample_rate || 1
|
565
|
+
if sample_rate == 1 or rand <= sample_rate
|
524
566
|
full_stat = ''.dup
|
525
567
|
full_stat << @prefix if @prefix
|
526
568
|
|
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.4.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: 2019-
|
11
|
+
date: 2019-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A Ruby DogStastd client
|
14
14
|
email: code@datadoghq.com
|
@@ -40,7 +40,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
requirements: []
|
43
|
-
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.7.6
|
44
45
|
signing_key:
|
45
46
|
specification_version: 4
|
46
47
|
summary: A Ruby DogStatsd client
|