dogstatsd-ruby 4.2.0 → 4.3.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 +75 -44
- 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: b0a17784b24e078a39ee2717d1b7b25d1879e067a5e356db6f98eb012d2bbef2
|
4
|
+
data.tar.gz: 9559cb5d04e7b8dee34becbd0adb9182fb1cbda48ae5de13a470cd1d843d4d8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 652f8010045d42ae2fe2056d6c97f645d54c430b491a1e878cdf85abd22fda2dfbeae74022fb71faa51f5ce636c1bb6dcef60e172ba15c4b74fcd3eded1d9b05
|
7
|
+
data.tar.gz: 42f8763913be88f9871568ac966403f19437c4e477792a771b4b10d9645e2e73f6a588f89c4ba8bd218feb44842f1f6a491434eb0cdc64a2e0a47b30287da8f2
|
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
|
-
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
|
79
|
+
socket = UDPSocket.new
|
80
|
+
socket.connect(@host, @port)
|
98
81
|
socket
|
99
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))
|
102
|
+
socket
|
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.3.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
|
@@ -398,7 +424,7 @@ 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
429
|
# @option opts [Integer, 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.
|
@@ -470,7 +496,7 @@ module Datadog
|
|
470
496
|
def format_event(title, text, opts=EMPTY_OPTIONS)
|
471
497
|
escaped_title = escape_event_content(title)
|
472
498
|
escaped_text = escape_event_content(text)
|
473
|
-
event_string_data = "_e{#{escaped_title.
|
499
|
+
event_string_data = "_e{#{escaped_title.bytesize},#{escaped_text.bytesize}}:#{escaped_title}|#{escaped_text}".dup
|
474
500
|
|
475
501
|
# We construct the string to be sent by adding '|key:value' parts to it when needed
|
476
502
|
# All pipes ('|') in the metadata are removed. Title and Text can keep theirs
|
@@ -486,12 +512,13 @@ module Datadog
|
|
486
512
|
event_string_data << "|##{tags_string}"
|
487
513
|
end
|
488
514
|
|
489
|
-
raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.
|
515
|
+
raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.bytesize > MAX_EVENT_SIZE
|
490
516
|
event_string_data
|
491
517
|
end
|
492
518
|
|
493
519
|
def tags_as_string(opts)
|
494
520
|
if tag_arr = opts[:tags]
|
521
|
+
tag_arr = tag_hash_to_array(tag_arr) if tag_arr.is_a? Hash
|
495
522
|
tag_arr = tag_arr.map { |tag| escape_tag_content(tag) }
|
496
523
|
tag_arr = tags + tag_arr # @tags are normalized when set, so not need to normalize them again
|
497
524
|
else
|
@@ -500,6 +527,10 @@ module Datadog
|
|
500
527
|
tag_arr.join(COMMA) unless tag_arr.empty?
|
501
528
|
end
|
502
529
|
|
530
|
+
def tag_hash_to_array(tag_hash)
|
531
|
+
tag_hash.to_a.map {|pair| pair.compact.join(":")}
|
532
|
+
end
|
533
|
+
|
503
534
|
def escape_event_content(msg)
|
504
535
|
msg.gsub NEW_LINE, ESC_NEW_LINE
|
505
536
|
end
|
@@ -519,8 +550,8 @@ module Datadog
|
|
519
550
|
end
|
520
551
|
|
521
552
|
def send_stats(stat, delta, type, opts=EMPTY_OPTIONS)
|
522
|
-
sample_rate = opts[:sample_rate] || 1
|
523
|
-
if sample_rate == 1 or rand
|
553
|
+
sample_rate = opts[:sample_rate] || @sample_rate || 1
|
554
|
+
if sample_rate == 1 or rand <= sample_rate
|
524
555
|
full_stat = ''.dup
|
525
556
|
full_stat << @prefix if @prefix
|
526
557
|
|
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.3.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-06-24 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
|