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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20e5033101eebbf77f983701353d0c687c986ac1
4
- data.tar.gz: 8613bc14341c7f02a97a4ecbd2e19c7b23659709
3
+ metadata.gz: d1d8587d5770be44d412655c81f21444ac88223e
4
+ data.tar.gz: 7c763e16d03096b7af47314fbf0860a255780bc7
5
5
  SHA512:
6
- metadata.gz: eaae41d8d0a45a4127e7e71a7eb241330e59438446420bb3ed9cde1498e2765a02031b214f78497e6158e590df8c22e235d0545c8e4459bde90bb6ff49bf3195
7
- data.tar.gz: 660a6799d4ea65dd9de23eb1575f2817c4b990ccf5b1136afb5de4b770cee4631f6e0f8d0da7aa8ef5523cb868d26fef8cb9efe0c2e4f600abac1b4d2bc442bc
6
+ metadata.gz: d2e236edd197147bacca5b22ee83f082597b510e9cc36dc1a2ec735d2110fd0fb191d140917f431c997fe5a8665b8cc5e7ccbc2dbd7a39152165d10b5c892545
7
+ data.tar.gz: 86cf8ce0812d543243957daefdb65a76b6751a106f3960fa3417b4994e219d9f3d07c5a82dc8d9486081f639c8980ce75f6892e0c6e89efbe13b821605ffda62
data/README.md CHANGED
@@ -1,2 +1,11 @@
1
- # Sensu::Extensions::Graphite
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
- class Template < Handler
6
- def name
7
- "graphite"
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
- def description
11
- "extension graphite"
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
- def run(event)
15
- logger.info("Hello Graphite")
16
- yield "template", 0
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.1
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-06-01 00:00:00.000000000 Z
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: EXTENSION_TYPE extension to do X
97
+ description: Extension to get metrics into Graphite
98
98
  email:
99
- - "<sensu-users@googlegroups.com>"
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/sensu-extensions/sensu-extensions-graphite
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: EXTENSION_TYPE extension to do X
130
+ summary: Extension to get metrics into Graphite
131
131
  test_files: []