litmus_paper 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -0
- data/lib/litmus_paper/app.rb +14 -1
- data/lib/litmus_paper/cache.rb +33 -0
- data/lib/litmus_paper/configuration.rb +8 -1
- data/lib/litmus_paper/configuration_file.rb +17 -1
- data/lib/litmus_paper/version.rb +1 -1
- data/lib/litmus_paper.rb +2 -1
- data/release +11 -0
- data/spec/litmus_paper/app_spec.rb +40 -1
- data/spec/litmus_paper/cache_spec.rb +74 -0
- data/spec/litmus_paper/configuration_file_spec.rb +12 -0
- data/spec/support/test.config +3 -0
- data/spec/support/test.reload.config +3 -0
- metadata +6 -2
data/README.md
CHANGED
data/lib/litmus_paper/app.rb
CHANGED
@@ -34,7 +34,12 @@ module LitmusPaper
|
|
34
34
|
end
|
35
35
|
|
36
36
|
get "/:service/status" do
|
37
|
-
health =
|
37
|
+
health = _cache.get(params[:service])
|
38
|
+
_cache.set(
|
39
|
+
params[:service],
|
40
|
+
health = LitmusPaper.check_service(params[:service])
|
41
|
+
) unless health
|
42
|
+
|
38
43
|
if health.nil?
|
39
44
|
_text 404, "NOT FOUND", { "X-Health" => "0" }
|
40
45
|
else
|
@@ -100,6 +105,14 @@ module LitmusPaper
|
|
100
105
|
_text 500, "Server Error"
|
101
106
|
end
|
102
107
|
|
108
|
+
def _cache
|
109
|
+
@cache ||= LitmusPaper::Cache.new(
|
110
|
+
LitmusPaper.cache_location,
|
111
|
+
"litmus_cache",
|
112
|
+
LitmusPaper.cache_ttl
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
103
116
|
def _create_status_file(status_file)
|
104
117
|
status_file.create(params[:reason], params[:health])
|
105
118
|
_text 201, "File created"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module LitmusPaper
|
4
|
+
class Cache
|
5
|
+
def initialize(location, namespace, ttl)
|
6
|
+
@path = File.join(location, namespace)
|
7
|
+
@ttl = ttl
|
8
|
+
|
9
|
+
FileUtils.mkdir_p(@path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def set(key, value)
|
13
|
+
return unless @ttl > 0
|
14
|
+
File.open(File.join(@path, key), "a") do |f|
|
15
|
+
f.flock(File::LOCK_EX)
|
16
|
+
f.rewind
|
17
|
+
f.write("#{Time.now.to_f + @ttl} #{YAML::dump(value)}")
|
18
|
+
f.flush
|
19
|
+
f.truncate(f.pos)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(key)
|
24
|
+
return unless File.exists?(File.join(@path, key))
|
25
|
+
File.open(File.join(@path, key), "r") do |f|
|
26
|
+
f.flock(File::LOCK_SH)
|
27
|
+
entry = f.read
|
28
|
+
expires_at, value = entry.split(" ", 2)
|
29
|
+
expires_at.to_f < Time.now.to_f ? nil : YAML::load(value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -5,13 +5,21 @@ module LitmusPaper
|
|
5
5
|
@services = {}
|
6
6
|
@port = 9292
|
7
7
|
@data_directory = "/etc/litmus"
|
8
|
+
@cache_location = "/run/shm"
|
9
|
+
@cache_ttl = -1
|
8
10
|
end
|
9
11
|
|
10
12
|
def evaluate(file = @config_file_path)
|
11
13
|
LitmusPaper.logger.info "Loading file #{file}"
|
12
14
|
config_contents = File.read(file)
|
13
15
|
instance_eval(config_contents)
|
14
|
-
LitmusPaper::Configuration.new(
|
16
|
+
LitmusPaper::Configuration.new(
|
17
|
+
@port,
|
18
|
+
@data_directory,
|
19
|
+
@services,
|
20
|
+
@cache_location,
|
21
|
+
@cache_ttl
|
22
|
+
)
|
15
23
|
end
|
16
24
|
|
17
25
|
def include_files(glob_pattern)
|
@@ -36,5 +44,13 @@ module LitmusPaper
|
|
36
44
|
block.call(service)
|
37
45
|
@services[name.to_s] = service
|
38
46
|
end
|
47
|
+
|
48
|
+
def cache_location(location)
|
49
|
+
@cache_location = location
|
50
|
+
end
|
51
|
+
|
52
|
+
def cache_ttl(ttl)
|
53
|
+
@cache_ttl = ttl
|
54
|
+
end
|
39
55
|
end
|
40
56
|
end
|
data/lib/litmus_paper/version.rb
CHANGED
data/lib/litmus_paper.rb
CHANGED
@@ -14,6 +14,7 @@ require 'forwardable'
|
|
14
14
|
|
15
15
|
require 'remote_syslog_logger'
|
16
16
|
|
17
|
+
require 'litmus_paper/cache'
|
17
18
|
require 'litmus_paper/configuration'
|
18
19
|
require 'litmus_paper/configuration_file'
|
19
20
|
require 'litmus_paper/dependency/file_contents'
|
@@ -35,7 +36,7 @@ require 'litmus_paper/version'
|
|
35
36
|
module LitmusPaper
|
36
37
|
class << self
|
37
38
|
extend Forwardable
|
38
|
-
def_delegators :@config, :services, :data_directory, :port
|
39
|
+
def_delegators :@config, :services, :data_directory, :port, :cache_location, :cache_ttl
|
39
40
|
attr_accessor :logger
|
40
41
|
end
|
41
42
|
|
data/release
ADDED
@@ -272,7 +272,7 @@ describe LitmusPaper::App do
|
|
272
272
|
last_response.header["X-Health-Forced"].should == "health"
|
273
273
|
end
|
274
274
|
|
275
|
-
it "returns the
|
275
|
+
it "returns the actual health value for an unhealthy service when the measured health is less than the forced value" do
|
276
276
|
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
|
277
277
|
LitmusPaper.services['test'] = test_service
|
278
278
|
LitmusPaper::StatusFile.service_health_file("test").create("Forcing health", 88)
|
@@ -418,6 +418,45 @@ describe LitmusPaper::App do
|
|
418
418
|
last_response.headers["X-Health-Forced"].should == "up"
|
419
419
|
last_response.body.should match(/Up for testing/)
|
420
420
|
end
|
421
|
+
|
422
|
+
it "retrieves a cached value during the cache_ttl" do
|
423
|
+
begin
|
424
|
+
cache = LitmusPaper::Cache.new(
|
425
|
+
location = "/tmp/litmus_cache",
|
426
|
+
namespace = "test_cache",
|
427
|
+
ttl = 0.05
|
428
|
+
)
|
429
|
+
LitmusPaper::App.any_instance.stub(:_cache).and_return(cache)
|
430
|
+
test_service = LitmusPaper::Service.new(
|
431
|
+
'test',
|
432
|
+
[AlwaysAvailableDependency.new],
|
433
|
+
[LitmusPaper::Metric::ConstantMetric.new(100)]
|
434
|
+
)
|
435
|
+
LitmusPaper.services['test'] = test_service
|
436
|
+
|
437
|
+
post "/test/health", :reason => "health for testing", :health => 88
|
438
|
+
last_response.status.should == 201
|
439
|
+
|
440
|
+
get "/test/status"
|
441
|
+
last_response.status.should == 200
|
442
|
+
last_response.body.should match(/health for testing 88/)
|
443
|
+
|
444
|
+
delete "/test/health"
|
445
|
+
last_response.status.should == 200
|
446
|
+
|
447
|
+
get "/test/status"
|
448
|
+
last_response.should be_ok
|
449
|
+
last_response.body.should match(/health for testing 88/)
|
450
|
+
|
451
|
+
sleep ttl
|
452
|
+
|
453
|
+
get "/test/status"
|
454
|
+
last_response.should be_ok
|
455
|
+
last_response.body.should_not match(/health for testing 88/)
|
456
|
+
ensure
|
457
|
+
FileUtils.rm_rf(location)
|
458
|
+
end
|
459
|
+
end
|
421
460
|
end
|
422
461
|
|
423
462
|
describe "server errors" do
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Cache do
|
4
|
+
before(:each) do
|
5
|
+
@location = "/tmp/litmus_cache"
|
6
|
+
@namespace = "test_cache"
|
7
|
+
@ttl = -1
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:each) do
|
11
|
+
FileUtils.rm_rf(@location)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "initialize" do
|
15
|
+
it "creates the directory structure" do
|
16
|
+
File.exists?(@location).should be false
|
17
|
+
LitmusPaper::Cache.new(@location, @namespace, @ttl)
|
18
|
+
File.exists?(File.join(@location, @namespace)).should be true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "get" do
|
23
|
+
it "returns false if the key was not previously set" do
|
24
|
+
cache = LitmusPaper::Cache.new(@location, @namespace, @ttl)
|
25
|
+
cache.get("non-existant-key").should be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when called with fresh entry" do
|
29
|
+
it "returns the value set" do
|
30
|
+
cache = LitmusPaper::Cache.new(@location, @namespace, 10)
|
31
|
+
cache.set("key", "some value")
|
32
|
+
cache.get("key").should == "some value"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when called with expired entry" do
|
37
|
+
it "returns nil" do
|
38
|
+
cache = LitmusPaper::Cache.new(@location, @namespace, -1)
|
39
|
+
cache.set("key", "some value")
|
40
|
+
cache.get("key").should be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "set" do
|
46
|
+
context "when called with non-positive ttl" do
|
47
|
+
it "does not store the value" do
|
48
|
+
key = "key"
|
49
|
+
cache = LitmusPaper::Cache.new(@location, @namespace, 0)
|
50
|
+
cache.set(key, "some value")
|
51
|
+
File.exists?(File.join(@location, @namespace, key)).should be false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when called with positive ttl" do
|
56
|
+
it "stores the value" do
|
57
|
+
key = "key"
|
58
|
+
cache = LitmusPaper::Cache.new(@location, @namespace, 1)
|
59
|
+
cache.set(key, "some value")
|
60
|
+
File.exists?(File.join(@location, @namespace, key)).should be true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "expires the entry after the ttl" do
|
65
|
+
key = "key"
|
66
|
+
ttl = 0.01
|
67
|
+
cache = LitmusPaper::Cache.new(@location, @namespace, ttl)
|
68
|
+
cache.set(key, "some value")
|
69
|
+
cache.get(key).should == "some value"
|
70
|
+
sleep ttl
|
71
|
+
cache.get(key).should be_nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -19,6 +19,18 @@ describe LitmusPaper::ConfigurationFile do
|
|
19
19
|
config = config_file.evaluate
|
20
20
|
config.data_directory.should == "/tmp/litmus_paper"
|
21
21
|
end
|
22
|
+
|
23
|
+
it "configures the cache_location" do
|
24
|
+
config_file = LitmusPaper::ConfigurationFile.new(TEST_CONFIG)
|
25
|
+
config = config_file.evaluate
|
26
|
+
config.cache_location.should == "/tmp/litmus_paper_cache"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "configures the cache_ttl" do
|
30
|
+
config_file = LitmusPaper::ConfigurationFile.new(TEST_CONFIG)
|
31
|
+
config = config_file.evaluate
|
32
|
+
config.cache_ttl.should == -1
|
33
|
+
end
|
22
34
|
end
|
23
35
|
|
24
36
|
describe "include_files" do
|
data/spec/support/test.config
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: litmus_paper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-12-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
@@ -165,6 +165,7 @@ files:
|
|
165
165
|
- lib/litmus_paper/agent_check_handler.rb
|
166
166
|
- lib/litmus_paper/agent_check_server.rb
|
167
167
|
- lib/litmus_paper/app.rb
|
168
|
+
- lib/litmus_paper/cache.rb
|
168
169
|
- lib/litmus_paper/cli/admin.rb
|
169
170
|
- lib/litmus_paper/cli/admin/command.rb
|
170
171
|
- lib/litmus_paper/cli/admin/force.rb
|
@@ -192,9 +193,11 @@ files:
|
|
192
193
|
- lib/litmus_paper/version.rb
|
193
194
|
- litmus-agent-check.init.sh
|
194
195
|
- litmus_paper.gemspec
|
196
|
+
- release
|
195
197
|
- spec/litmus_paper/agent_check_handler_spec.rb
|
196
198
|
- spec/litmus_paper/agent_check_server_spec.rb
|
197
199
|
- spec/litmus_paper/app_spec.rb
|
200
|
+
- spec/litmus_paper/cache_spec.rb
|
198
201
|
- spec/litmus_paper/cli/admin_spec.rb
|
199
202
|
- spec/litmus_paper/configuration_file_spec.rb
|
200
203
|
- spec/litmus_paper/dependency/file_contents_spec.rb
|
@@ -255,6 +258,7 @@ test_files:
|
|
255
258
|
- spec/litmus_paper/agent_check_handler_spec.rb
|
256
259
|
- spec/litmus_paper/agent_check_server_spec.rb
|
257
260
|
- spec/litmus_paper/app_spec.rb
|
261
|
+
- spec/litmus_paper/cache_spec.rb
|
258
262
|
- spec/litmus_paper/cli/admin_spec.rb
|
259
263
|
- spec/litmus_paper/configuration_file_spec.rb
|
260
264
|
- spec/litmus_paper/dependency/file_contents_spec.rb
|