sensu-plugins-kafka 0.7.0 → 0.8.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/CHANGELOG.md +5 -0
- data/bin/check-consumer-lag.rb +58 -66
- data/lib/sensu-plugins-kafka/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 436d7165e1ea6b4ac7efe7ee7c4456619cb0d7bd
|
4
|
+
data.tar.gz: 1b33367a5fb5e418031ab76b3f1f571c660d4e69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0386a39236c73b7b192bd287e1cd00c7a02da9ef8af2e79f26315d49a3dc005e87ddc77f66e19bbc47fb0f96b519963001fa574e496758ef3df92a35ab8825c
|
7
|
+
data.tar.gz: b500208baf3951334ef8a055feb277cb27aa261f7f1ea0b21f4618ba86ba5ad0287abad5b462f00ad61c963c22defb08d7278ab15e2d28c78b2519b21c6e5ea6
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,11 @@ This CHANGELOG follows the format listed at [Keep A Changelog](http://keepachang
|
|
10
10
|
### Fixed
|
11
11
|
### Changed
|
12
12
|
|
13
|
+
## [Unreleased]
|
14
|
+
|
15
|
+
### Breaking Changes
|
16
|
+
- Refactoring check-consumer-lag to remove shell/jvm execution
|
17
|
+
|
13
18
|
## [0.7.0]
|
14
19
|
|
15
20
|
### Added
|
data/bin/check-consumer-lag.rb
CHANGED
@@ -27,6 +27,17 @@
|
|
27
27
|
|
28
28
|
require 'sensu-plugin/check/cli'
|
29
29
|
|
30
|
+
require 'celluloid-io'
|
31
|
+
require 'json'
|
32
|
+
require 'poseidon'
|
33
|
+
require 'zookeeper'
|
34
|
+
|
35
|
+
module Poseidon
|
36
|
+
class Connection
|
37
|
+
TCPSocket = Celluloid::IO::TCPSocket
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
30
41
|
class ConsumerLagCheck < Sensu::Plugin::Check::CLI
|
31
42
|
option :group,
|
32
43
|
description: 'Consumer group',
|
@@ -34,25 +45,6 @@ class ConsumerLagCheck < Sensu::Plugin::Check::CLI
|
|
34
45
|
long: '--group NAME',
|
35
46
|
required: true
|
36
47
|
|
37
|
-
option :kafka_home,
|
38
|
-
description: 'Kafka home',
|
39
|
-
short: '-k NAME',
|
40
|
-
long: '--kafka-home NAME',
|
41
|
-
default: '/opt/kafka'
|
42
|
-
|
43
|
-
option :topic_excludes,
|
44
|
-
description: 'Excludes consumer topics',
|
45
|
-
short: '-e NAME',
|
46
|
-
long: '--topic-excludes NAME',
|
47
|
-
proc: proc { |a| a.split(',') }
|
48
|
-
|
49
|
-
option :autolist,
|
50
|
-
description: 'Auto list topics',
|
51
|
-
short: '-a VALUE',
|
52
|
-
long: '--auto-list VALUE',
|
53
|
-
boolean: true,
|
54
|
-
default: true
|
55
|
-
|
56
48
|
option :zookeeper,
|
57
49
|
description: 'ZooKeeper connect string',
|
58
50
|
short: '-z NAME',
|
@@ -60,85 +52,85 @@ class ConsumerLagCheck < Sensu::Plugin::Check::CLI
|
|
60
52
|
default: 'localhost:2181'
|
61
53
|
|
62
54
|
option :warning_over,
|
63
|
-
description: 'Warning if
|
55
|
+
description: 'Warning if lag is over specified value.',
|
64
56
|
short: '-W N',
|
65
57
|
long: '--warning-over N'
|
66
58
|
|
67
59
|
option :critical_over,
|
68
|
-
description: 'Critical if
|
60
|
+
description: 'Critical if lag is over specified value.',
|
69
61
|
short: '-C N',
|
70
62
|
long: '--critical-over N'
|
71
63
|
|
72
64
|
option :warning_under,
|
73
|
-
description: 'Warning if
|
65
|
+
description: 'Warning if lag is under specified value.',
|
74
66
|
short: '-w N',
|
75
67
|
long: '--warning-under N'
|
76
68
|
|
77
69
|
option :critical_under,
|
78
|
-
description: 'Critical if
|
70
|
+
description: 'Critical if lag is under specified value.',
|
79
71
|
short: '-c N',
|
80
72
|
long: '--critical-under N'
|
81
73
|
|
82
|
-
|
83
|
-
|
84
|
-
def read_lines(cmd)
|
85
|
-
IO.popen(cmd + ' 2>&1') do |child|
|
86
|
-
child.read.split("\n")
|
87
|
-
end
|
74
|
+
def kafka_topics(zk, group)
|
75
|
+
zk.get_children(path: "/consumers/#{group}/owners")[:children].sort
|
88
76
|
end
|
89
77
|
|
90
|
-
|
91
|
-
|
92
|
-
# @param cols
|
93
|
-
def line_to_hash(line, *cols)
|
94
|
-
Hash[cols.zip(line.strip.split(/\s+/, cols.size))]
|
78
|
+
def topics_partitions(zk, topic)
|
79
|
+
JSON.parse(zk.get(path: "/brokers/topics/#{topic}")[:data])['partitions'].keys.map(&:to_i).sort
|
95
80
|
end
|
96
81
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
line_to_hash(line, :group, :topic, :pid, :offset, :logsize, :lag, :owner)
|
102
|
-
end
|
82
|
+
def leader_broker(zk, topic, partition)
|
83
|
+
state = zk.get(path: "/brokers/topics/#{topic}/partitions/#{partition}/state")
|
84
|
+
leader = JSON.parse(state[:data])['leader']
|
85
|
+
JSON.parse(zk.get(path: "/brokers/ids/#{leader}")[:data])
|
103
86
|
end
|
104
87
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
topics.push(line)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
topics
|
88
|
+
def consumer_offset(zk, group, topic, partition)
|
89
|
+
zk.get(path: "/consumers/#{group}/offsets/#{topic}/#{partition}")[:data].to_i
|
90
|
+
end
|
91
|
+
|
92
|
+
def partition_owner(zk, group, partition)
|
93
|
+
zk.get(path: "/consumers/#{group}/offsets/#{owners}/#{partition}")[:data]
|
115
94
|
end
|
116
95
|
|
117
96
|
def run
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
97
|
+
z = Zookeeper.new(config[:zookeeper])
|
98
|
+
|
99
|
+
group = config[:group]
|
100
|
+
topics = kafka_topics(z, group)
|
101
|
+
|
102
|
+
critical 'Could not found topics' if topics.empty?
|
103
|
+
|
104
|
+
consumers = {}
|
105
|
+
topics.each do |topic|
|
106
|
+
consumers[topic] = {}
|
127
107
|
|
128
|
-
|
129
|
-
|
108
|
+
topics_partitions(z, topic).each do |partition|
|
109
|
+
owner = partition_owner(z, group, partition)
|
130
110
|
|
131
|
-
|
111
|
+
leader = leader_broker(z, topic, partition)
|
112
|
+
consumer = Poseidon::PartitionConsumer.new('CheckConsumerLag', leader['host'], leader['port'], topic, partition, :latest_offset)
|
113
|
+
logsize = consumer.next_offset
|
132
114
|
|
133
|
-
|
115
|
+
offset = consumer_offset(z, group, topic, partition)
|
116
|
+
|
117
|
+
lag = logsize - offset
|
118
|
+
|
119
|
+
consumers[topic][:partition] = partition
|
120
|
+
consumers[topic][:logsize] = logsize
|
121
|
+
consumers[topic][:offset] = offset
|
122
|
+
consumers[topic][:lag] = lag
|
123
|
+
consumers[topic][:owner] = owner
|
124
|
+
end
|
125
|
+
end
|
134
126
|
|
135
127
|
[:offset, :logsize, :lag].each do |field|
|
136
|
-
|
128
|
+
consumers.map do |k, v|
|
137
129
|
critical "Topic #{k} has partitions with #{field} < 0" unless v.select { |w| w[field].to_i < 0 }.empty?
|
138
130
|
end
|
139
131
|
end
|
140
132
|
|
141
|
-
|
133
|
+
consumers.map do |k, v|
|
142
134
|
critical "Topic #{k} has partitions with no owner" unless v.select { |w| w[:owner] == 'none' }.empty?
|
143
135
|
end
|
144
136
|
|
@@ -165,7 +157,7 @@ class ConsumerLagCheck < Sensu::Plugin::Check::CLI
|
|
165
157
|
end
|
166
158
|
when :under
|
167
159
|
if min_lag < threshold.to_i
|
168
|
-
msg =
|
160
|
+
msg = "Topics `#{min_topics}` for the group `#{config[:group]}` lag: #{min_lag} (<= #{threshold})"
|
169
161
|
send severity, msg
|
170
162
|
end
|
171
163
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu-plugins-kafka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sensu-Plugins and contributors
|
@@ -9,8 +9,36 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- certs/sensu-plugins.pem
|
12
|
-
date: 2017-02-
|
12
|
+
date: 2017-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: celluloid-io
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.17.3
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.17.3
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: poseidon
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.0.5
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.0.5
|
14
42
|
- !ruby/object:Gem::Dependency
|
15
43
|
name: sensu-plugin
|
16
44
|
requirement: !ruby/object:Gem::Requirement
|