litmus_paper 1.0.0 → 1.1.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/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
|