sensu-extensions-graphite 0.0.1 → 0.0.2
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 +10 -1
- data/lib/sensu/extensions/graphite.rb +228 -9
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1d8587d5770be44d412655c81f21444ac88223e
|
4
|
+
data.tar.gz: 7c763e16d03096b7af47314fbf0860a255780bc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2e236edd197147bacca5b22ee83f082597b510e9cc36dc1a2ec735d2110fd0fb191d140917f431c997fe5a8665b8cc5e7ccbc2dbd7a39152165d10b5c892545
|
7
|
+
data.tar.gz: 86cf8ce0812d543243957daefdb65a76b6751a106f3960fa3417b4994e219d9f3d07c5a82dc8d9486081f639c8980ce75f6892e0c6e89efbe13b821605ffda62
|
data/README.md
CHANGED
@@ -1,2 +1,11 @@
|
|
1
|
-
# Sensu::Extensions::
|
1
|
+
# Sensu::Extensions::Template
|
2
2
|
|
3
|
+
Welcome to the Sensu Extensions repository template! In this repository, you will find the files you need to be able to author your own Sensu Extension for Sensu Core (>= 0.26).
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
1. Fork this repository and name the fork after your new extension, e.g. `"sensu-extensions-docker"`
|
8
|
+
|
9
|
+
2. Write your extension (with tests!)
|
10
|
+
|
11
|
+
3. Create a GitHub issue on [sensu-extensions/template](https://github.com/sensu-extensions/template/issues) to request a review of your extension, to determine if it is ready to be moved to the [sensu-extensions GitHub organization](https://github.com/sensu-extensions) to be shared with the Sensu community!
|
@@ -2,19 +2,238 @@ require "sensu/extension"
|
|
2
2
|
|
3
3
|
module Sensu
|
4
4
|
module Extension
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
|
6
|
+
######################################
|
7
|
+
# ExponentialDecayTimer
|
8
|
+
#
|
9
|
+
# Implement an exponential backoff timer for reconnecting to metrics
|
10
|
+
# backends.
|
11
|
+
######################################
|
12
|
+
class ExponentialDecayTimer
|
13
|
+
attr_accessor :reconnect_time
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@reconnect_time = 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_reconnect_time(max_reconnect_time, connection_attempt_count)
|
20
|
+
if @reconnect_time < max_reconnect_time
|
21
|
+
seconds = @reconnect_time + (2**(connection_attempt_count - 1))
|
22
|
+
seconds = seconds * (0.5 * (1.0 + rand))
|
23
|
+
@reconnect_time = if seconds <= max_reconnect_time
|
24
|
+
seconds
|
25
|
+
else
|
26
|
+
max_reconnect_time
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@reconnect_time
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#########################################
|
34
|
+
# Connection Handler
|
35
|
+
#########################################
|
36
|
+
class ConnectionHandler < EM::Connection
|
37
|
+
|
38
|
+
# XXX: These should be runtime configurable.
|
39
|
+
MAX_RECONNECT_ATTEMPTS = 0 # Attempt no reconnects. Drop if it can't in favor for speed.
|
40
|
+
MAX_RECONNECT_TIME = 0 # seconds
|
41
|
+
|
42
|
+
attr_accessor :message_queue, :connection_pool
|
43
|
+
attr_accessor :name, :host, :port, :connected
|
44
|
+
attr_accessor :reconnect_timer
|
45
|
+
|
46
|
+
# ignore :reek:TooManyStatements
|
47
|
+
def post_init
|
48
|
+
@is_closed = false
|
49
|
+
@connection_attempt_count = 0
|
50
|
+
@max_reconnect_time = MAX_RECONNECT_TIME
|
51
|
+
@comm_inactivity_timeout = 0 # disable inactivity timeout
|
52
|
+
@pending_connect_timeout = 30 # seconds
|
53
|
+
@reconnect_timer = ExponentialDecayTimer.new
|
54
|
+
end
|
55
|
+
|
56
|
+
def connection_completed
|
57
|
+
@connected = true
|
58
|
+
end
|
59
|
+
|
60
|
+
def close_connection(*args)
|
61
|
+
@is_closed = true
|
62
|
+
@connected = false
|
63
|
+
super(*args)
|
64
|
+
end
|
65
|
+
|
66
|
+
def comm_inactivity_timeout
|
67
|
+
logger.info("Graphite: Connection to #{@name} timed out.")
|
68
|
+
schedule_reconnect
|
69
|
+
end
|
70
|
+
|
71
|
+
def unbind
|
72
|
+
@connected = false
|
73
|
+
unless @is_closed
|
74
|
+
logger.info('Graphite: Connection closed unintentionally.')
|
75
|
+
schedule_reconnect
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def send_data(*args)
|
80
|
+
super(*args)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Override EM::Connection.receive_data to prevent it from calling
|
84
|
+
# puts and randomly logging non-sense to sensu-server.log
|
85
|
+
def receive_data(data)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Reconnect normally attempts to connect at the end of the tick
|
89
|
+
# Delay the reconnect for some seconds.
|
90
|
+
def reconnect(time)
|
91
|
+
EM.add_timer(time) do
|
92
|
+
logger.info("Graphite: Attempting to reconnect relay channel: #{@name}.")
|
93
|
+
super(@host, @port)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_reconnect_time
|
98
|
+
@reconnect_timer.get_reconnect_time(
|
99
|
+
@max_reconnect_time,
|
100
|
+
@connection_attempt_count
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def schedule_reconnect
|
105
|
+
unless @connected
|
106
|
+
@connection_attempt_count += 1
|
107
|
+
reconnect_time = get_reconnect_time
|
108
|
+
logger.info("Graphite: Scheduling reconnect in #{@reconnect_time} seconds for relay channel: #{@name}.")
|
109
|
+
reconnect(reconnect_time)
|
110
|
+
end
|
111
|
+
reconnect_time
|
112
|
+
end
|
113
|
+
|
114
|
+
def logger
|
115
|
+
Sensu::Logger.get
|
116
|
+
end
|
117
|
+
|
118
|
+
end # ConnectionHandler
|
119
|
+
|
120
|
+
##########################################
|
121
|
+
# EndPoint
|
122
|
+
# An endpoint is a backend metric store. This is a compositional object
|
123
|
+
# to help keep the rest of the code sane.
|
124
|
+
##########################################
|
125
|
+
class Endpoint
|
126
|
+
|
127
|
+
# EM::Connection.send_data batches network connection writes in 16KB
|
128
|
+
# We should start out by having all data in the queue flush in the
|
129
|
+
# space of a single loop tick.
|
130
|
+
MAX_QUEUE_SIZE = 2048
|
131
|
+
|
132
|
+
attr_accessor :connection, :queue
|
133
|
+
|
134
|
+
def initialize(name, host, port)
|
135
|
+
@queue = []
|
136
|
+
@connection = EM.connect(host, port, ConnectionHandler)
|
137
|
+
@connection.name = name
|
138
|
+
@connection.host = host
|
139
|
+
@connection.port = port
|
140
|
+
@connection.message_queue = @queue
|
141
|
+
EventMachine::PeriodicTimer.new(60) do
|
142
|
+
Sensu::Logger.get.info("Graphite: queue size for #{name}: #{queue_length}")
|
8
143
|
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def queue_length
|
147
|
+
@queue
|
148
|
+
.map(&:bytesize)
|
149
|
+
.reduce(:+) || 0
|
150
|
+
end
|
151
|
+
|
152
|
+
def flush_to_net
|
153
|
+
sent = @connection.send_data(@queue.join)
|
154
|
+
@queue = [] if sent > 0
|
155
|
+
end
|
156
|
+
|
157
|
+
def relay_event(data)
|
158
|
+
if @connection.connected
|
159
|
+
@queue << data
|
160
|
+
if queue_length >= MAX_QUEUE_SIZE
|
161
|
+
flush_to_net
|
162
|
+
Sensu::Logger.get.debug('Graphite: successfully flushed to network')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def stop
|
168
|
+
if @connection.connected
|
169
|
+
flush_to_net
|
170
|
+
#@connection.close_connection_after_writing
|
171
|
+
@connection.close_connection # Force connection closing, do not wait.
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
#################################
|
179
|
+
# Graphite Handler
|
180
|
+
#################################
|
181
|
+
class Graphite < Handler
|
182
|
+
|
183
|
+
def initialize
|
184
|
+
super
|
185
|
+
@initialized = false
|
186
|
+
@counter = 0
|
187
|
+
end
|
188
|
+
|
189
|
+
def name
|
190
|
+
"graphite"
|
191
|
+
end
|
192
|
+
|
193
|
+
def description
|
194
|
+
"Extension to get metrics into Graphite"
|
195
|
+
end
|
9
196
|
|
10
|
-
|
11
|
-
|
197
|
+
def post_init
|
198
|
+
@endpoint = Endpoint.new(
|
199
|
+
@settings[:graphite][:name],
|
200
|
+
@settings[:graphite][:host],
|
201
|
+
@settings[:graphite][:port]
|
202
|
+
)
|
203
|
+
@counter = 0
|
204
|
+
end
|
205
|
+
|
206
|
+
def run(event)
|
207
|
+
begin
|
208
|
+
event = Oj.load(event)
|
209
|
+
metrics = event["check"]["output"]
|
210
|
+
rescue => e
|
211
|
+
logger.error("Graphite: Error setting up event object - #{e.backtrace.to_s}")
|
12
212
|
end
|
13
213
|
|
14
|
-
|
15
|
-
|
16
|
-
|
214
|
+
begin
|
215
|
+
if @counter > 2048
|
216
|
+
logger.debug("Graphite: recycling connection")
|
217
|
+
stop
|
218
|
+
post_init
|
219
|
+
end
|
220
|
+
|
221
|
+
logger.debug("Metrics: #{metrics}")
|
222
|
+
@endpoint.relay_event(metrics)
|
223
|
+
@counter += 1
|
224
|
+
rescue => e
|
225
|
+
logger.error("Graphite: Error posting metrics - #{e.backtrace.to_s}")
|
17
226
|
end
|
227
|
+
|
228
|
+
yield "", 0
|
18
229
|
end
|
230
|
+
|
231
|
+
def stop
|
232
|
+
@endpoint.stop
|
233
|
+
end
|
234
|
+
|
235
|
+
end # Graphite
|
236
|
+
#################################
|
237
|
+
|
19
238
|
end
|
20
|
-
end
|
239
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-extensions-graphite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu-Extensions and contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sensu-extension
|
@@ -94,9 +94,9 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description:
|
97
|
+
description: Extension to get metrics into Graphite
|
98
98
|
email:
|
99
|
-
- "<
|
99
|
+
- "<amine.benseddik@gmail.com>"
|
100
100
|
executables: []
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
@@ -105,7 +105,7 @@ files:
|
|
105
105
|
- LICENSE
|
106
106
|
- README.md
|
107
107
|
- lib/sensu/extensions/graphite.rb
|
108
|
-
homepage: https://github.com/
|
108
|
+
homepage: https://github.com/amine7536/sensu-extensions-graphite
|
109
109
|
licenses: []
|
110
110
|
metadata: {}
|
111
111
|
post_install_message:
|
@@ -127,5 +127,5 @@ rubyforge_project:
|
|
127
127
|
rubygems_version: 2.5.1
|
128
128
|
signing_key:
|
129
129
|
specification_version: 4
|
130
|
-
summary:
|
130
|
+
summary: Extension to get metrics into Graphite
|
131
131
|
test_files: []
|