inst_statsd 2.2.0 → 2.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/lib/inst_statsd/event.rb +64 -0
- data/lib/inst_statsd/request_stat.rb +12 -0
- data/lib/inst_statsd/statsd.rb +2 -0
- data/lib/inst_statsd/version.rb +5 -0
- data/lib/inst_statsd.rb +1 -0
- data/spec/inst_statsd/event_spec.rb +159 -0
- data/spec/inst_statsd/request_stat_spec.rb +19 -2
- data/spec/inst_statsd/statsd_spec.rb +4 -0
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3f7337500a808963c072d5a5f752cdb4c1934bfdbb597fb926bbde54b1ee7f
|
4
|
+
data.tar.gz: b6375958a56e88a8a0c1ffb766ae8ec31f517071f8032b8ef4947301aac9cbf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23d76e604d9a734e6d1f8530ddbf169a0b6f8e429bdcfe6c15b474da4a9ce6d23e1bfcaef2657c7d7bbdb15ab8a33dc633a388712fe6e1900a3b52b132bbdab8
|
7
|
+
data.tar.gz: eec92096bc95d50b22cc2f2562d71f4843fa31b00578f34c5c46897a4a83f20666ff3dd47ad5be98c0d014c5ee6f533611047f91d0b6e60969c14b01388387f4
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InstStatsd
|
4
|
+
# Mix-in methods for supporting DataDog events
|
5
|
+
# See https://docs.datadoghq.com/service_management/events/
|
6
|
+
module Event
|
7
|
+
SUPPORTED_TYPES = %i[
|
8
|
+
deploy
|
9
|
+
feature_disabled
|
10
|
+
feature_enabled
|
11
|
+
provision
|
12
|
+
refresh
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
def instance; end
|
16
|
+
def data_dog?; end
|
17
|
+
def dog_tags; end
|
18
|
+
|
19
|
+
# This end point allows you to post events to the DatDog event stream.
|
20
|
+
#
|
21
|
+
# @param [String] title Event title
|
22
|
+
# @param [String] text Event text. Supports newlines (+\n+)
|
23
|
+
# @param [String, nil] :type Can be "deploy", "feature_disabled",
|
24
|
+
# "feature_enabled", "provision", or "refresh"
|
25
|
+
# @param [Hash] :tags tags to be added to event. Note that the
|
26
|
+
# environment, service, and other data are automatically
|
27
|
+
# added as tags for you without specifying them here.
|
28
|
+
# @param [Integer, String, nil] :date_happened (nil) Assign a timestamp
|
29
|
+
# to the event. Default is now when none
|
30
|
+
# @param [String, nil] :priority ('normal') Can be "normal" or "low"
|
31
|
+
# @param [String, nil] :alert_type ('info') Can be "error", "warning", "info" or "success".
|
32
|
+
#
|
33
|
+
# @example Report an event:
|
34
|
+
# InstStatsd::Statsd.event(
|
35
|
+
# "Quiz API Deploy",
|
36
|
+
# "<release> was deployed to Quiz API",
|
37
|
+
# tags: {foo: 'bar'},
|
38
|
+
# type: 'deploy',
|
39
|
+
# alert_type: :success
|
40
|
+
# )
|
41
|
+
def event(title, text, type: nil, tags: {}, alert_type: nil, priority: nil, date_happened: nil)
|
42
|
+
return unless instance && data_dog?
|
43
|
+
|
44
|
+
instance.event(
|
45
|
+
title,
|
46
|
+
text,
|
47
|
+
{
|
48
|
+
alert_type: alert_type,
|
49
|
+
priority: priority,
|
50
|
+
date_happened: date_happened,
|
51
|
+
tags: tags_from_opts(tags, type, dog_tags)
|
52
|
+
}.compact
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def tags_from_opts(tags, type, dd_tags)
|
59
|
+
custom_tags = tags.merge(dd_tags)
|
60
|
+
custom_tags[:type] = type if SUPPORTED_TYPES.include? type
|
61
|
+
custom_tags.compact
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -20,6 +20,7 @@ module InstStatsd
|
|
20
20
|
self.short_stat = "request"
|
21
21
|
self.tags[:controller] = controller if controller
|
22
22
|
self.tags[:action] = action if action
|
23
|
+
self.tags[:status] = status if status
|
23
24
|
else
|
24
25
|
self.common_key = "request.#{controller}.#{action}" if controller && action
|
25
26
|
end
|
@@ -48,6 +49,17 @@ module InstStatsd
|
|
48
49
|
@payload.fetch(:params, {})['action']
|
49
50
|
end
|
50
51
|
|
52
|
+
def status
|
53
|
+
status = @payload.fetch(:status, 0)
|
54
|
+
# Only return status group to reduce the number of indexed custom metrics (and cost) of datadog
|
55
|
+
return '1XX' if status >= 100 and status < 200
|
56
|
+
return '2XX' if status >= 200 and status < 300
|
57
|
+
return '3XX' if status >= 300 and status < 400
|
58
|
+
return '4XX' if status >= 400 and status < 500
|
59
|
+
return '5XX' if status >= 500 and status < 600
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
51
63
|
def total
|
52
64
|
if (!@finish || !@start)
|
53
65
|
return 0
|
data/lib/inst_statsd/statsd.rb
CHANGED
@@ -24,6 +24,8 @@
|
|
24
24
|
|
25
25
|
module InstStatsd
|
26
26
|
module Statsd
|
27
|
+
extend InstStatsd::Event
|
28
|
+
|
27
29
|
# replace "." in key names with another character to avoid creating spurious sub-folders in graphite
|
28
30
|
def self.escape(str, replacement = '_')
|
29
31
|
str.respond_to?(:gsub) ? str.gsub('.', replacement) : str
|
data/lib/inst_statsd.rb
CHANGED
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe InstStatsd::Event do
|
6
|
+
include described_class
|
7
|
+
|
8
|
+
let(:title) { "Title" }
|
9
|
+
let(:text) {"Some text."}
|
10
|
+
|
11
|
+
let(:instance) { double }
|
12
|
+
let(:data_dog?) { true }
|
13
|
+
let(:dog_tags) { {} }
|
14
|
+
let(:opts) { {} }
|
15
|
+
|
16
|
+
describe '#event' do
|
17
|
+
subject { event(title, text, opts) }
|
18
|
+
|
19
|
+
context 'with title and text only' do
|
20
|
+
let(:opts) { {} }
|
21
|
+
|
22
|
+
it 'invokes "event" on the instance with title and text' do
|
23
|
+
expect(instance).to receive(:event).with(
|
24
|
+
title,
|
25
|
+
text,
|
26
|
+
tags: {}
|
27
|
+
)
|
28
|
+
|
29
|
+
subject
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with alert_type set' do
|
34
|
+
let(:opts) { { alert_type: :error } }
|
35
|
+
|
36
|
+
it 'invokes "event" on the instance with expected arguments' do
|
37
|
+
expect(instance).to receive(:event).with(
|
38
|
+
title,
|
39
|
+
text,
|
40
|
+
alert_type: :error,
|
41
|
+
tags: {}
|
42
|
+
)
|
43
|
+
|
44
|
+
subject
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with priority set' do
|
49
|
+
let(:opts) { { priority: :low } }
|
50
|
+
|
51
|
+
it 'invokes "event" on the instance with expected arguments' do
|
52
|
+
expect(instance).to receive(:event).with(
|
53
|
+
title,
|
54
|
+
text,
|
55
|
+
priority: :low,
|
56
|
+
tags: {}
|
57
|
+
)
|
58
|
+
|
59
|
+
subject
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with date_happened set' do
|
64
|
+
let(:opts) { { date_happened: date_happened } }
|
65
|
+
let(:date_happened) { Time.now.to_i }
|
66
|
+
|
67
|
+
it 'invokes "event" on the instance with expected arguments' do
|
68
|
+
expect(instance).to receive(:event).with(
|
69
|
+
title,
|
70
|
+
text,
|
71
|
+
date_happened: date_happened,
|
72
|
+
tags: {}
|
73
|
+
)
|
74
|
+
|
75
|
+
subject
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with an invalid type set' do
|
80
|
+
let(:opts) { { type: :banana } }
|
81
|
+
|
82
|
+
it 'does not sent the invalid aggregation key' do
|
83
|
+
expect(instance).to receive(:event).with(
|
84
|
+
title,
|
85
|
+
text,
|
86
|
+
tags: {}
|
87
|
+
)
|
88
|
+
|
89
|
+
subject
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with a valid type set' do
|
94
|
+
let(:opts) { { type: :deploy } }
|
95
|
+
|
96
|
+
it 'sets the valid aggregation key' do
|
97
|
+
expect(instance).to receive(:event).with(
|
98
|
+
title,
|
99
|
+
text,
|
100
|
+
tags: {type: :deploy}
|
101
|
+
)
|
102
|
+
|
103
|
+
subject
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with custom tags' do
|
108
|
+
let(:opts) { { tags: { project: 'cool-project'} } }
|
109
|
+
|
110
|
+
it 'invokes "event" on the instance with expected arguments' do
|
111
|
+
expect(instance).to receive(:event).with(
|
112
|
+
title,
|
113
|
+
text,
|
114
|
+
tags: { project: 'cool-project' }
|
115
|
+
)
|
116
|
+
|
117
|
+
subject
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'with all opts set' do
|
122
|
+
let(:date_happened) { Time.now.to_i }
|
123
|
+
let(:opts) do
|
124
|
+
{
|
125
|
+
type: :deploy,
|
126
|
+
alert_type: :warning,
|
127
|
+
priority: :low,
|
128
|
+
date_happened: date_happened,
|
129
|
+
tags: { foo: 'bar' }
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'sets all arguments' do
|
134
|
+
expect(instance).to receive(:event).with(
|
135
|
+
title,
|
136
|
+
text,
|
137
|
+
alert_type: :warning,
|
138
|
+
priority: :low,
|
139
|
+
date_happened: date_happened,
|
140
|
+
tags: { foo: 'bar', type: :deploy }
|
141
|
+
)
|
142
|
+
|
143
|
+
subject
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when the instance is not DataDog' do
|
148
|
+
let(:data_dog?) { false }
|
149
|
+
|
150
|
+
it { is_expected.to eq nil }
|
151
|
+
|
152
|
+
it 'does not invoke "event" on the instance' do
|
153
|
+
expect(instance).not_to receive(:event)
|
154
|
+
|
155
|
+
subject
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -70,6 +70,22 @@ describe InstStatsd::RequestStat do
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
describe '#status' do
|
74
|
+
it 'should return nil if status is not defined' do
|
75
|
+
rs = create_subject
|
76
|
+
expect(rs.status).to eq nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return HTTP status group if present' do
|
80
|
+
expect(create_subject({status: 200}).status).to eq '2XX'
|
81
|
+
expect(create_subject({status: 201}).status).to eq '2XX'
|
82
|
+
expect(create_subject({status: 302}).status).to eq '3XX'
|
83
|
+
expect(create_subject({status: 400}).status).to eq '4XX'
|
84
|
+
expect(create_subject({status: 404}).status).to eq '4XX'
|
85
|
+
expect(create_subject({status: 503}).status).to eq '5XX'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
73
89
|
describe '#total' do
|
74
90
|
it 'correctly calculates milliseconds from start, finish' do
|
75
91
|
rs = create_subject({params: {}})
|
@@ -113,10 +129,11 @@ describe InstStatsd::RequestStat do
|
|
113
129
|
params: {
|
114
130
|
'controller' => 'foo',
|
115
131
|
'action' => 'index'
|
116
|
-
}
|
132
|
+
},
|
133
|
+
status: 200
|
117
134
|
}
|
118
135
|
rs = create_subject(payload, statsd)
|
119
|
-
expect(statsd).to receive(:timing).with('request.total', 1000, {short_stat: 'request.total', tags: {action: "index", controller: "foo"}} )
|
136
|
+
expect(statsd).to receive(:timing).with('request.total', 1000, {short_stat: 'request.total', tags: {action: "index", controller: "foo", status: '2XX'}} )
|
120
137
|
rs.report
|
121
138
|
end
|
122
139
|
|
@@ -10,6 +10,10 @@ describe InstStatsd::Statsd do
|
|
10
10
|
InstStatsd::Statsd.reset_instance
|
11
11
|
end
|
12
12
|
|
13
|
+
it 'includes the events module' do
|
14
|
+
expect(described_class).to respond_to :event
|
15
|
+
end
|
16
|
+
|
13
17
|
it 'appends the hostname to stat names by default' do
|
14
18
|
allow(InstStatsd::Statsd).to receive(:hostname).and_return('testhost')
|
15
19
|
statsd = double
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inst_statsd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Cloward
|
8
8
|
- Jason Madsen
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dogstatsd-ruby
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
|
-
description:
|
126
|
+
description:
|
127
127
|
email:
|
128
128
|
- ncloward@instructure.com
|
129
129
|
- jmadsen@instructure.com
|
@@ -136,15 +136,18 @@ files:
|
|
136
136
|
- lib/inst_statsd/block_tracking.rb
|
137
137
|
- lib/inst_statsd/counter.rb
|
138
138
|
- lib/inst_statsd/default_tracking.rb
|
139
|
+
- lib/inst_statsd/event.rb
|
139
140
|
- lib/inst_statsd/null_logger.rb
|
140
141
|
- lib/inst_statsd/request_logger.rb
|
141
142
|
- lib/inst_statsd/request_stat.rb
|
142
143
|
- lib/inst_statsd/request_tracking.rb
|
143
144
|
- lib/inst_statsd/sql_tracker.rb
|
144
145
|
- lib/inst_statsd/statsd.rb
|
146
|
+
- lib/inst_statsd/version.rb
|
145
147
|
- spec/inst_statsd/block_stat_spec.rb
|
146
148
|
- spec/inst_statsd/block_tracking_spec.rb
|
147
149
|
- spec/inst_statsd/counter_spec.rb
|
150
|
+
- spec/inst_statsd/event_spec.rb
|
148
151
|
- spec/inst_statsd/inst_statsd_spec.rb
|
149
152
|
- spec/inst_statsd/null_logger_spec.rb
|
150
153
|
- spec/inst_statsd/request_logger_spec.rb
|
@@ -159,7 +162,7 @@ homepage: https://github.com/instructure/inst_statsd
|
|
159
162
|
licenses:
|
160
163
|
- MIT
|
161
164
|
metadata: {}
|
162
|
-
post_install_message:
|
165
|
+
post_install_message:
|
163
166
|
rdoc_options: []
|
164
167
|
require_paths:
|
165
168
|
- lib
|
@@ -167,21 +170,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
170
|
requirements:
|
168
171
|
- - ">="
|
169
172
|
- !ruby/object:Gem::Version
|
170
|
-
version: '2.
|
173
|
+
version: '2.7'
|
171
174
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
175
|
requirements:
|
173
176
|
- - ">="
|
174
177
|
- !ruby/object:Gem::Version
|
175
178
|
version: '0'
|
176
179
|
requirements: []
|
177
|
-
rubygems_version: 3.2.
|
178
|
-
signing_key:
|
180
|
+
rubygems_version: 3.2.6
|
181
|
+
signing_key:
|
179
182
|
specification_version: 4
|
180
183
|
summary: Statsd for Instructure
|
181
184
|
test_files:
|
182
185
|
- spec/inst_statsd/block_stat_spec.rb
|
183
186
|
- spec/inst_statsd/block_tracking_spec.rb
|
184
187
|
- spec/inst_statsd/counter_spec.rb
|
188
|
+
- spec/inst_statsd/event_spec.rb
|
185
189
|
- spec/inst_statsd/inst_statsd_spec.rb
|
186
190
|
- spec/inst_statsd/null_logger_spec.rb
|
187
191
|
- spec/inst_statsd/request_logger_spec.rb
|