rec 1.2.3 → 1.3.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.
data/CHANGELOG CHANGED
@@ -1,4 +1,9 @@
1
- === version 1.2.2
1
+ === Version 1.3.0
2
+ - Allow for pre-setting the file descriptors: $stdin, $stdout, $stderr, $miss
3
+ - Prevent events being logged as missed when they matched but not fully
4
+ - Added Notify_duration and Log_duration as State shortcuts
5
+
6
+ === Version 1.2.3
2
7
  - Recognise more date patterns
3
8
  - Improved performance
4
9
 
data/README CHANGED
@@ -231,3 +231,5 @@ refer to any parameter succinctly instead of a cumbersome hash notation, so:
231
231
  state.threshold === state.params['threshold']
232
232
 
233
233
  For more examples, see the link:file.EXAMPLES.html page.
234
+ For an example of how to execute a ruleset, see link:file.RUNNING page.
235
+
data/RUNNING ADDED
@@ -0,0 +1,26 @@
1
+ == Running REC
2
+ Here is an example script for executing REC as a daemon with a given name:
3
+
4
+ #!/usr/local/bin/ruby
5
+ # change process name. shows as "ruby: mymonitord"
6
+ $0 = "mymonitord"
7
+
8
+ require 'rubygems'
9
+ require 'rec'
10
+ include REC
11
+
12
+ $stdin = File.open("/var/mymon/logs/mymon.log", "r")
13
+ $stdout = File.open("/var/mymon/logs/rec.log" ,"a")
14
+ $miss = File.open("/var/mymon/logs/miss.log" ,"a")
15
+ $sterr = File.open("/var/mymon/logs/summary.log" ,"a")
16
+
17
+ load '/var/mymon/rulesets/credentials.rec'
18
+ load '/var/mymon/rulesets/mymon.rec'
19
+
20
+ Correlator::start(:debug=>true)
21
+
22
+ The credentials for sending emails and IMs are held in credentials, and the rules in mymon.rec
23
+
24
+ I find it easier to set up file descriptor redirection in this way than using command line notation.
25
+
26
+
@@ -44,11 +44,7 @@ class Correlator
44
44
  run()
45
45
  }
46
46
  $stderr.puts("rec is starting...")
47
- begin
48
- $miss = IO.open(3, "a") # for missed events
49
- rescue
50
- $miss = nil
51
- end
47
+ $miss ||= IO.open(3, "a") # write out to &3 for missed events, unless $miss is pre-defined
52
48
  @running = true
53
49
  run()
54
50
  end
@@ -71,8 +67,8 @@ class Correlator
71
67
  State.expire_states() # remove expired states before we check the rules
72
68
  eventMatched = false
73
69
  Rule.each { |rule|
74
- title = rule.check(message)
75
- eventMatched = true unless title.nil? # empty match is still a match
70
+ matchok, title = rule.check(message)
71
+ eventMatched ||= matchok
76
72
  next if title.nil?
77
73
  break if title.empty? # match without a message means 'swallow this event'
78
74
  state = State[title] || rule.create_state(title)
data/lib/rec/rule.rb CHANGED
@@ -108,19 +108,20 @@ class Rule
108
108
  end
109
109
 
110
110
  # Checks the original +logMessage+ against the rule, looking for a match.
111
+ # Returns a boolean (true if entry matched the pattern), and a string
111
112
  def check(logMessage)
112
113
  @@checked[@rid] += 1
113
- matchData = @pattern.match(logMessage) || return
114
+ return [false, nil] unless matchData = @pattern.match(logMessage)
114
115
  @matches = Hash[@details.zip(matchData.to_a()[1..-1])] # map matched values to detail keys
115
116
  # if any notstates are specified, make sure none are present
116
- @notstates.each { |str| return if State[str.sprinth(@matches)] }
117
+ @notstates.each { |str| return([true, nil]) if State[str.sprinth(@matches)] }
117
118
  # if any allstates are specified, they all need to be present
118
- @allstates.each { |str| return unless State[str.sprinth(@matches)] }
119
+ @allstates.each { |str| return([true, nil]) unless State[str.sprinth(@matches)] }
119
120
  # if anystates are specified, we must find one that matches
120
- return unless @anystates.empty? or @anystates.detect {|str| State[str.sprinth(@matches)] }
121
+ return([true, nil]) unless @anystates.empty? or @anystates.detect {|str| State[str.sprinth(@matches)] }
121
122
  title = @message.sprinth(@matches)
122
123
  @@matched[@rid] += 1
123
- return(title)
124
+ return([true, title])
124
125
  end
125
126
 
126
127
  # Creates a state with the given title at the specified time
data/lib/rec/state.rb CHANGED
@@ -22,9 +22,8 @@ class State
22
22
  state.generate()
23
23
  }
24
24
 
25
- # shortcut action to ignore an event
25
+ # shortcut action to ignore an event, but leave the state to expire
26
26
  Ignore = Proc.new { |state|
27
- state.release()
28
27
  }
29
28
 
30
29
  # shortcut action to generate a message and release the state immediately
@@ -58,6 +57,28 @@ class State
58
57
  state.release()
59
58
  }
60
59
 
60
+ Notify_duration = Proc.new { |state|
61
+ # We must have only one allstate, which is the original state (eg. "server down")
62
+ orig = state.params[:allstates][0] # get the original state's key
63
+ duration = state.find(original).age
64
+ # we expect to have :alert containing "%duration$d minutes"
65
+ state.details["duration"] = duration.to_i()/60 # store the outage duration
66
+ Notify.normal(state.generate()) # send the notice
67
+ state.release(original) # forget both
68
+ state.release()
69
+ }
70
+
71
+ Log_duration = Proc.new { |state|
72
+ # We must have only one allstate, which is the original state (eg. "process started")
73
+ orig = state.params[:allstates][0] # get the original state's key
74
+ duration = state.find(original).age
75
+ # we expect to have :alert containing "%duration$d minutes"
76
+ state.details["duration"] = duration.to_i()/60 # store the duration
77
+ state.generate() # record the event
78
+ state.release(original) # forget both
79
+ state.release()
80
+ }
81
+
61
82
  # A array of Timeouts. A Timeout struct has two elements:
62
83
  # - timestamp at which to expire
63
84
  # - key of the state to be expired
@@ -248,6 +269,11 @@ class State
248
269
  generate(sym) if @count == 1
249
270
  end
250
271
 
272
+ # Convenience method to find another state, based on parameters in this state
273
+ def find(template)
274
+ self.find(template, self)
275
+ end
276
+
251
277
  # Allow access to any parameter by a convenience method
252
278
  # state.capture
253
279
  # is more succinct than
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rec
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 2
9
8
  - 3
10
- version: 1.2.3
9
+ - 0
10
+ version: 1.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Richard Kernahan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-10-02 00:00:00 Z
18
+ date: 2012-10-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: xmpp4r
@@ -63,6 +63,7 @@ files:
63
63
  - EXAMPLES
64
64
  - MULTIPLEX
65
65
  - LICENSE
66
+ - RUNNING
66
67
  - CHANGELOG
67
68
  homepage: http://rubygems.org/gems/rec
68
69
  licenses: []