alerty 0.0.8 → 0.0.9
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 +6 -0
- data/README.md +5 -0
- data/alerty.gemspec +1 -1
- data/lib/alerty/cli.rb +7 -1
- data/lib/alerty/command.rb +53 -34
- data/lib/alerty/config.rb +14 -0
- data/spec/command_spec.rb +27 -1
- data/spec/config_spec.rb +22 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 689717247b8b716abcb2c075cb639dea127bceb4
|
4
|
+
data.tar.gz: 3e30b2ad81fef99ed76de3890f2fd604e352874c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8f92fe2bf8a763242ba11a153ce4c61e2fd94d2a05bc4187ce324c6f97fb62be620a9a115556a590a88997ef75b5ff7f5ec9145a91b77acc16b212816995e39
|
7
|
+
data.tar.gz: c579e1a0202ae502bf43ff8b52961fb1bbfb5b5fb400781b48e7e848865e48ac93a412881a45b93103523e6864860ddf006ab3a6d0fe6d761de88685f5f44b6a
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -25,6 +25,8 @@ log_path: STDOUT
|
|
25
25
|
log_level: 'debug'
|
26
26
|
timeout: 10
|
27
27
|
lock_path: /tmp/lock
|
28
|
+
retry_limit: 2
|
29
|
+
retry_wait: 10
|
28
30
|
plugins:
|
29
31
|
- type: stdout
|
30
32
|
```
|
@@ -46,6 +48,8 @@ $ bin/alerty -h
|
|
46
48
|
-l, --log-level LOG_LEVEL log level (default: warn)
|
47
49
|
-t, --timeout SECONDS timeout of the command, send alert if timeout reached (default: no timeout)
|
48
50
|
--lock LOCK_FILE exclusive lock file to prevent running a command duplicatedly, send alert if locked (default: no lock)
|
51
|
+
--retry-limit NUMBER number of retries (default: 0)
|
52
|
+
--retry-wait SECONDS retry interval = retry wait +/- 12.5% randomness (default: 1.0)
|
49
53
|
-d, --debug debug mode (same with --log-level debug)
|
50
54
|
```
|
51
55
|
|
@@ -117,6 +121,7 @@ plugins:
|
|
117
121
|
* output: the output of the exectued command
|
118
122
|
* started_at: the time when command executed in epoch time.
|
119
123
|
* duration: the duration which the command execution has taken in seconds.
|
124
|
+
* retries: the number of retries
|
120
125
|
|
121
126
|
## ChangeLog
|
122
127
|
|
data/alerty.gemspec
CHANGED
data/lib/alerty/cli.rb
CHANGED
@@ -26,11 +26,17 @@ class Alerty
|
|
26
26
|
opts[:log_level] = v
|
27
27
|
}
|
28
28
|
op.on('-t', '--timeout SECONDS', "timeout the command (default: no timeout)") {|v|
|
29
|
-
opts[:timeout] = v.
|
29
|
+
opts[:timeout] = v.to_f
|
30
30
|
}
|
31
31
|
op.on('--lock LOCK_FILE', "exclusive lock file to prevent running a command duplicatedly (default: no lock)") {|v|
|
32
32
|
opts[:lock_path] = v
|
33
33
|
}
|
34
|
+
op.on('--retry-limit NUMBER', "number of retries (default: 0)") {|v|
|
35
|
+
opts[:retry_limit] = v.to_i
|
36
|
+
}
|
37
|
+
op.on('--retry-wait SECONDS', "retry interval = retry wait +/- 12.5% randomness (default: 1.0)") {|v|
|
38
|
+
opts[:retry_wait] = v.to_f
|
39
|
+
}
|
34
40
|
op.on('-d', '--debug', "debug mode (same with --log-level debug)") {|v|
|
35
41
|
opts[:log_level] = 'debug'
|
36
42
|
}
|
data/lib/alerty/command.rb
CHANGED
@@ -11,41 +11,46 @@ class Alerty
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def run!
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
14
|
+
record = {}
|
15
|
+
with_retry do |retries|
|
16
|
+
started_at = Time.now
|
17
|
+
begin
|
18
|
+
result = Frontkick.exec("#{@command} 2>&1", @opts)
|
19
|
+
rescue Frontkick::Timeout => e
|
20
|
+
record = {
|
21
|
+
hostname: @hostname,
|
22
|
+
command: @command,
|
23
|
+
exitstatus: 1,
|
24
|
+
output: "`#{@command}` is timeout (#{@opts[:timeout]} sec)",
|
25
|
+
started_at: started_at.to_f,
|
26
|
+
duration: @opts[:timeout],
|
27
|
+
retries: retries,
|
28
|
+
}
|
29
|
+
rescue Frontkick::Locked => e
|
30
|
+
record = {
|
31
|
+
hostname: @hostname,
|
32
|
+
command: @command,
|
33
|
+
exitstatus: 1,
|
34
|
+
output: "`#{@opts[:exclusive]}` is locked by another process",
|
35
|
+
started_at: started_at.to_f,
|
36
|
+
duration: 0,
|
37
|
+
retries: retries,
|
38
|
+
}
|
39
|
+
else
|
40
|
+
record = {
|
41
|
+
hostname: @hostname,
|
42
|
+
command: @command,
|
43
|
+
exitstatus: result.exitstatus,
|
44
|
+
output: result.stdout,
|
45
|
+
started_at: started_at.to_f,
|
46
|
+
duration: result.duration,
|
47
|
+
retries: retries,
|
48
|
+
}
|
49
|
+
end
|
50
|
+
Alerty.logger.info { "result: #{record.to_json}" }
|
51
|
+
record
|
44
52
|
end
|
45
|
-
|
46
|
-
if record[:exitstatus] == 0
|
47
|
-
exit 0
|
48
|
-
else
|
53
|
+
unless record[:exitstatus] == 0
|
49
54
|
Config.plugins.each do |plugin|
|
50
55
|
begin
|
51
56
|
plugin.alert(record)
|
@@ -56,5 +61,19 @@ class Alerty
|
|
56
61
|
exit record[:exitstatus]
|
57
62
|
end
|
58
63
|
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def with_retry
|
68
|
+
retries = 0
|
69
|
+
while true
|
70
|
+
record = yield(retries)
|
71
|
+
break if record[:exitstatus] == 0
|
72
|
+
break if retries >= Config.retry_limit
|
73
|
+
retries += 1
|
74
|
+
sleep Config.retry_interval
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
59
78
|
end
|
60
79
|
end
|
data/lib/alerty/config.rb
CHANGED
@@ -34,6 +34,20 @@ class Alerty
|
|
34
34
|
opts[:lock_path] || config.lock_path
|
35
35
|
end
|
36
36
|
|
37
|
+
def retry_limit
|
38
|
+
opts[:retry_limit] || config.retry_limit || 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def retry_wait
|
42
|
+
opts[:retry_wait] || config.retry_wait || 1.0
|
43
|
+
end
|
44
|
+
|
45
|
+
def retry_interval
|
46
|
+
@random ||= Random.new
|
47
|
+
randomness = retry_wait * 0.125
|
48
|
+
retry_wait + @random.rand(-randomness .. randomness)
|
49
|
+
end
|
50
|
+
|
37
51
|
def plugins
|
38
52
|
@plugins ||= config.fetch('plugins').map do |plugin|
|
39
53
|
require "alerty/plugin/#{plugin.type}"
|
data/spec/command_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe Alerty::Command do
|
|
19
19
|
timeout: 20,
|
20
20
|
exclusive: '/tmp/lock',
|
21
21
|
}).and_return(Frontkick::Result.new(exit_code: 0))
|
22
|
-
expect { command.run! }.
|
22
|
+
expect { command.run! }.not_to raise_error
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -104,5 +104,31 @@ describe Alerty::Command do
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
+
context 'retry' do
|
108
|
+
before do
|
109
|
+
Alerty::Config.instance_variable_set(:@config, Hashie::Mash.new(
|
110
|
+
plugins: [{
|
111
|
+
type: 'stdout',
|
112
|
+
}]
|
113
|
+
))
|
114
|
+
Alerty::Config.configure(
|
115
|
+
log_path: '/tmp/foo',
|
116
|
+
log_level: 'fatal',
|
117
|
+
retry_limit: 1,
|
118
|
+
)
|
119
|
+
end
|
120
|
+
|
121
|
+
let(:command) { Alerty::Command.new(command: 'echo foo') }
|
122
|
+
|
123
|
+
it do
|
124
|
+
expect(Frontkick).to receive(:exec).twice.with("echo foo 2>&1", {
|
125
|
+
timeout: nil,
|
126
|
+
exclusive: nil,
|
127
|
+
}).and_return(Frontkick::Result.new(stdout: 'foo', exit_code: 1))
|
128
|
+
stdout = capture_stdout { expect { command.run! }.to raise_error(SystemExit) }
|
129
|
+
expect(JSON.parse(stdout)["retries"]).to eql(1)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
107
133
|
end
|
108
134
|
end
|
data/spec/config_spec.rb
CHANGED
@@ -8,6 +8,8 @@ describe Alerty::Config do
|
|
8
8
|
log_level: 'fatal',
|
9
9
|
timeout: 20,
|
10
10
|
lock_path: '/tmp/lock',
|
11
|
+
retry_limit: 5,
|
12
|
+
retry_wait: 10,
|
11
13
|
)
|
12
14
|
end
|
13
15
|
|
@@ -15,6 +17,8 @@ describe Alerty::Config do
|
|
15
17
|
it { expect(Alerty::Config.log_level).to eql('fatal') }
|
16
18
|
it { expect(Alerty::Config.timeout).to eql(20) }
|
17
19
|
it { expect(Alerty::Config.lock_path).to eql('/tmp/lock') }
|
20
|
+
it { expect(Alerty::Config.retry_limit).to eql(5) }
|
21
|
+
it { expect(Alerty::Config.retry_wait).to eql(10) }
|
18
22
|
end
|
19
23
|
|
20
24
|
describe 'config' do
|
@@ -24,6 +28,8 @@ describe Alerty::Config do
|
|
24
28
|
log_level: 'fatal',
|
25
29
|
timeout: 20,
|
26
30
|
lock_path: '/tmp/lock',
|
31
|
+
retry_limit: 5,
|
32
|
+
retry_wait: 10,
|
27
33
|
))
|
28
34
|
end
|
29
35
|
|
@@ -31,6 +37,22 @@ describe Alerty::Config do
|
|
31
37
|
it { expect(Alerty::Config.log_level).to eql('fatal') }
|
32
38
|
it { expect(Alerty::Config.timeout).to eql(20) }
|
33
39
|
it { expect(Alerty::Config.lock_path).to eql('/tmp/lock') }
|
40
|
+
it { expect(Alerty::Config.retry_limit).to eql(5) }
|
41
|
+
it { expect(Alerty::Config.retry_wait).to eql(10) }
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#retry_interval' do
|
45
|
+
before do
|
46
|
+
Alerty::Config.configure(
|
47
|
+
retry_wait: 10,
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
it do
|
52
|
+
# retry_wait +/- 12.5% randomness
|
53
|
+
expect(Alerty::Config.retry_interval).to be >= 10 - 1.25
|
54
|
+
expect(Alerty::Config.retry_interval).to be <= 10 + 1.25
|
55
|
+
end
|
34
56
|
end
|
35
57
|
|
36
58
|
describe 'plugins' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alerty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -175,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
175
|
version: '0'
|
176
176
|
requirements: []
|
177
177
|
rubyforge_project:
|
178
|
-
rubygems_version: 2.
|
178
|
+
rubygems_version: 2.4.5
|
179
179
|
signing_key:
|
180
180
|
specification_version: 4
|
181
181
|
summary: Send an alert if a given command failed
|