redis_alerting 1.1.1 → 1.3.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 +5 -13
- data/LICENSE.txt +1 -1
- data/README.md +51 -15
- data/bin/redis-alerting +1 -0
- data/etc/config.yml +12 -8
- data/lib/redis_alerting/config.rb +16 -1
- data/lib/redis_alerting/engine.rb +51 -10
- data/lib/redis_alerting/version.rb +1 -1
- data/lib/redis_alerting.rb +5 -2
- metadata +19 -19
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ODRlY2JlMTIyMzZiOWU5YTgwM2NlMjE4YjNlZGU2NGI3MDlkNmM2ZQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9002db58d2b36ba06bb23317c3bf5da1fe8a7699
|
4
|
+
data.tar.gz: 43fecfbb4fa2a032d0aa384b085504fa0c5c19a9
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NzRlNDM5YjA1NmU4MDkzNjQyN2E3ZWUzZDE4ZjIyYjI5Y2Q2OWIyMzQ0NTkx
|
11
|
-
NjE0ZmE3ZDZlYTVlMjZmMmI3MGI2YzIwYTE2NzE1ZTZiMTVhYTg=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTg2YWNiODQyZTg4NzgwNTVkZGIzZTAzMDVjMDE2OGUyYTcwMWE3MjBiMjUy
|
14
|
-
MjlkM2M3Zjk5ZmEzOTkxOWRiYzY0ZmM3NDBkZmY1YTEyYWNkZjUwN2U5ZjZl
|
15
|
-
N2UyZjQ1ZTA2NTljMGZlNGI4MzQ0Y2Q5NGRhYmZkMWZmZDlhMTg=
|
6
|
+
metadata.gz: 0693caadb5119b3cb42855c85d82a95155645455d3568f0641d80ee33c16bbe50e13f17522adf6cf9d5a03acfc839417d68724c4b9138d17c1b8369aeffe59f0
|
7
|
+
data.tar.gz: 95509af5f6264bb945082dc2dae47495b487d2159cf07bf6aa1c65473e0c6ad300b170319d17b5c48498987e7aefb725a34551f2ae91e8e01efbae91d26b1d28
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -20,12 +20,19 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
To start the engine:
|
23
|
+
To start and daemonize the engine:
|
24
24
|
|
25
25
|
```sh
|
26
26
|
redis-alerting start -- -c path/to/config.yml
|
27
27
|
```
|
28
28
|
|
29
|
+
To run it with logging output:
|
30
|
+
|
31
|
+
```sh
|
32
|
+
redis-alerting run -- -c path/to/config.yml -l info
|
33
|
+
#redis-alerting run -- -c path/to/config.yml -l debug # this will be noisy!
|
34
|
+
```
|
35
|
+
|
29
36
|
Check the status:
|
30
37
|
|
31
38
|
```sh
|
@@ -46,17 +53,43 @@ Given the config file below we will describe how the gem would check some limits
|
|
46
53
|
|
47
54
|
```yaml
|
48
55
|
---
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
56
|
+
:interval: 1 # how often to check the readings
|
57
|
+
:namespace: alerts # the namespace to use for tracking active alerts/conditions
|
58
|
+
:separator: . # redis namespace separator
|
59
|
+
:channel: alerts # publish alert messages to this channel
|
60
|
+
:extrema: # details for where to find extrema information
|
61
|
+
:min: min # what you call your minimum
|
62
|
+
:max: max # what you call your maximum
|
63
|
+
:pattern: settings.$source_$extrema # the pattern to locate your extrema keys
|
64
|
+
:sources: # keys to obtain values from that need to be checked
|
65
|
+
:ph: readings.ph
|
66
|
+
:ec: readings.ec
|
67
|
+
:flow_rate: readings.flow_rate
|
68
|
+
# :name: redis.key.with.live.value
|
58
69
|
```
|
59
70
|
|
71
|
+
### Extrema Patterns
|
72
|
+
|
73
|
+
So to find the min/max keys you will need to specify the pattern your extrema keys use (you use a pattern right?)
|
74
|
+
|
75
|
+
In the above case `settings.$source_$extrema` would be translated into:
|
76
|
+
|
77
|
+
* `settings.ph_min`
|
78
|
+
* `settings.ph_max`
|
79
|
+
* `settings.flow_rate_min`
|
80
|
+
* `settings.flow_rate_max`
|
81
|
+
|
82
|
+
If you stored your extrema a bit differently, a pattern like this might suffice: `alerts:$source:$extrema`:
|
83
|
+
|
84
|
+
* `alerts:ph:min`
|
85
|
+
* `alerts:ph:max`
|
86
|
+
* `alerts:ec:min`
|
87
|
+
* `alerts:ec:max`
|
88
|
+
|
89
|
+
Get it?
|
90
|
+
|
91
|
+
### Sources
|
92
|
+
|
60
93
|
With the example of `ph` above, the alerting system would check the redis key `readings.ph` and determine if it was outside the limits set in `alerts.ph.max` and `alerts.ph.min`.
|
61
94
|
|
62
95
|
When it finds that the value in `readings.ph` is outside the range, it will add "ph" to the redis set `alerts.active`. When it comes back into range "ph" will be removed from the `alerts.active` set.
|
@@ -64,9 +97,12 @@ When it finds that the value in `readings.ph` is outside the range, it will add
|
|
64
97
|
So to quickly summarize:
|
65
98
|
|
66
99
|
* `readings.ph` - the reading value used to check against the min and max settings
|
67
|
-
* `
|
68
|
-
* `
|
69
|
-
|
100
|
+
* `settings.ph_min` - the minimum value for the reading (below which an alert is raised)
|
101
|
+
* `settings.ph_max` - the maximum value for the reading (above which an alert is raised)
|
102
|
+
|
103
|
+
### Active Set
|
104
|
+
|
105
|
+
At anytime you can query the contents of the `alerts.active` SET to see which alert sources are currently active. It will contain the name specified under the sources section.
|
70
106
|
|
71
107
|
### Published messages
|
72
108
|
|
@@ -103,8 +139,8 @@ With the engine started try this (still sticking with the keys in the config fil
|
|
103
139
|
|
104
140
|
```sh
|
105
141
|
$ redis-cli
|
106
|
-
127.0.0.1:6379> set
|
107
|
-
127.0.0.1:6379> set
|
142
|
+
127.0.0.1:6379> set settings.ph_min 4000
|
143
|
+
127.0.0.1:6379> set settings.ph_max 9000
|
108
144
|
127.0.0.1:6379> set readings.ph 6000
|
109
145
|
127.0.0.1:6379> smembers alerts.active
|
110
146
|
(empty list or set)
|
data/bin/redis-alerting
CHANGED
data/etc/config.yml
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
:interval: 1
|
3
|
+
:namespace: alerts
|
4
|
+
:separator: .
|
5
|
+
:channel: alerts
|
6
|
+
:extrema:
|
7
|
+
:min: min
|
8
|
+
:max: max
|
9
|
+
:pattern: settings.$source_$extrema
|
10
|
+
:sources:
|
11
|
+
:ph: readings.ph
|
12
|
+
:ec: readings.ec
|
13
|
+
:flow_rate: readings.flow_rate
|
@@ -22,11 +22,26 @@ module RedisAlerting
|
|
22
22
|
raise ArgumentError, "Invalid config file: #{@config[:config]}" unless File.exists? @config[:config]
|
23
23
|
|
24
24
|
yaml = YAML.load_file(@config[:config])
|
25
|
-
@config.merge!(yaml
|
25
|
+
@config.merge!(yaml)
|
26
|
+
|
27
|
+
@config[:log_level] = parse_log_level
|
26
28
|
|
27
29
|
raise ArgumentError, "Incomplete configuration" unless valid_config?
|
28
30
|
end
|
29
31
|
|
32
|
+
def parse_log_level
|
33
|
+
return Logger::UNKNOWN if @config[:log].nil? or @config[:log] == false
|
34
|
+
|
35
|
+
case @config[:log]
|
36
|
+
when "error"
|
37
|
+
Logger::ERROR
|
38
|
+
when "debug"
|
39
|
+
Logger::DEBUG
|
40
|
+
else
|
41
|
+
Logger::INFO
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
30
45
|
# TODO: check we have all the needed options
|
31
46
|
def valid_config?
|
32
47
|
true
|
@@ -1,21 +1,43 @@
|
|
1
1
|
module RedisAlerting
|
2
2
|
class Engine
|
3
|
-
def initialize(config, redis)
|
4
|
-
@config
|
5
|
-
@active_set = "#{@config[:namespace]}
|
6
|
-
@redis
|
3
|
+
def initialize(config, redis, log)
|
4
|
+
@config = config
|
5
|
+
@active_set = "#{@config[:namespace]}#{@config[:separator]}active"
|
6
|
+
@redis = redis
|
7
|
+
@log = log
|
8
|
+
@extrema = {}
|
9
|
+
|
7
10
|
check_redis
|
11
|
+
build_extrema
|
12
|
+
|
13
|
+
@log.info "Redis Alerting Engine Initialized"
|
14
|
+
@log.info "Publishing alert information on channel: #{@config[:channel]}"
|
15
|
+
@log.info "Currently active alerts are in the key: #{@active_set}"
|
16
|
+
|
17
|
+
@log.info "Working with sources:"
|
18
|
+
@config[:sources].each do |name, source|
|
19
|
+
@log.info " #{name}: #{source}"
|
20
|
+
end
|
21
|
+
|
22
|
+
@log.info "Working with extrema:"
|
23
|
+
@extrema.each do |name, ex|
|
24
|
+
@log.info " #{name}:"
|
25
|
+
@log.info " min: #{ex[:min]}"
|
26
|
+
@log.info " max: #{ex[:max]}"
|
27
|
+
end
|
28
|
+
|
8
29
|
end
|
9
30
|
|
10
31
|
def run
|
11
|
-
ns = @config[:namespace]
|
12
32
|
@config[:sources].each do |name, source|
|
13
33
|
|
14
34
|
# get the readings and alert ranges
|
15
|
-
min = @redis.get(
|
16
|
-
max = @redis.get(
|
35
|
+
min = @redis.get(@extrema[name][:min]).to_i
|
36
|
+
max = @redis.get(@extrema[name][:max]).to_i
|
17
37
|
value = @redis.get(source).to_i
|
18
38
|
|
39
|
+
@log.debug "Checking #{name} (min #{min}) (max #{max}): #{value}"
|
40
|
+
|
19
41
|
# silently ignore
|
20
42
|
next if max.nil? or min.nil? or value.nil?
|
21
43
|
|
@@ -40,8 +62,11 @@ module RedisAlerting
|
|
40
62
|
end
|
41
63
|
|
42
64
|
def add_alert_for(name, condition, value, min, max)
|
43
|
-
return if @redis.sismember(@active_set, name)
|
65
|
+
return if @redis.sismember(@active_set, name) and @redis.get(condition_key(name)) == condition.to_s
|
44
66
|
@redis.sadd @active_set, name
|
67
|
+
@redis.set condition_key(name), condition
|
68
|
+
|
69
|
+
@log.info "Added #{name} to active set"
|
45
70
|
|
46
71
|
publish({
|
47
72
|
action: :add,
|
@@ -56,7 +81,10 @@ module RedisAlerting
|
|
56
81
|
def remove_if_alert_exists(name, value, min, max)
|
57
82
|
return unless @redis.sismember(@active_set, name)
|
58
83
|
@redis.srem @active_set, name
|
59
|
-
|
84
|
+
@redis.set condition_key(name), "OK"
|
85
|
+
|
86
|
+
@log.info "Removed #{name} from active set"
|
87
|
+
|
60
88
|
publish({
|
61
89
|
action: :remove,
|
62
90
|
name: name,
|
@@ -68,12 +96,25 @@ module RedisAlerting
|
|
68
96
|
|
69
97
|
def publish(message)
|
70
98
|
@redis.publish @config[:channel], message.to_json
|
71
|
-
|
99
|
+
@log.info "Pushed message: #{message.inspect}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def condition_key(name)
|
103
|
+
"#{@config[:namespace]}#{@config[:separator]}#{name}#{@config[:separator]}condition"
|
72
104
|
end
|
73
105
|
|
74
106
|
def check_redis
|
75
107
|
raise ArgumentError, "Invalid Redis instance given" unless @redis.is_a? Redis
|
76
108
|
raise ArgumentError, "Could not connect to Redis" unless @redis.ping == "PONG"
|
77
109
|
end
|
110
|
+
|
111
|
+
def build_extrema
|
112
|
+
@config[:sources].each do |source, redis_key|
|
113
|
+
@extrema[source] = {
|
114
|
+
min: @config[:extrema][:pattern].gsub("$source", source.to_s).gsub("$extrema", @config[:extrema][:min]),
|
115
|
+
max: @config[:extrema][:pattern].gsub("$source", source.to_s).gsub("$extrema", @config[:extrema][:max])
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
78
119
|
end
|
79
120
|
end
|
data/lib/redis_alerting.rb
CHANGED
@@ -2,14 +2,17 @@ require "redis_alerting/version"
|
|
2
2
|
require "redis_alerting/engine"
|
3
3
|
require "redis_alerting/config"
|
4
4
|
require 'redis'
|
5
|
+
require 'logger'
|
5
6
|
require 'yaml'
|
6
7
|
require 'json'
|
7
8
|
|
8
9
|
module RedisAlerting
|
9
10
|
class << self
|
10
11
|
def run(opts)
|
11
|
-
config
|
12
|
-
|
12
|
+
config = RedisAlerting::Config.new(opts).to_hash
|
13
|
+
log = Logger.new STDOUT
|
14
|
+
log.level = config[:log_level]
|
15
|
+
engine = RedisAlerting::Engine.new(config, ::Redis.new, log)
|
13
16
|
|
14
17
|
loop do
|
15
18
|
engine.run
|
metadata
CHANGED
@@ -1,111 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_alerting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert McLeod
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: slop
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: daemons
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '1.7'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.7'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '10.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '10.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: pry
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
description: Checks redis for alert conditions and adds keys to a set when a value
|
@@ -117,7 +117,7 @@ executables:
|
|
117
117
|
extensions: []
|
118
118
|
extra_rdoc_files: []
|
119
119
|
files:
|
120
|
-
- .gitignore
|
120
|
+
- ".gitignore"
|
121
121
|
- Gemfile
|
122
122
|
- LICENSE.txt
|
123
123
|
- README.md
|
@@ -141,12 +141,12 @@ require_paths:
|
|
141
141
|
- lib
|
142
142
|
required_ruby_version: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- -
|
144
|
+
- - ">="
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
|
-
- -
|
149
|
+
- - ">="
|
150
150
|
- !ruby/object:Gem::Version
|
151
151
|
version: '0'
|
152
152
|
requirements: []
|