dogstatsd-ruby 4.5.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 +32 -79
- data/lib/datadog/statsd.rb +95 -29
- metadata +9 -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,86 +1,35 @@
|
|
1
|
+
# dogstatsd-ruby
|
1
2
|
|
2
|
-
dogstatsd-ruby
|
3
|
-
==============
|
4
|
-
|
5
|
-
A client for DogStatsD, an extension of the StatsD metric server for Datadog.
|
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).
|
6
4
|
|
7
5
|
[](http://travis-ci.org/DataDog/dogstatsd-ruby)
|
8
6
|
|
9
|
-
|
10
|
-
-----------------
|
11
|
-
|
12
|
-
First install the library:
|
13
|
-
|
14
|
-
gem install dogstatsd-ruby
|
15
|
-
|
16
|
-
Then start instrumenting your code:
|
17
|
-
|
18
|
-
``` ruby
|
19
|
-
# Load the dogstats module.
|
20
|
-
require 'datadog/statsd'
|
21
|
-
|
22
|
-
# Create a stats instance.
|
23
|
-
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
|
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/).
|
28
8
|
|
29
|
-
|
30
|
-
statsd.increment('page.views')
|
31
|
-
statsd.increment('messages.count', by: 2, tags: ['kind:incoming'])
|
9
|
+
## Installation
|
32
10
|
|
33
|
-
|
34
|
-
statsd.gauge('users.online', 123, sample_rate: 0.5)
|
35
|
-
|
36
|
-
# Sample a histogram
|
37
|
-
statsd.histogram('file.upload.size', 1234)
|
38
|
-
|
39
|
-
# Time a block of code
|
40
|
-
statsd.time('page.render') do
|
41
|
-
render_page('home.html')
|
42
|
-
end
|
43
|
-
|
44
|
-
# Send several metrics at the same time
|
45
|
-
# All metrics will be buffered and sent in one packet when the block completes
|
46
|
-
statsd.batch do |s|
|
47
|
-
s.increment('page.views')
|
48
|
-
s.gauge('users.online', 123)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Tag a metric.
|
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})
|
11
|
+
First install the library:
|
56
12
|
|
57
|
-
|
58
|
-
|
59
|
-
s.increment('page.views')
|
60
|
-
end
|
13
|
+
```
|
14
|
+
gem install dogstatsd-ruby
|
61
15
|
```
|
62
16
|
|
63
|
-
|
17
|
+
## Configuration
|
64
18
|
|
65
|
-
|
19
|
+
To instantiate a DogStatsd client:
|
66
20
|
|
67
|
-
```
|
68
|
-
#
|
69
|
-
|
21
|
+
```ruby
|
22
|
+
# Import the library
|
23
|
+
require 'datadog/statsd'
|
70
24
|
|
71
|
-
#
|
72
|
-
statsd.
|
73
|
-
'SO MUCH SNOW',
|
74
|
-
"Started yesterday and it won't stop !!",
|
75
|
-
alert_type: 'error',
|
76
|
-
tags: ['urgent', 'endoftheworld']
|
77
|
-
)
|
25
|
+
# Create a DogStatsD client instance.
|
26
|
+
statsd = Datadog::Statsd.new('localhost', 8125)
|
78
27
|
```
|
79
28
|
|
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).
|
80
30
|
|
31
|
+
### Origin detection over UDP
|
81
32
|
|
82
|
-
Origin detection over UDP
|
83
|
-
-------------
|
84
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.
|
85
34
|
|
86
35
|
To enable origin detection over UDP, add the following lines to your application manifest
|
@@ -93,27 +42,31 @@ env:
|
|
93
42
|
```
|
94
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.
|
95
44
|
|
45
|
+
## Usage
|
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).
|
96
48
|
|
97
|
-
|
98
|
-
-------------
|
49
|
+
### Metrics
|
99
50
|
|
100
|
-
|
101
|
-
[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:
|
102
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)
|
103
58
|
|
104
|
-
|
105
|
-
--------
|
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).
|
106
60
|
|
107
|
-
|
108
|
-
[here](http://github.com/DataDog/dogstatsd-ruby/issues/).
|
61
|
+
### Events
|
109
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.
|
110
64
|
|
111
|
-
|
112
|
-
----------------------------
|
65
|
+
### Service Checks
|
113
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.
|
114
68
|
|
115
|
-
Credits
|
116
|
-
-------
|
69
|
+
## Credits
|
117
70
|
|
118
71
|
dogstatsd-ruby is forked from Rien Henrichs [original Statsd
|
119
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,6 +83,10 @@ module Datadog
|
|
33
83
|
# DogStatsd unix socket path. Not used by default.
|
34
84
|
attr_reader :socket_path
|
35
85
|
|
86
|
+
def initialize(telemetry)
|
87
|
+
@telemetry = telemetry
|
88
|
+
end
|
89
|
+
|
36
90
|
# Close the underlying socket
|
37
91
|
def close
|
38
92
|
@socket && @socket.close
|
@@ -40,7 +94,12 @@ module Datadog
|
|
40
94
|
|
41
95
|
def write(message)
|
42
96
|
@logger.debug { "Statsd: #{message}" } if @logger
|
43
|
-
|
97
|
+
payload = message + @telemetry.flush()
|
98
|
+
send_message(payload)
|
99
|
+
|
100
|
+
@telemetry.reset
|
101
|
+
@telemetry.bytes_sent += payload.length
|
102
|
+
@telemetry.packets_sent += 1
|
44
103
|
rescue StandardError => boom
|
45
104
|
# Try once to reconnect if the socket has been closed
|
46
105
|
retries ||= 1
|
@@ -57,6 +116,8 @@ module Datadog
|
|
57
116
|
end
|
58
117
|
end
|
59
118
|
|
119
|
+
@telemetry.bytes_dropped += payload.length
|
120
|
+
@telemetry.packets_dropped += 1
|
60
121
|
@logger.error { "Statsd: #{boom.class} #{boom}" } if @logger
|
61
122
|
nil
|
62
123
|
end
|
@@ -69,7 +130,8 @@ module Datadog
|
|
69
130
|
end
|
70
131
|
|
71
132
|
class UDPConnection < Connection
|
72
|
-
def initialize(host, port, logger)
|
133
|
+
def initialize(host, port, logger, telemetry)
|
134
|
+
super(telemetry)
|
73
135
|
@host = host || ENV.fetch('DD_AGENT_HOST', nil) || DEFAULT_HOST
|
74
136
|
@port = port || ENV.fetch('DD_DOGSTATSD_PORT', nil) || DEFAULT_PORT
|
75
137
|
@logger = logger
|
@@ -91,7 +153,8 @@ module Datadog
|
|
91
153
|
class UDSConnection < Connection
|
92
154
|
class BadSocketError < StandardError; end
|
93
155
|
|
94
|
-
def initialize(socket_path, logger)
|
156
|
+
def initialize(socket_path, logger, telemetry)
|
157
|
+
super(telemetry)
|
95
158
|
@socket_path = socket_path
|
96
159
|
@logger = logger
|
97
160
|
end
|
@@ -186,7 +249,8 @@ module Datadog
|
|
186
249
|
CRITICAL = 2
|
187
250
|
UNKNOWN = 3
|
188
251
|
|
189
|
-
|
252
|
+
DEFAULT_BUFFER_SIZE = 8 * 1_024
|
253
|
+
MAX_EVENT_SIZE = 8 * 1_024
|
190
254
|
|
191
255
|
COUNTER_TYPE = 'c'.freeze
|
192
256
|
GAUGE_TYPE = 'g'.freeze
|
@@ -194,7 +258,7 @@ module Datadog
|
|
194
258
|
DISTRIBUTION_TYPE = 'd'.freeze
|
195
259
|
TIMING_TYPE = 'ms'.freeze
|
196
260
|
SET_TYPE = 's'.freeze
|
197
|
-
VERSION = "4.
|
261
|
+
VERSION = "4.6.0".freeze
|
198
262
|
|
199
263
|
# A namespace to prepend to all statsd calls. Defaults to no namespace.
|
200
264
|
attr_reader :namespace
|
@@ -227,23 +291,12 @@ module Datadog
|
|
227
291
|
port = nil,
|
228
292
|
namespace: nil,
|
229
293
|
tags: nil,
|
230
|
-
max_buffer_bytes:
|
294
|
+
max_buffer_bytes: DEFAULT_BUFFER_SIZE,
|
231
295
|
socket_path: nil,
|
232
296
|
logger: nil,
|
233
|
-
sample_rate: nil
|
297
|
+
sample_rate: nil,
|
298
|
+
disable_telemetry: false
|
234
299
|
)
|
235
|
-
if socket_path.nil?
|
236
|
-
@connection = UDPConnection.new(host, port, logger)
|
237
|
-
else
|
238
|
-
@connection = UDSConnection.new(socket_path, logger)
|
239
|
-
end
|
240
|
-
@logger = logger
|
241
|
-
|
242
|
-
@namespace = namespace
|
243
|
-
@prefix = @namespace ? "#{@namespace}.".freeze : nil
|
244
|
-
|
245
|
-
@sample_rate = sample_rate
|
246
|
-
|
247
300
|
unless tags.nil? or tags.is_a? Array or tags.is_a? Hash
|
248
301
|
raise ArgumentError, 'tags must be a Array<String> or a Hash'
|
249
302
|
end
|
@@ -254,7 +307,25 @@ module Datadog
|
|
254
307
|
# append the entity id to tags if DD_ENTITY_ID env var is not nil
|
255
308
|
@tags << 'dd.internal.entity_id:' + escape_tag_content(ENV.fetch('DD_ENTITY_ID', nil)) unless ENV.fetch('DD_ENTITY_ID', nil).nil?
|
256
309
|
|
257
|
-
|
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
|
320
|
+
@logger = logger
|
321
|
+
|
322
|
+
@namespace = namespace
|
323
|
+
@prefix = @namespace ? "#{@namespace}.".freeze : nil
|
324
|
+
|
325
|
+
@sample_rate = sample_rate
|
326
|
+
|
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))
|
258
329
|
end
|
259
330
|
|
260
331
|
# yield a new instance to a block and close it when done
|
@@ -338,9 +409,6 @@ module Datadog
|
|
338
409
|
end
|
339
410
|
|
340
411
|
# Sends a value to be tracked as a distribution to the statsd server.
|
341
|
-
# Note: Distributions are a beta feature of Datadog and not generally
|
342
|
-
# available. Distributions must be specifically enabled for your
|
343
|
-
# organization.
|
344
412
|
#
|
345
413
|
# @param [String] stat stat name.
|
346
414
|
# @param [Numeric] value distribution value.
|
@@ -416,6 +484,7 @@ module Datadog
|
|
416
484
|
# @example Report a critical service check status
|
417
485
|
# $statsd.service_check('my.service.check', Statsd::CRITICAL, :tags=>['urgent'])
|
418
486
|
def service_check(name, status, opts=EMPTY_OPTIONS)
|
487
|
+
@telemetry.service_checks += 1
|
419
488
|
send_stat format_service_check(name, status, opts)
|
420
489
|
end
|
421
490
|
|
@@ -438,6 +507,7 @@ module Datadog
|
|
438
507
|
# @example Report an awful event:
|
439
508
|
# $statsd.event('Something terrible happened', 'The end is near if we do nothing', :alert_type=>'warning', :tags=>['end_of_times','urgent'])
|
440
509
|
def event(title, text, opts=EMPTY_OPTIONS)
|
510
|
+
@telemetry.events += 1
|
441
511
|
send_stat format_event(title, text, opts)
|
442
512
|
end
|
443
513
|
|
@@ -563,6 +633,7 @@ module Datadog
|
|
563
633
|
end
|
564
634
|
|
565
635
|
def send_stats(stat, delta, type, opts=EMPTY_OPTIONS)
|
636
|
+
@telemetry.metrics += 1
|
566
637
|
sample_rate = opts[:sample_rate] || @sample_rate || 1
|
567
638
|
if sample_rate == 1 or rand <= sample_rate
|
568
639
|
full_stat = ''.dup
|
@@ -590,17 +661,12 @@ module Datadog
|
|
590
661
|
full_stat << '#'.freeze
|
591
662
|
full_stat << tags_string
|
592
663
|
end
|
593
|
-
|
594
664
|
send_stat(full_stat)
|
595
665
|
end
|
596
666
|
end
|
597
667
|
|
598
668
|
def send_stat(message)
|
599
|
-
|
600
|
-
@batch.add message
|
601
|
-
else
|
602
|
-
@connection.write(message)
|
603
|
-
end
|
669
|
+
@batch.open? ? @batch.add(message) : @connection.write(message)
|
604
670
|
end
|
605
671
|
end
|
606
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:
|
@@ -41,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
41
45
|
version: '0'
|
42
46
|
requirements: []
|
43
47
|
rubyforge_project:
|
44
|
-
rubygems_version: 2.7.
|
48
|
+
rubygems_version: 2.7.10
|
45
49
|
signing_key:
|
46
50
|
specification_version: 4
|
47
51
|
summary: A Ruby DogStatsd client
|