sensu-plugins-cassandra 0.0.1.alpha.1
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -0
- data/CHANGELOG.md +6 -0
- data/LICENSE +22 -0
- data/README.md +54 -0
- data/bin/check-cassandra-schema.rb +83 -0
- data/bin/metrics-cassandra-graphite.rb +381 -0
- data/lib/sensu-plugins-cassandra.rb +7 -0
- metadata +229 -0
- metadata.gz.sig +1 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 01590d99080dbd40e971b6bbb0a104524f6dac23
|
4
|
+
data.tar.gz: ac8608508b57ddc7d48b183d28a83c6bbc420a04
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 569331519e50b498b36ae08c5328c2d8cd070162af8de58c547cc8959762dac6aeffe298988a5d167eb8c5f38d5f9a7579347703a3b415dfac1c5bd9002f6439
|
7
|
+
data.tar.gz: 0083a833323afa9b8d04f656fc95816977a6d54f094ebd0e3e735082980174fc36d91b034c7d1718a46564c4c479e2beda60f8166cc30c5474a372a7de532395
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
���C�L�,����X�Uj�6���Ft��1��b�ِ�c�DA��-o�7�)�L#�>R� �4V��wv>�����Z�^r݂�.����4��gU��R_��:_�K^�@�d_k/E/D܊us�ʎ�<Fm�6�o����$Y�1i�6��d��O���z¬|�2�X�z)�K��v
|
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 devops@yieldbot.com
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
## sensu-plugins-cassandra
|
2
|
+
|
3
|
+
[](https://travis-ci.org/sensu-plugins/sensu-plugins-cassandra)
|
4
|
+
[](http://badge.fury.io/rb/sensu-plugins-cassandra)
|
5
|
+
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-cassandra)
|
6
|
+
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-cassandra)
|
7
|
+
[](https://gemnasium.com/sensu-plugins/sensu-plugins-cassandra)
|
8
|
+
|
9
|
+
## Functionality
|
10
|
+
|
11
|
+
## Files
|
12
|
+
* bin/check-cassandra-schema
|
13
|
+
* bin/metrics-cassandra-graphite
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add the public key (if you haven’t already) as a trusted certificate
|
20
|
+
|
21
|
+
```
|
22
|
+
gem cert --add <(curl -Ls https://raw.githubusercontent.com/sensu-plugins/sensu-plugins.github.io/master/certs/sensu-plugins.pem)
|
23
|
+
gem install sensu-plugins-cassandra -P MediumSecurity
|
24
|
+
```
|
25
|
+
|
26
|
+
You can also download the key from /certs/ within each repository.
|
27
|
+
|
28
|
+
#### Rubygems
|
29
|
+
|
30
|
+
`gem install sensu-plugins-cassandra`
|
31
|
+
|
32
|
+
#### Bundler
|
33
|
+
|
34
|
+
Add *sensu-plugins-cassandra* to your Gemfile and run `bundle install` or `bundle update`
|
35
|
+
|
36
|
+
#### Chef
|
37
|
+
|
38
|
+
Using the Sensu **sensu_gem** LWRP
|
39
|
+
```
|
40
|
+
sensu_gem 'sensu-plugins-cassandra' do
|
41
|
+
options('--prerelease')
|
42
|
+
version '0.0.1'
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Using the Chef **gem_package** resource
|
47
|
+
```
|
48
|
+
gem_package 'sensu-plugins-cassandra' do
|
49
|
+
options('--prerelease')
|
50
|
+
version '0.0.1'
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
## Notes
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# check-cassandra-schema
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin uses Apache Cassandra's `nodetool` to check to see
|
7
|
+
# if any node in the cluster has run into a schema disagreement problem
|
8
|
+
#
|
9
|
+
# OUTPUT:
|
10
|
+
# plain text
|
11
|
+
#
|
12
|
+
# PLATFORMS:
|
13
|
+
# Linux
|
14
|
+
#
|
15
|
+
# DEPENDENCIES:
|
16
|
+
# gem: sensu-plugin
|
17
|
+
# Cassandra's nodetool
|
18
|
+
#
|
19
|
+
# USAGE:
|
20
|
+
# #YELLOW
|
21
|
+
#
|
22
|
+
# NOTES:
|
23
|
+
# See http://www.datastax.com/documentation/cassandra/2.0/cassandra/dml/dml_handle_schema_disagree_t.html
|
24
|
+
# for more details
|
25
|
+
#
|
26
|
+
# LICENSE:
|
27
|
+
# Copyright 2014 Sonian, Inc. and contributors. <support@sensuapp.org>
|
28
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
29
|
+
# for details.
|
30
|
+
#
|
31
|
+
|
32
|
+
require 'sensu-plugin/check/cli'
|
33
|
+
require 'English'
|
34
|
+
|
35
|
+
#
|
36
|
+
# Check Cassandra Schema
|
37
|
+
#
|
38
|
+
class CheckCassandraSchema < Sensu::Plugin::Check::CLI
|
39
|
+
option :hostname,
|
40
|
+
short: '-h HOSTNAME',
|
41
|
+
long: '--host HOSTNAME',
|
42
|
+
description: 'cassandra hostname',
|
43
|
+
default: 'localhost'
|
44
|
+
|
45
|
+
option :port,
|
46
|
+
short: '-P PORT',
|
47
|
+
long: '--port PORT',
|
48
|
+
description: 'cassandra JMX port',
|
49
|
+
default: '7199'
|
50
|
+
|
51
|
+
# execute cassandra's nodetool and return output as string
|
52
|
+
def nodetool_cmd(cmd)
|
53
|
+
out = `nodetool -h #{config[:hostname]} -p #{config[:port]} #{cmd} 2>&1`
|
54
|
+
[out, $CHILD_STATUS]
|
55
|
+
end
|
56
|
+
|
57
|
+
def run # rubocop:disable all
|
58
|
+
out, rc = nodetool_cmd('describecluster')
|
59
|
+
if rc != 0
|
60
|
+
critical(out)
|
61
|
+
end
|
62
|
+
|
63
|
+
bad_nodes = []
|
64
|
+
# #YELLOW
|
65
|
+
out.each_line do |line| # rubocop:disable Style/Next
|
66
|
+
if m = line.match(/\s+UNREACHABLE:\s+(.*)\[(.*)\]\s+$/)# rubocop:disable all
|
67
|
+
bad_nodes << m[2]
|
68
|
+
next
|
69
|
+
end
|
70
|
+
if bad_nodes.count > 0
|
71
|
+
if m = line.match(/\s+(.*)\[(.*)\]\s+$/)# rubocop:disable all
|
72
|
+
bad_nodes << m[2]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if bad_nodes.count > 0
|
78
|
+
critical('nodes ' + bad_nodes.join(', ') + ' are in schema disagreement')
|
79
|
+
else
|
80
|
+
ok
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,381 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# cassandra-graphite
|
4
|
+
#
|
5
|
+
# DESCRIPTION:
|
6
|
+
# This plugin uses Apache Cassandra's `nodetool` to collect metrics
|
7
|
+
# from an instance of Cassandra. Default is localhost and port 7199.
|
8
|
+
# Use 8080 for Cassandra < 0.8.
|
9
|
+
#
|
10
|
+
# By default, only 'info' and 'tpstats' metrics will be output, but
|
11
|
+
# can be disabled with `--no-info` or `--no-tpstats`.
|
12
|
+
#
|
13
|
+
# Use `--cfstats` to get detailed metrics on keyspaces and column
|
14
|
+
# families.
|
15
|
+
#
|
16
|
+
# Only column-families matching a regex will be output if the
|
17
|
+
# `--filter REGEX` flag is used.
|
18
|
+
#
|
19
|
+
# OUTPUT:
|
20
|
+
# metric data
|
21
|
+
#
|
22
|
+
# PLATFORMS:
|
23
|
+
# Linux
|
24
|
+
#
|
25
|
+
# DEPENDENCIES:
|
26
|
+
# gem: sensu-plugin
|
27
|
+
# Cassandra's nodetool
|
28
|
+
#
|
29
|
+
# USAGE:
|
30
|
+
# # info and tpstats
|
31
|
+
# ----------------
|
32
|
+
#
|
33
|
+
# $ ./cassandra-metrics.rb
|
34
|
+
#
|
35
|
+
# host.cassandra.load 75696701.44 1344547246
|
36
|
+
# host.cassandra.uptime 580640 1344547246
|
37
|
+
# host.cassandra.heap.used 88332042.24 1344547246
|
38
|
+
# host.cassandra.heap.total 408944640.0 1344547246
|
39
|
+
# host.cassandra.exceptions 0 1344547246
|
40
|
+
# host.cassandra.threadpool.ReadStage.active 0 1344547246
|
41
|
+
# host.cassandra.threadpool.ReadStage.pending 0 1344547246
|
42
|
+
# ...
|
43
|
+
#
|
44
|
+
# All metrics, including keyspaces and column families
|
45
|
+
# ----------------------------------------------------
|
46
|
+
#
|
47
|
+
# $ ./cassandra-metrics.rb --cfstats
|
48
|
+
#
|
49
|
+
# Show metrics for column-families matching '.*user.*' regex
|
50
|
+
# ----------------------------------------------------------
|
51
|
+
#
|
52
|
+
# $ ./cassandra-metrics.rb --cfstats --filter .*user.*
|
53
|
+
#
|
54
|
+
# Show keyspace metrics, but not column family metrics
|
55
|
+
# ----------------------------------------------------
|
56
|
+
#
|
57
|
+
# $ ./cassandra-metrics.rb --cfstats NOTHING_SHOULD_MATCH_THIS_REGEX
|
58
|
+
#
|
59
|
+
# NOTES:
|
60
|
+
# Heavily inspired by Datadog's python plugin:
|
61
|
+
# https://github.com/miketheman/dd-agent/blob/master/checks/cassandra.py
|
62
|
+
#
|
63
|
+
# LICENSE:
|
64
|
+
# Copyright 2012 Joe Miller https://github.com/joemiller
|
65
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
66
|
+
# for details.
|
67
|
+
#
|
68
|
+
|
69
|
+
require 'sensu-plugin/metric/cli'
|
70
|
+
require 'socket'
|
71
|
+
|
72
|
+
UNITS_FACTOR = {
|
73
|
+
'bytes' => 1,
|
74
|
+
'KB' => 1024,
|
75
|
+
'MB' => 1024**2,
|
76
|
+
'GB' => 1024**3,
|
77
|
+
'TB' => 1024**4
|
78
|
+
}
|
79
|
+
|
80
|
+
#
|
81
|
+
# Cassandra Metrics
|
82
|
+
#
|
83
|
+
class CassandraMetrics < Sensu::Plugin::Metric::CLI::Graphite
|
84
|
+
option :hostname,
|
85
|
+
short: '-h HOSTNAME',
|
86
|
+
long: '--host HOSTNAME',
|
87
|
+
description: 'cassandra hostname',
|
88
|
+
default: 'localhost'
|
89
|
+
|
90
|
+
option :port,
|
91
|
+
short: '-P PORT',
|
92
|
+
long: '--port PORT',
|
93
|
+
description: 'cassandra JMX port',
|
94
|
+
default: '7199'
|
95
|
+
|
96
|
+
option :scheme,
|
97
|
+
description: 'Metric naming scheme, text to prepend to metric',
|
98
|
+
short: '-s SCHEME',
|
99
|
+
long: '--scheme SCHEME',
|
100
|
+
default: "#{Socket.gethostname}.cassandra"
|
101
|
+
|
102
|
+
option :filter_regex,
|
103
|
+
description: 'regular expression for filtering column families (use with --cfstats)',
|
104
|
+
on: :tail,
|
105
|
+
short: '-f REGEX',
|
106
|
+
long: '--filter REGEX'
|
107
|
+
|
108
|
+
option :info,
|
109
|
+
description: 'output high-level Cassandra "info" metrics (default: yes)',
|
110
|
+
on: :tail,
|
111
|
+
short: '-i',
|
112
|
+
long: '--[no-]info',
|
113
|
+
boolean: true,
|
114
|
+
default: true
|
115
|
+
|
116
|
+
option :compactionstats,
|
117
|
+
description: 'output Cassandra "compactionstats" metrics (default: yes)',
|
118
|
+
on: :tail,
|
119
|
+
short: '-o',
|
120
|
+
long: '--[no-]compactionstats',
|
121
|
+
boolean: true,
|
122
|
+
default: true
|
123
|
+
|
124
|
+
option :tpstats,
|
125
|
+
description: 'output Cassandra threadPool metrics (default: yes)',
|
126
|
+
on: :tail,
|
127
|
+
short: '-t',
|
128
|
+
long: '--[no-]tpstats',
|
129
|
+
boolean: true,
|
130
|
+
default: true
|
131
|
+
|
132
|
+
option :cfstats,
|
133
|
+
description: 'output metrics on keyspaces and column families (default: no)',
|
134
|
+
on: :tail,
|
135
|
+
short: '-c',
|
136
|
+
long: '--[no-]cfstats',
|
137
|
+
boolean: true,
|
138
|
+
default: false
|
139
|
+
|
140
|
+
# convert_to_bytes(512, 'KB') => 524288
|
141
|
+
# convert_to_bytes(1, 'MB') => 1048576
|
142
|
+
def convert_to_bytes(size, unit)
|
143
|
+
size.to_f * UNITS_FACTOR[unit]
|
144
|
+
end
|
145
|
+
|
146
|
+
# execute cassandra's nodetool and return output as string
|
147
|
+
def nodetool_cmd(cmd)
|
148
|
+
`nodetool -h #{config[:hostname]} -p #{config[:port]} #{cmd}`
|
149
|
+
end
|
150
|
+
|
151
|
+
# nodetool -h localhost info:
|
152
|
+
# v 0.7
|
153
|
+
#
|
154
|
+
# 36299342986353445520010708318471778930
|
155
|
+
# Load : 457.02 KB
|
156
|
+
# Generation No : 1295816448
|
157
|
+
# Uptime (seconds) : 95
|
158
|
+
# Heap Memory (MB) : 521.86 / 1019.88
|
159
|
+
#
|
160
|
+
# v 0.8
|
161
|
+
# Token : 51022655878160265769426795515063697984
|
162
|
+
# Gossip active : True
|
163
|
+
# Load : 283.87 GB
|
164
|
+
# Generation No : 1331653944
|
165
|
+
# Uptime (seconds) : 188319
|
166
|
+
# Heap Memory (MB) : 2527.04 / 3830.00
|
167
|
+
# Data Center : 283
|
168
|
+
# Rack : 76
|
169
|
+
# Exceptions : 0
|
170
|
+
#
|
171
|
+
# v 1.1
|
172
|
+
# Token : 141784319550391026443072753096570088106
|
173
|
+
# Gossip active : true
|
174
|
+
# Thrift active : true
|
175
|
+
# Load : 821.59 GB
|
176
|
+
# Generation No : 1345535280
|
177
|
+
# Uptime (seconds) : 34269
|
178
|
+
# Heap Memory (MB) : 2382.02 / 3032.00
|
179
|
+
# Data Center : datacenter1
|
180
|
+
# Rack : rack1
|
181
|
+
# Exceptions : 0
|
182
|
+
# Key Cache : size 28141776 (bytes), capacity 104857584 (bytes), 9489268 hits, 9676043 requests, 0.987 recent hit rate, 14400 save period in seconds
|
183
|
+
# Row Cache : size 7947581 (bytes), capacity 1048576000 (bytes), 84005 hits, 104727 requests, 0.701 recent hit rate, 0 save period in seconds
|
184
|
+
#
|
185
|
+
# According to io/util/FileUtils.java units for load are:
|
186
|
+
# TB/GB/MB/KB/bytes
|
187
|
+
#
|
188
|
+
def parse_info# rubocop:disable all
|
189
|
+
info = nodetool_cmd('info')
|
190
|
+
# #YELLOW
|
191
|
+
info.each_line do |line| # rubocop:disable Style/Next
|
192
|
+
if m = line.match(/^Exceptions\s*:\s+([0-9]+)$/)# rubocop:disable all
|
193
|
+
output "#{config[:scheme]}.exceptions", m[1], @timestamp
|
194
|
+
end
|
195
|
+
|
196
|
+
if m = line.match(/^Load\s*:\s+([0-9.]+)\s+([KMGT]B|bytes)$/)# rubocop:disable all
|
197
|
+
output "#{config[:scheme]}.load", convert_to_bytes(m[1], m[2]), @timestamp
|
198
|
+
end
|
199
|
+
|
200
|
+
if m = line.match(/^Uptime[^:]+:\s+(\d+)$/)# rubocop:disable all
|
201
|
+
output "#{config[:scheme]}.uptime", m[1], @timestamp
|
202
|
+
end
|
203
|
+
|
204
|
+
if m = line.match(/^Heap Memory[^:]+:\s+([0-9.]+)\s+\/\s+([0-9.]+)$/)# rubocop:disable all
|
205
|
+
output "#{config[:scheme]}.heap.used", convert_to_bytes(m[1], 'MB'), @timestamp
|
206
|
+
output "#{config[:scheme]}.heap.total", convert_to_bytes(m[2], 'MB'), @timestamp
|
207
|
+
end
|
208
|
+
|
209
|
+
# v1.1+
|
210
|
+
if m = line.match(/^Key Cache[^:]+: size ([0-9]+) \(bytes\), capacity ([0-9]+) \(bytes\), ([0-9]+) hits, ([0-9]+) requests/)# rubocop:disable all
|
211
|
+
output "#{config[:scheme]}.key_cache.size", m[1], @timestamp
|
212
|
+
output "#{config[:scheme]}.key_cache.capacity", m[2], @timestamp
|
213
|
+
output "#{config[:scheme]}.key_cache.hits", m[3], @timestamp
|
214
|
+
output "#{config[:scheme]}.key_cache.requests", m[4], @timestamp
|
215
|
+
end
|
216
|
+
|
217
|
+
if m = line.match(/^Row Cache[^:]+: size ([0-9]+) \(bytes\), capacity ([0-9]+) \(bytes\), ([0-9]+) hits, ([0-9]+) requests/)# rubocop:disable all
|
218
|
+
output "#{config[:scheme]}.row_cache.size", m[1], @timestamp
|
219
|
+
output "#{config[:scheme]}.row_cache.capacity", m[2], @timestamp
|
220
|
+
output "#{config[:scheme]}.row_cache.hits", m[3], @timestamp
|
221
|
+
output "#{config[:scheme]}.row_cache.requests", m[4], @timestamp
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# nodetool -h localhost tpstats:
|
227
|
+
# Pool Name Active Pending Completed Blocked All time blocked
|
228
|
+
# ReadStage 0 0 282971 0 0
|
229
|
+
# RequestResponseStage 0 0 32926 0 0
|
230
|
+
# MutationStage 0 0 3216105 0 0
|
231
|
+
# ReadRepairStage 0 0 0 0 0
|
232
|
+
# ReplicateOnWriteStage 0 0 0 0 0
|
233
|
+
# GossipStage 0 0 0 0 0
|
234
|
+
# AntiEntropyStage 0 0 0 0 0
|
235
|
+
# MigrationStage 0 0 188 0 0
|
236
|
+
# MemtablePostFlusher 0 0 110 0 0
|
237
|
+
# StreamStage 0 0 0 0 0
|
238
|
+
# FlushWriter 0 0 110 0 0
|
239
|
+
# MiscStage 0 0 0 0 0
|
240
|
+
# InternalResponseStage 0 0 179 0 0
|
241
|
+
# HintedHandoff 0 0 0 0 0
|
242
|
+
#
|
243
|
+
# Message type Dropped
|
244
|
+
# RANGE_SLICE 0
|
245
|
+
# READ_REPAIR 0
|
246
|
+
# BINARY 0
|
247
|
+
# READ 0
|
248
|
+
# MUTATION 0
|
249
|
+
# REQUEST_RESPONSE 0
|
250
|
+
def parse_tpstats# rubocop:disable all
|
251
|
+
tpstats = nodetool_cmd('tpstats')
|
252
|
+
tpstats.each_line do |line|
|
253
|
+
next if line.match(/^Pool Name/)
|
254
|
+
next if line.match(/^Message type/)
|
255
|
+
|
256
|
+
if m = line.match(/^(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/)# rubocop:disable all
|
257
|
+
(thread, active, pending, completed, blocked, _) = m.captures
|
258
|
+
|
259
|
+
output "#{config[:scheme]}.threadpool.#{thread}.active", active, @timestamp
|
260
|
+
output "#{config[:scheme]}.threadpool.#{thread}.pending", pending, @timestamp
|
261
|
+
output "#{config[:scheme]}.threadpool.#{thread}.completed", completed, @timestamp
|
262
|
+
output "#{config[:scheme]}.threadpool.#{thread}.blocked", blocked, @timestamp
|
263
|
+
end
|
264
|
+
|
265
|
+
if m = line.match(/^(\w+)\s+(\d+)$/)# rubocop:disable all
|
266
|
+
(message_type, dropped) = m.captures
|
267
|
+
output "#{config[:scheme]}.message_type.#{message_type}.dropped", dropped, @timestamp
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# nodetool -h localhost compactionstats
|
273
|
+
# pending tasks: 1
|
274
|
+
# compaction type keyspace column family bytes compacted bytes total progress
|
275
|
+
# ....
|
276
|
+
#
|
277
|
+
# note: we are only capturing the 'pending tasks' stats
|
278
|
+
def parse_compactionstats
|
279
|
+
cstats = nodetool_cmd('compactionstats')
|
280
|
+
cstats.each_line do |line|
|
281
|
+
if m = line.match(/^pending tasks:\s+([0-9]+)/)# rubocop:disable all
|
282
|
+
output "#{config[:scheme]}.compactionstats.pending_tasks", m[1], @timestamp
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
# nodetool -h localhost cfstats
|
288
|
+
# Keyspace: system
|
289
|
+
# Read Count: 216
|
290
|
+
# Read Latency: 1.4066805555555557 ms.
|
291
|
+
# Write Count: 36
|
292
|
+
# Write Latency: 0.32755555555555554 ms.
|
293
|
+
# Pending Tasks: 0
|
294
|
+
# Column Family: NodeIdInfo
|
295
|
+
# SSTable count: 0
|
296
|
+
# Space used (live): 0
|
297
|
+
# Space used (total): 0
|
298
|
+
# Number of Keys (estimate): 0
|
299
|
+
# Memtable Columns Count: 0
|
300
|
+
# Memtable Data Size: 0
|
301
|
+
# Memtable Switch Count: 0
|
302
|
+
# Read Count: 0
|
303
|
+
# Read Latency: NaN ms.
|
304
|
+
# Write Count: 0
|
305
|
+
# Write Latency: NaN ms.
|
306
|
+
# Pending Tasks: 0
|
307
|
+
# Bloom Filter False Postives: 0
|
308
|
+
# Bloom Filter False Ratio: 0.00000
|
309
|
+
# Bloom Filter Space Used: 0
|
310
|
+
# Key cache capacity: 1
|
311
|
+
# Key cache size: 0
|
312
|
+
# Key cache hit rate: NaN
|
313
|
+
# Row cache: disabled
|
314
|
+
# Compacted row minimum size: 0
|
315
|
+
# Compacted row maximum size: 0
|
316
|
+
# Compacted row mean size: 0
|
317
|
+
#
|
318
|
+
# some notes on parsing cfstats output:
|
319
|
+
# - a line preceeded by 1 tab contains keyspace metrics
|
320
|
+
# - a line preceeded by 2 tabs contains column family metrics
|
321
|
+
def parse_cfstats# rubocop:disable all
|
322
|
+
def get_metric(string)
|
323
|
+
string.strip!
|
324
|
+
(metric, value) = string.split(': ')
|
325
|
+
if metric.nil? || value.nil?
|
326
|
+
return [nil, nil]
|
327
|
+
else
|
328
|
+
# sanitize metric names for graphite
|
329
|
+
metric.gsub!(/[^a-zA-Z0-9]/, '_') # convert all other chars to _
|
330
|
+
metric.gsub!(/[_]*$/, '') # remove any _'s at end of the string
|
331
|
+
metric.gsub!(/[_]{2,}/, '_') # convert sequence of multiple _'s to single _
|
332
|
+
metric.downcase!
|
333
|
+
# sanitize metric values for graphite. Numbers only, please.
|
334
|
+
value = value.chomp(' ms.').gsub(/([0-9.]+)$/, '\1')
|
335
|
+
end
|
336
|
+
[metric, value]
|
337
|
+
end
|
338
|
+
|
339
|
+
cfstats = nodetool_cmd('cfstats')
|
340
|
+
|
341
|
+
keyspace = nil
|
342
|
+
cf = nil
|
343
|
+
|
344
|
+
cfstats.each_line do |line|
|
345
|
+
num_indents = line.count("\t")
|
346
|
+
if m = line.match(/^Keyspace:\s+(\w+)$/)# rubocop:disable all
|
347
|
+
keyspace = m[1]
|
348
|
+
elsif m = line.match(/\t\tColumn Family[^:]*:\s+(\w+)$/)# rubocop:disable all
|
349
|
+
cf = m[1]
|
350
|
+
elsif num_indents == 0
|
351
|
+
# keyspace = nil
|
352
|
+
cf = nil
|
353
|
+
elsif num_indents == 2 && !cf.nil?
|
354
|
+
# a column family metric
|
355
|
+
# #YELLOW
|
356
|
+
if config[:filter_regex]
|
357
|
+
unless cf.match(config[:filter_regex]) # rubocop:disable IfUnlessModifier
|
358
|
+
next
|
359
|
+
end
|
360
|
+
end
|
361
|
+
(metric, value) = get_metric(line)
|
362
|
+
output "#{config[:scheme]}.#{keyspace}.#{cf}.#{metric}", value, @timestamp unless value == 'disabled'
|
363
|
+
elsif num_indents == 1 && !keyspace.nil?
|
364
|
+
# a keyspace metric
|
365
|
+
(metric, value) = get_metric(line)
|
366
|
+
output "#{config[:scheme]}.#{keyspace}.#{metric}", value, @timestamp
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def run# rubocop:disable all
|
372
|
+
@timestamp = Time.now.to_i
|
373
|
+
|
374
|
+
parse_info if config[:info]
|
375
|
+
parse_compactionstats if config[:compactionstats]
|
376
|
+
parse_tpstats if config[:tpstats]
|
377
|
+
parse_cfstats if config[:cfstats]
|
378
|
+
|
379
|
+
ok
|
380
|
+
end
|
381
|
+
end
|
metadata
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sensu-plugins-cassandra
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.alpha.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yieldbot, Inc. and contributors
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDgDCCAmigAwIBAgIBATANBgkqhkiG9w0BAQUFADBDMRIwEAYDVQQDDAltYXR0
|
14
|
+
am9uZXMxGDAWBgoJkiaJk/IsZAEZFgh5aWVsZGJvdDETMBEGCgmSJomT8ixkARkW
|
15
|
+
A2NvbTAeFw0xNTAxMjgyMTAyNTFaFw0xNjAxMjgyMTAyNTFaMEMxEjAQBgNVBAMM
|
16
|
+
CW1hdHRqb25lczEYMBYGCgmSJomT8ixkARkWCHlpZWxkYm90MRMwEQYKCZImiZPy
|
17
|
+
LGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyTSzVYnO
|
18
|
+
CLgyrIyT1mBQakArQyW8xhi6MlDqyzXHJGeERT790U6EgoBVeS4XoK0ptFZNR8Tf
|
19
|
+
zko0w+Nv47TarSCgkPOaxY+mxWnAVR10dOmfeLr7huiMyps+YD56/EF2FqQ3jf/+
|
20
|
+
qohENfKD91qy1ieEy+Fn7Pf74ltbNKUdkb9a9eFXQ0DQ4ip5vik7DzjQkUTj4lca
|
21
|
+
k6ArwnmHX4YDhZoYtrQJ8jVktN0/+NtA40M5qkCYHNe5tUW25b/tKVYuioxG6b2Z
|
22
|
+
oIzaZxRLxf6HVAWpCVRT/F5+/yjigkX4u++eYacfLGleXQzoK7BL65vHGMJygWEE
|
23
|
+
0TKGqFOrl/L0AQIDAQABo38wfTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNV
|
24
|
+
HQ4EFgQUEf6a8Td7MrSZc8ImbLFZAENPbz0wIQYDVR0RBBowGIEWbWF0dGpvbmVz
|
25
|
+
QHlpZWxkYm90LmNvbTAhBgNVHRIEGjAYgRZtYXR0am9uZXNAeWllbGRib3QuY29t
|
26
|
+
MA0GCSqGSIb3DQEBBQUAA4IBAQBbzXAYA3BVGw8DZ0YYoY1VHPNEcH5qPIApmHO8
|
27
|
+
rvSmuUT0yMEi7u00H/5uHRFf4LleGT/+sTdyXKsNPGT9kdRuQEgwi+vf7Zfvd8aX
|
28
|
+
UF/+4VkEYf/8rV8Ere6u2QaWPgApdMV6JjKr1fAwCTd8AuGXNaWItiPPMseSQzLJ
|
29
|
+
JKP4hVvbc1d+oS925B1lcBiqn2aYvElbyNAVmQPywNNqkWmvtlqj9ZVJfV5HQLdu
|
30
|
+
8sHuVruarogxxKPBzlL2is4EUb6oN/RdpGx2l4254+nyR+abg//Ed27Ym0PkB4lk
|
31
|
+
HP0m8WSjZmFr109pE/sVsM5jtOCvogyujQOjNVGN4gz1wwPr
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2015-04-09 00:00:00.000000000 Z
|
34
|
+
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: sensu-plugin
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.1.0
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.1.0
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: english
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.6.3
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.6.3
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: codeclimate-test-reporter
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.4'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.4'
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rubocop
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.17.0
|
84
|
+
type: :development
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.17.0
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rspec
|
93
|
+
requirement: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '3.1'
|
98
|
+
type: :development
|
99
|
+
prerelease: false
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '3.1'
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: bundler
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '1.7'
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '1.7'
|
119
|
+
- !ruby/object:Gem::Dependency
|
120
|
+
name: rake
|
121
|
+
requirement: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '10.0'
|
126
|
+
type: :development
|
127
|
+
prerelease: false
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - "~>"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '10.0'
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: github-markup
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '1.3'
|
140
|
+
type: :development
|
141
|
+
prerelease: false
|
142
|
+
version_requirements: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '1.3'
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: redcarpet
|
149
|
+
requirement: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '3.2'
|
154
|
+
type: :development
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - "~>"
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '3.2'
|
161
|
+
- !ruby/object:Gem::Dependency
|
162
|
+
name: yard
|
163
|
+
requirement: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0.8'
|
168
|
+
type: :development
|
169
|
+
prerelease: false
|
170
|
+
version_requirements: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - "~>"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0.8'
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
name: pry
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - "~>"
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0.10'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - "~>"
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0.10'
|
189
|
+
description: Sensu plugins for working with cassandra
|
190
|
+
email: "<sensu-users@googlegroups.com>"
|
191
|
+
executables: []
|
192
|
+
extensions: []
|
193
|
+
extra_rdoc_files: []
|
194
|
+
files:
|
195
|
+
- CHANGELOG.md
|
196
|
+
- LICENSE
|
197
|
+
- README.md
|
198
|
+
- bin/check-cassandra-schema.rb
|
199
|
+
- bin/metrics-cassandra-graphite.rb
|
200
|
+
- lib/sensu-plugins-cassandra.rb
|
201
|
+
homepage: https://github.com/sensu-plugins/sensu-plugins-cassandra
|
202
|
+
licenses:
|
203
|
+
- MIT
|
204
|
+
metadata:
|
205
|
+
maintainer: ''
|
206
|
+
development_status: active
|
207
|
+
production_status: unstable - testing recommended
|
208
|
+
post_install_message:
|
209
|
+
rdoc_options: []
|
210
|
+
require_paths:
|
211
|
+
- lib
|
212
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
213
|
+
requirements:
|
214
|
+
- - ">="
|
215
|
+
- !ruby/object:Gem::Version
|
216
|
+
version: 1.9.3
|
217
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - ">"
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 1.3.1
|
222
|
+
requirements: []
|
223
|
+
rubyforge_project:
|
224
|
+
rubygems_version: 2.2.2
|
225
|
+
signing_key:
|
226
|
+
specification_version: 4
|
227
|
+
summary: Sensu plugins for working with haproxy
|
228
|
+
test_files: []
|
229
|
+
has_rdoc:
|
metadata.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
n��3�9�9�'�5Mߓ럝����*��N4-�f2̓0)�3C'�6�|��3JX�]��\�Z5\��"-��`9�Ӂ�[�/IBy��-�ܱF���y�Zs2�Ӏ�:��9�B,P�n��qJ$����j��ɦ�8L�q��b�Z9n��Q��%m�ɦ}�j�ҝ���yO��]X���A�k�f-�0o���~۴�:�'?x{-O��j��WM��4*�&"�Y?;at��
|