nagios_analyzer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.textile +50 -0
- data/Rakefile +2 -0
- data/lib/nagios_analyzer.rb +2 -0
- data/lib/nagios_analyzer/section.rb +31 -0
- data/lib/nagios_analyzer/status.rb +63 -0
- data/lib/nagios_analyzer/version.rb +3 -0
- data/nagios_analyzer.gemspec +23 -0
- data/spec/data/status.dat +280 -0
- data/spec/section_spec.rb +73 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/status_spec.rb +77 -0
- metadata +140 -0
data/Gemfile
ADDED
data/README.textile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
h1. nagios_analyzer
|
2
|
+
|
3
|
+
h2. Description
|
4
|
+
|
5
|
+
nagios_analyzer gem allows you to parse a status.dat file produced by nagios or shinken.
|
6
|
+
|
7
|
+
It's similar to nagios_parser in some way, but has different goals:
|
8
|
+
* the parser doesn't rely on 3rd party library nor standard parser like 'racc', I want to keep the code very simple to read and maintain ;
|
9
|
+
* the parser supports defining scopes, which are processed on the raw file for performance concern, ruby objects being instanciated lately when necessary : on my conf (85hosts/700services), spawning a ruby object for each section makes the script at least 10 times slower (0.25s => >3s). Most of the time, you'll only want to access a subset of your services or hosts, so it's ok.
|
10
|
+
|
11
|
+
Since nagios_parser looks very cool too, you should try both and keep the best one for you.
|
12
|
+
|
13
|
+
h2. Installation
|
14
|
+
|
15
|
+
<pre>gem install nagios_analyzer</pre>
|
16
|
+
|
17
|
+
h2. Usage
|
18
|
+
|
19
|
+
<pre>
|
20
|
+
require 'nagios_analyzer'
|
21
|
+
require 'pp'
|
22
|
+
|
23
|
+
status = NagiosAnalyzer::Status.new("/path/to/status.dat")
|
24
|
+
|
25
|
+
# get services items
|
26
|
+
pp status.service_items
|
27
|
+
|
28
|
+
# get host items
|
29
|
+
pp status.host_items
|
30
|
+
|
31
|
+
# all items ?
|
32
|
+
pp status.items
|
33
|
+
|
34
|
+
# in fact, each items is a hash
|
35
|
+
pp status.items.first
|
36
|
+
|
37
|
+
# get all sections, even those where status is OK
|
38
|
+
status = NagiosAnalyzer::Status.new("/path/to/status.dat", :include_ok => true)
|
39
|
+
|
40
|
+
# define a personal scope (applied to section string, so look at your status.dat!)
|
41
|
+
not_acknowleged = lambda{|section| section.include?("problem_has_been_acknowledged=0") }
|
42
|
+
status = NagiosAnalyzer::Status.new("/path/to/status.dat", :scope => not_acknowledged)
|
43
|
+
|
44
|
+
# add more scopes
|
45
|
+
status.scopes << lambda{|s| s.include?("notifications_enabled=1") } #no notifications
|
46
|
+
status.scopes << lambda{|s| s.start_with?("hoststatus") } #only host statuses
|
47
|
+
|
48
|
+
# reset cached results (if you changed scopes!)
|
49
|
+
status.reset_cache!
|
50
|
+
</pre>
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module NagiosAnalyzer
|
2
|
+
class Section < ::Hash
|
3
|
+
def initialize(section)
|
4
|
+
section.strip!
|
5
|
+
section.each_line do |line|
|
6
|
+
line.strip!
|
7
|
+
if line.match(/(\S+) \{/)
|
8
|
+
self[:type] = $1
|
9
|
+
elsif line.match(/(\S+)=(.*)/) #more efficient than include?+split+join..
|
10
|
+
self[$1.to_sym] = ($2 == "#{$2.to_i}" ? $2.to_i : $2)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
if self[:type] == "servicestatus"
|
14
|
+
self[:status] = Status::STATES[self[:current_state]]
|
15
|
+
else
|
16
|
+
self[:status] = (self[:current_state] == Status::STATE_OK ? "OK" : "CRITICAL")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def <=>(other)
|
21
|
+
self.sort_array <=> other.sort_array
|
22
|
+
end
|
23
|
+
|
24
|
+
def sort_array
|
25
|
+
[ (self[:type] == "servicestatus" ? 1 : 0),
|
26
|
+
Status::STATES_ORDER[self[:current_state]].to_i,
|
27
|
+
self[:host_name],
|
28
|
+
self[:service_description].to_s ]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module NagiosAnalyzer
|
2
|
+
class Status
|
3
|
+
attr_accessor :last_updated, :scopes
|
4
|
+
|
5
|
+
STATE_OK = 0
|
6
|
+
STATES = {
|
7
|
+
0 => "OK",
|
8
|
+
1 => "WARNING",
|
9
|
+
2 => "CRITICAL",
|
10
|
+
3 => "UNKNOWN",
|
11
|
+
4 => "DEPENDENT"
|
12
|
+
}
|
13
|
+
STATES_ORDER = {
|
14
|
+
2 => 0, #critical => first etc.
|
15
|
+
3 => 1,
|
16
|
+
1 => 2,
|
17
|
+
4 => 3,
|
18
|
+
0 => 4
|
19
|
+
}
|
20
|
+
|
21
|
+
def initialize(statusfile, options = {})
|
22
|
+
@file = statusfile
|
23
|
+
sections #loads section at this point so we raise immediatly if file has a item
|
24
|
+
@last_updated = Time.at(File.mtime(statusfile))
|
25
|
+
#scope is an array of lambda procs : it evaluates to true if service has to be displayed
|
26
|
+
@scopes = []
|
27
|
+
@scopes << lambda { |section| !section.include?("current_state=#{STATE_OK}") } unless options[:include_ok]
|
28
|
+
@scopes << options[:scope] if options[:scope].is_a?(Proc)
|
29
|
+
end
|
30
|
+
|
31
|
+
def sections
|
32
|
+
# don't try to instanciate each section ! on my conf (85hosts/700services),
|
33
|
+
# it makes the script more 10 times slower (0.25s => >3s)
|
34
|
+
@sections ||= File.read(@file).split("\n\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
def host_items
|
38
|
+
@host_items ||= sections.map do |s|
|
39
|
+
Section.new(s) if s.start_with?("hoststatus") && in_scope?(s)
|
40
|
+
end.compact.sort
|
41
|
+
end
|
42
|
+
|
43
|
+
def service_items
|
44
|
+
@service_items ||= sections.map do |s|
|
45
|
+
Section.new(s) if s.start_with?("servicestatus") && in_scope?(s)
|
46
|
+
end.compact.sort
|
47
|
+
end
|
48
|
+
|
49
|
+
def items
|
50
|
+
@items ||= (host_items + service_items).sort
|
51
|
+
end
|
52
|
+
|
53
|
+
def in_scope?(section)
|
54
|
+
@scopes.inject(true) do |memo,condition|
|
55
|
+
memo && condition.call(section)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def reset_cache!
|
60
|
+
@items = @service_items = @host_items = nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "nagios_analyzer/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "nagios_analyzer"
|
7
|
+
s.version = NagiosAnalyzer::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jean-Baptiste Barth"]
|
10
|
+
s.email = ["jeanbaptiste.barth@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/jbbarth/nagios_analyzer"
|
12
|
+
s.summary = %q{Parses a nagios/shinken status.dat file}
|
13
|
+
s.description = File.read(File.expand_path('../README.textile',__FILE__))
|
14
|
+
|
15
|
+
s.rubyforge_project = "nagios_analyzer"
|
16
|
+
|
17
|
+
s.add_development_dependency "rspec"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
info {
|
2
|
+
created=1268064975
|
3
|
+
version=3.0.2
|
4
|
+
}
|
5
|
+
|
6
|
+
programstatus {
|
7
|
+
modified_host_attributes=0
|
8
|
+
modified_service_attributes=0
|
9
|
+
nagios_pid=29127
|
10
|
+
daemon_mode=1
|
11
|
+
program_start=1267775205
|
12
|
+
last_command_check=1268064974
|
13
|
+
last_log_rotation=1268002800
|
14
|
+
enable_notifications=1
|
15
|
+
active_service_checks_enabled=1
|
16
|
+
passive_service_checks_enabled=1
|
17
|
+
active_host_checks_enabled=1
|
18
|
+
passive_host_checks_enabled=1
|
19
|
+
enable_event_handlers=1
|
20
|
+
obsess_over_services=0
|
21
|
+
obsess_over_hosts=0
|
22
|
+
check_service_freshness=1
|
23
|
+
check_host_freshness=1
|
24
|
+
enable_flap_detection=0
|
25
|
+
enable_failure_prediction=1
|
26
|
+
process_performance_data=1
|
27
|
+
global_host_event_handler=
|
28
|
+
global_service_event_handler=
|
29
|
+
next_comment_id=10
|
30
|
+
next_downtime_id=1
|
31
|
+
next_event_id=51893
|
32
|
+
next_problem_id=24169
|
33
|
+
next_notification_id=4606
|
34
|
+
total_external_command_buffer_slots=4096
|
35
|
+
used_external_command_buffer_slots=0
|
36
|
+
high_external_command_buffer_slots=0
|
37
|
+
active_scheduled_host_check_stats=19,82,243
|
38
|
+
active_ondemand_host_check_stats=1,2,7
|
39
|
+
passive_host_check_stats=0,0,0
|
40
|
+
active_scheduled_service_check_stats=302,632,1627
|
41
|
+
active_ondemand_service_check_stats=0,0,0
|
42
|
+
passive_service_check_stats=0,0,0
|
43
|
+
cached_host_check_stats=1,2,7
|
44
|
+
cached_service_check_stats=0,0,0
|
45
|
+
external_command_stats=0,0,0
|
46
|
+
parallel_host_check_stats=19,82,243
|
47
|
+
serial_host_check_stats=0,0,0
|
48
|
+
}
|
49
|
+
|
50
|
+
hoststatus {
|
51
|
+
host_name=server-web
|
52
|
+
modified_attributes=0
|
53
|
+
check_command=check-host-alive
|
54
|
+
check_period=setra-0h-24h
|
55
|
+
notification_period=
|
56
|
+
check_interval=5.000000
|
57
|
+
retry_interval=1.000000
|
58
|
+
event_handler=
|
59
|
+
has_been_checked=1
|
60
|
+
should_be_scheduled=1
|
61
|
+
check_execution_time=0.006
|
62
|
+
check_latency=0.091
|
63
|
+
check_type=0
|
64
|
+
current_state=0
|
65
|
+
last_hard_state=0
|
66
|
+
last_event_id=0
|
67
|
+
current_event_id=0
|
68
|
+
current_problem_id=0
|
69
|
+
last_problem_id=0
|
70
|
+
plugin_output=PING OK - Packet loss = 0%, RTA = 0.37 ms
|
71
|
+
long_plugin_output=
|
72
|
+
performance_data=
|
73
|
+
last_check=1268064745
|
74
|
+
next_check=1268065055
|
75
|
+
check_options=0
|
76
|
+
current_attempt=1
|
77
|
+
max_attempts=3
|
78
|
+
current_event_id=0
|
79
|
+
last_event_id=0
|
80
|
+
state_type=1
|
81
|
+
last_state_change=1254151315
|
82
|
+
last_hard_state_change=1254151315
|
83
|
+
last_time_up=1268064755
|
84
|
+
last_time_down=0
|
85
|
+
last_time_unreachable=0
|
86
|
+
last_notification=0
|
87
|
+
next_notification=0
|
88
|
+
no_more_notifications=0
|
89
|
+
current_notification_number=0
|
90
|
+
current_notification_id=0
|
91
|
+
notifications_enabled=1
|
92
|
+
problem_has_been_acknowledged=0
|
93
|
+
acknowledgement_type=0
|
94
|
+
active_checks_enabled=1
|
95
|
+
passive_checks_enabled=0
|
96
|
+
event_handler_enabled=1
|
97
|
+
flap_detection_enabled=1
|
98
|
+
failure_prediction_enabled=1
|
99
|
+
process_performance_data=1
|
100
|
+
obsess_over_host=0
|
101
|
+
last_update=1268064975
|
102
|
+
is_flapping=0
|
103
|
+
percent_state_change=0.00
|
104
|
+
scheduled_downtime_depth=0
|
105
|
+
}
|
106
|
+
|
107
|
+
hoststatus {
|
108
|
+
host_name=server-mail
|
109
|
+
modified_attributes=0
|
110
|
+
check_command=check-host-alive
|
111
|
+
check_period=setra-7h-20h
|
112
|
+
notification_period=
|
113
|
+
check_interval=5.000000
|
114
|
+
retry_interval=1.000000
|
115
|
+
event_handler=
|
116
|
+
has_been_checked=1
|
117
|
+
should_be_scheduled=1
|
118
|
+
check_execution_time=0.005
|
119
|
+
check_latency=0.545
|
120
|
+
check_type=0
|
121
|
+
current_state=0
|
122
|
+
last_hard_state=0
|
123
|
+
last_event_id=0
|
124
|
+
current_event_id=0
|
125
|
+
current_problem_id=0
|
126
|
+
last_problem_id=0
|
127
|
+
plugin_output=PING OK - Packet loss = 0%, RTA = 0.44 ms
|
128
|
+
long_plugin_output=
|
129
|
+
performance_data=
|
130
|
+
last_check=1268064895
|
131
|
+
next_check=1268065205
|
132
|
+
check_options=0
|
133
|
+
current_attempt=1
|
134
|
+
max_attempts=1
|
135
|
+
current_event_id=0
|
136
|
+
last_event_id=0
|
137
|
+
state_type=1
|
138
|
+
last_state_change=0
|
139
|
+
last_hard_state_change=0
|
140
|
+
last_time_up=1268064905
|
141
|
+
last_time_down=0
|
142
|
+
last_time_unreachable=0
|
143
|
+
last_notification=0
|
144
|
+
next_notification=0
|
145
|
+
no_more_notifications=0
|
146
|
+
current_notification_number=0
|
147
|
+
current_notification_id=0
|
148
|
+
notifications_enabled=1
|
149
|
+
problem_has_been_acknowledged=0
|
150
|
+
acknowledgement_type=0
|
151
|
+
active_checks_enabled=1
|
152
|
+
passive_checks_enabled=0
|
153
|
+
event_handler_enabled=1
|
154
|
+
flap_detection_enabled=1
|
155
|
+
failure_prediction_enabled=1
|
156
|
+
process_performance_data=1
|
157
|
+
obsess_over_host=0
|
158
|
+
last_update=1268064975
|
159
|
+
is_flapping=0
|
160
|
+
percent_state_change=0.00
|
161
|
+
scheduled_downtime_depth=0
|
162
|
+
}
|
163
|
+
|
164
|
+
servicestatus {
|
165
|
+
host_name=server-web
|
166
|
+
service_description=SWAP
|
167
|
+
modified_attributes=0
|
168
|
+
check_command=LINUX_SWAP!40!50
|
169
|
+
check_period=setra-7h-20h
|
170
|
+
notification_period=setra-7h-20h
|
171
|
+
check_interval=5.000000
|
172
|
+
retry_interval=1.000000
|
173
|
+
event_handler=
|
174
|
+
has_been_checked=1
|
175
|
+
should_be_scheduled=1
|
176
|
+
check_execution_time=0.369
|
177
|
+
check_latency=0.219
|
178
|
+
check_type=0
|
179
|
+
current_state=1
|
180
|
+
last_hard_state=1
|
181
|
+
last_event_id=50646
|
182
|
+
current_event_id=50777
|
183
|
+
current_problem_id=23595
|
184
|
+
last_problem_id=22914
|
185
|
+
current_attempt=3
|
186
|
+
max_attempts=3
|
187
|
+
current_event_id=50777
|
188
|
+
last_event_id=50646
|
189
|
+
state_type=1
|
190
|
+
last_state_change=1267029324
|
191
|
+
last_hard_state_change=1267029324
|
192
|
+
last_time_ok=1266943217
|
193
|
+
last_time_warning=1268064913
|
194
|
+
last_time_unknown=1265813122
|
195
|
+
last_time_critical=1267029024
|
196
|
+
plugin_output=Swap Space: 50%used(990MB/1984MB) (>40%) : WARNING
|
197
|
+
long_plugin_output=
|
198
|
+
performance_data=
|
199
|
+
last_check=1268064913
|
200
|
+
next_check=1268065213
|
201
|
+
check_options=0
|
202
|
+
current_notification_number=2
|
203
|
+
current_notification_id=4370
|
204
|
+
last_notification=1267029335
|
205
|
+
next_notification=1267029335
|
206
|
+
no_more_notifications=1
|
207
|
+
notifications_enabled=1
|
208
|
+
active_checks_enabled=1
|
209
|
+
passive_checks_enabled=0
|
210
|
+
event_handler_enabled=1
|
211
|
+
problem_has_been_acknowledged=0
|
212
|
+
acknowledgement_type=0
|
213
|
+
flap_detection_enabled=1
|
214
|
+
failure_prediction_enabled=1
|
215
|
+
process_performance_data=1
|
216
|
+
obsess_over_service=0
|
217
|
+
last_update=1268064975
|
218
|
+
is_flapping=0
|
219
|
+
percent_state_change=0.00
|
220
|
+
scheduled_downtime_depth=0
|
221
|
+
}
|
222
|
+
|
223
|
+
servicestatus {
|
224
|
+
host_name=server-mail
|
225
|
+
service_description=CPU-AVG
|
226
|
+
modified_attributes=0
|
227
|
+
check_command=LINUX_CPU
|
228
|
+
check_period=setra-7h-20h
|
229
|
+
notification_period=setra-7h-20h
|
230
|
+
check_interval=5.000000
|
231
|
+
retry_interval=1.000000
|
232
|
+
event_handler=
|
233
|
+
has_been_checked=1
|
234
|
+
should_be_scheduled=1
|
235
|
+
check_execution_time=0.227
|
236
|
+
check_latency=0.300
|
237
|
+
check_type=0
|
238
|
+
current_state=0
|
239
|
+
last_hard_state=0
|
240
|
+
last_event_id=45074
|
241
|
+
current_event_id=45077
|
242
|
+
current_problem_id=0
|
243
|
+
last_problem_id=21160
|
244
|
+
current_attempt=1
|
245
|
+
max_attempts=3
|
246
|
+
current_event_id=45077
|
247
|
+
last_event_id=45074
|
248
|
+
state_type=1
|
249
|
+
last_state_change=1263109049
|
250
|
+
last_hard_state_change=1262189471
|
251
|
+
last_time_ok=1268064914
|
252
|
+
last_time_warning=1263108989
|
253
|
+
last_time_unknown=0
|
254
|
+
last_time_critical=0
|
255
|
+
plugin_output=CPU Used OK: 0.1% - Wait=0%, System=0%, User=0%, Other=0%, Nice=0%, Idle=99.9%
|
256
|
+
long_plugin_output=
|
257
|
+
performance_data=
|
258
|
+
last_check=1268064914
|
259
|
+
next_check=1268065214
|
260
|
+
check_options=0
|
261
|
+
current_notification_number=0
|
262
|
+
current_notification_id=0
|
263
|
+
last_notification=0
|
264
|
+
next_notification=0
|
265
|
+
no_more_notifications=0
|
266
|
+
notifications_enabled=0
|
267
|
+
active_checks_enabled=1
|
268
|
+
passive_checks_enabled=0
|
269
|
+
event_handler_enabled=1
|
270
|
+
problem_has_been_acknowledged=0
|
271
|
+
acknowledgement_type=0
|
272
|
+
flap_detection_enabled=1
|
273
|
+
failure_prediction_enabled=1
|
274
|
+
process_performance_data=1
|
275
|
+
obsess_over_service=0
|
276
|
+
last_update=1268064975
|
277
|
+
is_flapping=0
|
278
|
+
percent_state_change=0.00
|
279
|
+
scheduled_downtime_depth=0
|
280
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path('../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
describe NagiosAnalyzer::Section do
|
4
|
+
include NagiosAnalyzer
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
file = File.expand_path('../data/status.dat',__FILE__)
|
8
|
+
status = Status.new(file)
|
9
|
+
@section = status.service_items.first
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns a hash with keys only" do
|
13
|
+
@section.should be_a(Section)
|
14
|
+
@section.should be_a(Hash)
|
15
|
+
@section.keys.map(&:class).uniq.should == [Symbol]
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses a section" do
|
19
|
+
@section[:type].should == "servicestatus"
|
20
|
+
@section[:host_name].should == "server-web"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "converts integers to Integer's" do
|
24
|
+
@section[:max_attempts].should be_a(Integer)
|
25
|
+
@section[:max_attempts].should == 3
|
26
|
+
end
|
27
|
+
|
28
|
+
it "provides a :status key to know the status" do
|
29
|
+
@section[:status].should == "WARNING"
|
30
|
+
Section.new("servicestatus {\ncurrent_state=0\n}")[:status].should == "OK"
|
31
|
+
Section.new("servicestatus {\ncurrent_state=2\n}")[:status].should == "CRITICAL"
|
32
|
+
Section.new("servicestatus {\ncurrent_state=3\n}")[:status].should == "UNKNOWN"
|
33
|
+
Section.new("hoststatus {\ncurrent_state=0\n}")[:status].should == "OK"
|
34
|
+
Section.new("hoststatus {\ncurrent_state=42\n}")[:status].should == "CRITICAL"
|
35
|
+
end
|
36
|
+
|
37
|
+
context "#sort" do
|
38
|
+
it "places servicestatus'es after hoststatus'es" do
|
39
|
+
a = Section.new("servicestatus {\ncurrent_state=0\n}")
|
40
|
+
b = Section.new("hoststatus {\ncurrent_state=0\n}")
|
41
|
+
[a,b].sort.should == [b,a]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "places critical before unknown before warning before pending before dependent before ok" do
|
45
|
+
host = Section.new("hoststatus {\ncurrent_state=0\n}")
|
46
|
+
critical = Section.new("servicestatus {\ncurrent_state=2\n}")
|
47
|
+
unknown = Section.new("servicestatus {\ncurrent_state=3\n}")
|
48
|
+
warning = Section.new("servicestatus {\ncurrent_state=1\n}")
|
49
|
+
dependent = Section.new("servicestatus {\ncurrent_state=4\n}")
|
50
|
+
ok = Section.new("servicestatus {\ncurrent_state=0\n}")
|
51
|
+
[ok, unknown, dependent, critical, host, warning].sort.should == [host, critical, unknown, warning, dependent, ok]
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sorts by host_name" do
|
55
|
+
a = Section.new("hoststatus {\ncurrent_state=0\nhost_name=a\n}")
|
56
|
+
b = Section.new("hoststatus {\ncurrent_state=0\nhost_name=b\n}")
|
57
|
+
[b,a].sort.should == [a,b]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "sorts by service_description" do
|
61
|
+
a = Section.new("hoststatus {\ncurrent_state=0\n}")
|
62
|
+
b = Section.new("servicestatus {\ncurrent_state=0\nservice_description=b\n}")
|
63
|
+
c = Section.new("servicestatus {\ncurrent_state=0\nservice_description=c\n}")
|
64
|
+
[c,b,a].sort.should == [a,b,c]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "has no problem even with missing fields (hostname don't have service_description)" do
|
68
|
+
a = Section.new("hoststatus {\ncurrent_state=0\n}")
|
69
|
+
b = Section.new("hoststatus {\ncurrent_state=0\n}")
|
70
|
+
[a,b].sort.should == [a,b]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/status_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.expand_path('../spec_helper',__FILE__)
|
2
|
+
|
3
|
+
describe NagiosAnalyzer::Status do
|
4
|
+
before(:each) do
|
5
|
+
@file = File.expand_path('../data/status.dat',__FILE__)
|
6
|
+
@status = NagiosAnalyzer::Status.new(@file, :include_ok => true)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "creates a NagiosAnalyzer::Status object" do
|
10
|
+
@status.should be
|
11
|
+
@status.sections.should be_a(Array)
|
12
|
+
@status.sections.first.should include("created=")
|
13
|
+
@status.should have(6).sections
|
14
|
+
end
|
15
|
+
|
16
|
+
it "provides a last_updated attribute" do
|
17
|
+
@status.last_updated.should be_a(Time)
|
18
|
+
end
|
19
|
+
|
20
|
+
context "#scopes" do
|
21
|
+
it "provides scopes to filter sections" do
|
22
|
+
@status.should have(6).sections
|
23
|
+
@status.should have(0).scopes
|
24
|
+
end
|
25
|
+
|
26
|
+
it "tells if a section is in the scopes" do
|
27
|
+
@status.scopes << lambda{|s|s.include?("host_name=server-web")}
|
28
|
+
@status.in_scope?(@status.sections[2]).should be_true
|
29
|
+
@status.in_scope?(@status.sections[3]).should be_false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "defines scope in the initialization" do
|
33
|
+
@status = NagiosAnalyzer::Status.new(@file, :include_ok => true,
|
34
|
+
:scope => lambda{|s|s.include?("host_name=server-web")})
|
35
|
+
@status.in_scope?(@status.sections[2]).should be_true
|
36
|
+
@status.in_scope?(@status.sections[3]).should be_false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "#items, #service_items, #host_items" do
|
41
|
+
it "returns all items" do
|
42
|
+
@status.should have(6).sections
|
43
|
+
@status.should have(4).items #don't return info{} and programstatus{} sections
|
44
|
+
@status.items.first.should be_a(NagiosAnalyzer::Section)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns host items" do
|
48
|
+
@status.should have(2).host_items #4 = 2 host_items
|
49
|
+
@status.host_items.first[:type].should == "hoststatus"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns service items" do
|
53
|
+
@status.should have(2).service_items # ... + 2 service_items
|
54
|
+
@status.service_items.first[:type].should == "servicestatus"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "resets cached attributes" do
|
58
|
+
@status.should have(4).items
|
59
|
+
@status.scopes << lambda{|s| s.start_with?("servicestatus")}
|
60
|
+
@status.should have(4).items
|
61
|
+
@status.reset_cache!
|
62
|
+
@status.should have(2).items
|
63
|
+
@status.should have(0).host_items
|
64
|
+
@status.should have(2).service_items
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "without :include_ok option" do
|
69
|
+
it "should filter items" do
|
70
|
+
@status = NagiosAnalyzer::Status.new(@file)
|
71
|
+
@status.should have(1).items #don't return info{} and programstatus{} sections
|
72
|
+
@status.should have(0).host_items #4 = 2 host_items
|
73
|
+
@status.should have(1).service_items # ... + 2 service_items
|
74
|
+
@status.service_items.first.should_not include("current_state=0")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nagios_analyzer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jean-Baptiste Barth
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-28 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
description: |
|
34
|
+
h1. nagios_analyzer
|
35
|
+
|
36
|
+
h2. Description
|
37
|
+
|
38
|
+
nagios_analyzer gem allows you to parse a status.dat file produced by nagios or shinken.
|
39
|
+
|
40
|
+
It's similar to nagios_parser in some way, but has different goals:
|
41
|
+
* the parser doesn't rely on 3rd party library nor standard parser like 'racc', I want to keep the code very simple to read and maintain ;
|
42
|
+
* the parser supports defining scopes, which are processed on the raw file for performance concern, ruby objects being instanciated lately when necessary : on my conf (85hosts/700services), spawning a ruby object for each section makes the script at least 10 times slower (0.25s => >3s). Most of the time, you'll only want to access a subset of your services or hosts, so it's ok.
|
43
|
+
|
44
|
+
Since nagios_parser looks very cool too, you should try both and keep the best one for you.
|
45
|
+
|
46
|
+
h2. Installation
|
47
|
+
|
48
|
+
<pre>gem install nagios_analyzer</pre>
|
49
|
+
|
50
|
+
h2. Usage
|
51
|
+
|
52
|
+
<pre>
|
53
|
+
require 'nagios_analyzer'
|
54
|
+
require 'pp'
|
55
|
+
|
56
|
+
status = NagiosAnalyzer::Status.new("/path/to/status.dat")
|
57
|
+
|
58
|
+
# get services items
|
59
|
+
pp status.service_items
|
60
|
+
|
61
|
+
# get host items
|
62
|
+
pp status.host_items
|
63
|
+
|
64
|
+
# all items ?
|
65
|
+
pp status.items
|
66
|
+
|
67
|
+
# in fact, each items is a hash
|
68
|
+
pp status.items.first
|
69
|
+
|
70
|
+
# get all sections, even those where status is OK
|
71
|
+
status = NagiosAnalyzer::Status.new("/path/to/status.dat", :include_ok => true)
|
72
|
+
|
73
|
+
# define a personal scope (applied to section string, so look at your status.dat!)
|
74
|
+
not_acknowleged = lambda{|section| section.include?("problem_has_been_acknowledged=0") }
|
75
|
+
status = NagiosAnalyzer::Status.new("/path/to/status.dat", :scope => not_acknowledged)
|
76
|
+
|
77
|
+
# add more scopes
|
78
|
+
status.scopes << lambda{|s| s.include?("notifications_enabled=1") } #no notifications
|
79
|
+
status.scopes << lambda{|s| s.start_with?("hoststatus") } #only host statuses
|
80
|
+
|
81
|
+
# reset cached results (if you changed scopes!)
|
82
|
+
status.reset_cache!
|
83
|
+
</pre>
|
84
|
+
|
85
|
+
email:
|
86
|
+
- jeanbaptiste.barth@gmail.com
|
87
|
+
executables: []
|
88
|
+
|
89
|
+
extensions: []
|
90
|
+
|
91
|
+
extra_rdoc_files: []
|
92
|
+
|
93
|
+
files:
|
94
|
+
- .gitignore
|
95
|
+
- Gemfile
|
96
|
+
- README.textile
|
97
|
+
- Rakefile
|
98
|
+
- lib/nagios_analyzer.rb
|
99
|
+
- lib/nagios_analyzer/section.rb
|
100
|
+
- lib/nagios_analyzer/status.rb
|
101
|
+
- lib/nagios_analyzer/version.rb
|
102
|
+
- nagios_analyzer.gemspec
|
103
|
+
- spec/data/status.dat
|
104
|
+
- spec/section_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/status_spec.rb
|
107
|
+
has_rdoc: true
|
108
|
+
homepage: http://github.com/jbbarth/nagios_analyzer
|
109
|
+
licenses: []
|
110
|
+
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
segments:
|
122
|
+
- 0
|
123
|
+
version: "0"
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
version: "0"
|
132
|
+
requirements: []
|
133
|
+
|
134
|
+
rubyforge_project: nagios_analyzer
|
135
|
+
rubygems_version: 1.3.7
|
136
|
+
signing_key:
|
137
|
+
specification_version: 3
|
138
|
+
summary: Parses a nagios/shinken status.dat file
|
139
|
+
test_files: []
|
140
|
+
|