deimos 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +18 -0
- data/README.md +73 -4
- data/deimos.gemspec +3 -0
- data/lib/deimos/endpoints/metrics.rb +11 -0
- data/lib/deimos/endpoints/status.rb +17 -0
- data/lib/deimos/metrics/manager.rb +48 -0
- data/lib/deimos/status/manager.rb +21 -0
- data/lib/deimos/status/runner.rb +30 -0
- data/lib/deimos/version.rb +1 -1
- data/lib/deimos.rb +47 -10
- metadata +49 -4
- data/lib/deimos/manager.rb +0 -17
- data/lib/deimos/status.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15cc6372bc401ffa051316be8573fd8066b5f1749753679d680459c8846a394d
|
4
|
+
data.tar.gz: 504c5872e4c5c71ebd1f269075667589697fd3e20b95e6f10461e01fb2d8009a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 115bd70bb83642e7e58eeb5fd79856a0c1bb42390f879898ae015d0180bd81770ef6eb9499af239b1dc0ed6c90330f175abd4176a8b0b61834d1603e5dc83075
|
7
|
+
data.tar.gz: 4bf4b534367761779afc0c359cd5081c308d7245049b4a8c28fd953ef1d7a332d3d4af32e45098221f96a86a32ae94e2e8f02238b53fb635572a38668bbb6da9
|
data/Gemfile.lock
CHANGED
@@ -2,23 +2,38 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
deimos (0.1.0)
|
5
|
+
activesupport
|
6
|
+
concurrent-ruby
|
5
7
|
huyegger
|
8
|
+
prometheus-client
|
6
9
|
sinatra
|
7
10
|
sinatra-contrib
|
8
11
|
|
9
12
|
GEM
|
10
13
|
remote: https://rubygems.org/
|
11
14
|
specs:
|
15
|
+
activesupport (5.2.2)
|
16
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
+
i18n (>= 0.7, < 2)
|
18
|
+
minitest (~> 5.1)
|
19
|
+
tzinfo (~> 1.1)
|
12
20
|
backports (3.12.0)
|
13
21
|
coderay (1.1.2)
|
22
|
+
concurrent-ruby (1.1.4)
|
14
23
|
diff-lcs (1.3)
|
15
24
|
huyegger (0.4.4)
|
25
|
+
i18n (1.6.0)
|
26
|
+
concurrent-ruby (~> 1.0)
|
16
27
|
method_source (0.9.2)
|
28
|
+
minitest (5.11.3)
|
17
29
|
multi_json (1.13.1)
|
18
30
|
mustermann (1.0.3)
|
31
|
+
prometheus-client (0.9.0)
|
32
|
+
quantile (~> 0.2.1)
|
19
33
|
pry (0.12.2)
|
20
34
|
coderay (~> 1.1.0)
|
21
35
|
method_source (~> 0.9.0)
|
36
|
+
quantile (0.2.1)
|
22
37
|
rack (2.0.6)
|
23
38
|
rack-protection (2.0.5)
|
24
39
|
rack
|
@@ -48,7 +63,10 @@ GEM
|
|
48
63
|
rack-protection (= 2.0.5)
|
49
64
|
sinatra (= 2.0.5)
|
50
65
|
tilt (>= 1.3, < 3)
|
66
|
+
thread_safe (0.3.6)
|
51
67
|
tilt (2.0.9)
|
68
|
+
tzinfo (1.2.5)
|
69
|
+
thread_safe (~> 0.1)
|
52
70
|
|
53
71
|
PLATFORMS
|
54
72
|
ruby
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Deimos
|
2
2
|
|
3
|
-
|
3
|
+
Deimos is an application designed to be run alongside Phobos, but can be run in any context to provide a unified status and metrics interface for kubernetes style applications.
|
4
4
|
|
5
|
-
|
5
|
+
## Name
|
6
|
+
|
7
|
+
Deimos, brother of Phobos, from Greek mythology. The personification of dread and terror. Also it is the other natural Martian satelite, the first being Phobos
|
6
8
|
|
7
9
|
## Installation
|
8
10
|
|
@@ -22,7 +24,74 @@ Or install it yourself as:
|
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
|
-
|
27
|
+
### Configuration
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
Deimos.configure do |config|
|
31
|
+
config.log_level = ENV.fetch("LOG_LEVEL", ::Logger::INFO)
|
32
|
+
config.port = ENV.fetch("PORT", 5000)
|
33
|
+
config.bind = ENV.fetch("BIND_IP", "0.0.0.0")
|
34
|
+
# An application hash that allows you to add more rack apps
|
35
|
+
# Doesn't override the defaults, just merges
|
36
|
+
config.applications.merge('/path' => Rack::App.new)
|
37
|
+
# Allows you to inject more middlewares into the application
|
38
|
+
config.applications.middleware << Middleware
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
### Status
|
43
|
+
|
44
|
+
Deimos allows you to add as many status checks are you like, however the API expects a true or false response. Any false responses from the bound blocks will return an `internal_server_error`
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
Deimos.status.add(:allocations) { AllocationService::Status.new.call }
|
48
|
+
Deimos.status.add(:another_check) { true }
|
49
|
+
```
|
50
|
+
```json
|
51
|
+
# GET /status
|
52
|
+
{ "allocations":true, "another_check":true }
|
53
|
+
```
|
54
|
+
|
55
|
+
Status checks are run in parallel.
|
56
|
+
|
57
|
+
|
58
|
+
### Metrics
|
59
|
+
|
60
|
+
Deimos uses `ActiveSupport::Notification` and `Prometheus` under the hood.
|
61
|
+
|
62
|
+
#### Subscribing
|
63
|
+
|
64
|
+
The subsription takes, three required arguments and a block.
|
65
|
+
* The event name to subscribe to
|
66
|
+
* The type of collector
|
67
|
+
* The prometheus label
|
68
|
+
|
69
|
+
It also takes any extra keyword arguments and passes them to the collector, allowing you to specify extra options for each type of collector
|
70
|
+
|
71
|
+
* [Prometheus Collectors](https://github.com/prometheus/client_ruby#metrics)
|
72
|
+
* [ActiveSupport Notifications](https://api.rubyonrails.org/classes/ActiveSupport/Notifications.html)
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
Deimos.metrics.subscribe('event.name', type: :gauge, label: 'Label') do |event, collector|
|
76
|
+
collector.increment({}, event.payload[:value])
|
77
|
+
# event is an ActiveSupport::Notification::Event
|
78
|
+
# event.name # => "render"
|
79
|
+
# event.duration # => 10 (in milliseconds)
|
80
|
+
# event.payload # => {some: :payload}
|
81
|
+
|
82
|
+
# collector is a Prometheus::Client::#{type.classify}
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
#### Instrumenting
|
87
|
+
|
88
|
+
`Deimos.metrics.instrument` delegates directly to `ActiveSupport::Notifications.instrument`, please see the [ActiveSupport Notifications](https://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) documentation for more information
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Deimos.metrics.instrument('product_count', value: 10 + i) do
|
92
|
+
# can wrap a block to give you code execution duration
|
93
|
+
end
|
94
|
+
```
|
26
95
|
|
27
96
|
## Development
|
28
97
|
|
@@ -32,7 +101,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
101
|
|
33
102
|
## Contributing
|
34
103
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
104
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/adamcarlile/deimos.
|
36
105
|
|
37
106
|
## License
|
38
107
|
|
data/deimos.gemspec
CHANGED
@@ -23,6 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "sinatra"
|
24
24
|
spec.add_dependency "sinatra-contrib"
|
25
25
|
spec.add_dependency "huyegger"
|
26
|
+
spec.add_dependency "concurrent-ruby"
|
27
|
+
spec.add_dependency "prometheus-client"
|
28
|
+
spec.add_dependency "activesupport"
|
26
29
|
|
27
30
|
spec.add_development_dependency "bundler", "~> 1.16"
|
28
31
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Deimos
|
2
|
+
module Endpoints
|
3
|
+
class Status < Sinatra::Application
|
4
|
+
disable :logging
|
5
|
+
set :logger, Deimos.logger
|
6
|
+
|
7
|
+
get "/" do
|
8
|
+
status_runner = Deimos.status.run!
|
9
|
+
|
10
|
+
content_type :json
|
11
|
+
status status_runner.status
|
12
|
+
status_runner.body
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Deimos
|
2
|
+
module Metrics
|
3
|
+
class Manager
|
4
|
+
TYPES = {
|
5
|
+
counter: Prometheus::Client::Counter,
|
6
|
+
gauge: Prometheus::Client::Gauge,
|
7
|
+
histogram: Prometheus::Client::Histogram,
|
8
|
+
summary: Prometheus::Client::Summary
|
9
|
+
}
|
10
|
+
|
11
|
+
delegate :instrument, to: ActiveSupport::Notifications
|
12
|
+
|
13
|
+
def subscriptions
|
14
|
+
@subscriptions ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def collectors
|
18
|
+
@collectors ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def registry
|
22
|
+
@registry ||= Prometheus::Client.registry
|
23
|
+
end
|
24
|
+
|
25
|
+
def subscribe(event_name, type:, label:, **kwargs, &block)
|
26
|
+
Deimos.logger.info "Metrics: Subscribed to #{event_name}..."
|
27
|
+
subscriptions << ActiveSupport::Notifications.subscribe(event_name) do |*args|
|
28
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
29
|
+
collector = register_collector!(event_name, type, label, kwargs)
|
30
|
+
if block_given?
|
31
|
+
yield(event, collector)
|
32
|
+
else
|
33
|
+
Deimos.logger.info event
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def register_collector!(event_name, type, about, **kwargs)
|
41
|
+
return collectors[event_name] if collectors[event_name].present?
|
42
|
+
name = event_name.gsub(".", "_").to_sym
|
43
|
+
collectors[event_name] = TYPES[type].new(name, about, kwargs).tap { |x| registry.register(x) }
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Deimos
|
2
|
+
module Status
|
3
|
+
class Manager
|
4
|
+
|
5
|
+
attr_reader :checks
|
6
|
+
def checks
|
7
|
+
@checks ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(name, &block)
|
11
|
+
Deimos.logger.info "Status: Reporting #{name} status..."
|
12
|
+
|
13
|
+
checks[name] = block || Proc.new { true }
|
14
|
+
end
|
15
|
+
|
16
|
+
def run!
|
17
|
+
Deimos::Status::Runner.new(checks)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Deimos
|
2
|
+
module Status
|
3
|
+
class Runner
|
4
|
+
def initialize(checks)
|
5
|
+
@checks = checks.dup
|
6
|
+
end
|
7
|
+
|
8
|
+
def status
|
9
|
+
ok? ? :ok : :internal_server_error
|
10
|
+
end
|
11
|
+
|
12
|
+
def body
|
13
|
+
completed_checks.to_json
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def ok?
|
19
|
+
completed_checks.values.all?
|
20
|
+
end
|
21
|
+
|
22
|
+
def completed_checks
|
23
|
+
@completed_checks ||= @checks.transform_values do |function|
|
24
|
+
Concurrent::Promises.future(&function)
|
25
|
+
end.transform_values(&:value)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/deimos/version.rb
CHANGED
data/lib/deimos.rb
CHANGED
@@ -1,27 +1,53 @@
|
|
1
|
+
require 'rack'
|
1
2
|
require 'huyegger'
|
2
3
|
require 'sinatra'
|
4
|
+
require 'active_support'
|
3
5
|
require 'sinatra/contrib'
|
6
|
+
require "sinatra/json"
|
4
7
|
require 'webrick'
|
5
8
|
require 'logger'
|
9
|
+
require 'webrick'
|
10
|
+
require 'concurrent-ruby'
|
11
|
+
require 'prometheus/client'
|
12
|
+
require 'prometheus/middleware/exporter'
|
6
13
|
|
7
14
|
require "deimos/version"
|
8
15
|
|
9
16
|
require 'deimos/logger'
|
10
|
-
require 'deimos/
|
17
|
+
require 'deimos/status/runner'
|
18
|
+
require 'deimos/status/manager'
|
19
|
+
require 'deimos/metrics/manager'
|
11
20
|
|
12
21
|
module Deimos
|
13
22
|
module_function
|
14
23
|
|
15
24
|
def boot!
|
16
|
-
require 'deimos/status'
|
17
|
-
|
25
|
+
require 'deimos/endpoints/status'
|
26
|
+
require 'deimos/endpoints/metrics'
|
27
|
+
Thread.new do
|
28
|
+
::Rack::Handler::WEBrick.run(application, {
|
29
|
+
BindAddress: Deimos.config.bind,
|
30
|
+
Port: Deimos.config.port,
|
31
|
+
Logger: Deimos.logger,
|
32
|
+
AccessLog: []
|
33
|
+
})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def application
|
38
|
+
Rack::Builder.new do
|
39
|
+
Deimos.middleware.each { |m| use m }
|
40
|
+
run Rack::URLMap.new(Deimos.applications)
|
41
|
+
end
|
18
42
|
end
|
19
43
|
|
20
44
|
def config
|
21
45
|
@config ||= OpenStruct.new.tap do |x|
|
22
|
-
x.log_level
|
23
|
-
x.port
|
24
|
-
x.bind
|
46
|
+
x.log_level = ENV.fetch("LOG_LEVEL", ::Logger::INFO)
|
47
|
+
x.port = ENV.fetch("PORT", 5000)
|
48
|
+
x.bind = ENV.fetch("BIND_IP", "0.0.0.0")
|
49
|
+
x.applications = {}
|
50
|
+
x.middleware = []
|
25
51
|
end
|
26
52
|
end
|
27
53
|
|
@@ -29,12 +55,23 @@ module Deimos
|
|
29
55
|
yield(config)
|
30
56
|
end
|
31
57
|
|
32
|
-
def
|
33
|
-
@
|
58
|
+
def middleware
|
59
|
+
@middleware ||= [Rack::Deflater, Deimos::Logger] | config.middleware
|
60
|
+
end
|
61
|
+
|
62
|
+
def applications
|
63
|
+
@applications ||= {
|
64
|
+
"/status" => Deimos::Endpoints::Status,
|
65
|
+
"/metrics" => Deimos::Endpoints::Metrics
|
66
|
+
}.merge(config.applications)
|
67
|
+
end
|
68
|
+
|
69
|
+
def status
|
70
|
+
@status ||= Deimos::Status::Manager.new
|
34
71
|
end
|
35
72
|
|
36
|
-
def
|
37
|
-
|
73
|
+
def metrics
|
74
|
+
@metrics ||= Deimos::Metrics::Manager.new
|
38
75
|
end
|
39
76
|
|
40
77
|
def logger
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deimos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Carlile
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -52,6 +52,48 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: concurrent-ruby
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: prometheus-client
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activesupport
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: bundler
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -127,9 +169,12 @@ files:
|
|
127
169
|
- bin/setup
|
128
170
|
- deimos.gemspec
|
129
171
|
- lib/deimos.rb
|
172
|
+
- lib/deimos/endpoints/metrics.rb
|
173
|
+
- lib/deimos/endpoints/status.rb
|
130
174
|
- lib/deimos/logger.rb
|
131
|
-
- lib/deimos/manager.rb
|
132
|
-
- lib/deimos/status.rb
|
175
|
+
- lib/deimos/metrics/manager.rb
|
176
|
+
- lib/deimos/status/manager.rb
|
177
|
+
- lib/deimos/status/runner.rb
|
133
178
|
- lib/deimos/version.rb
|
134
179
|
homepage: https://github.com/adamcarlile/deimos
|
135
180
|
licenses:
|
data/lib/deimos/manager.rb
DELETED
data/lib/deimos/status.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require "sinatra/base"
|
2
|
-
require "sinatra/json"
|
3
|
-
require 'webrick'
|
4
|
-
|
5
|
-
# Sinatra Applicaiton to present basic health check endpoint
|
6
|
-
module Deimos
|
7
|
-
class Status < Sinatra::Application
|
8
|
-
|
9
|
-
set :bind, Deimos.config.bind
|
10
|
-
set :port, Deimos.config.port
|
11
|
-
disable :show_exceptions, :traps, :logging
|
12
|
-
|
13
|
-
use Deimos::Logger
|
14
|
-
|
15
|
-
set :quiet, true
|
16
|
-
set :logger, Deimos.logger
|
17
|
-
set :server, :webrick
|
18
|
-
set :server_settings,
|
19
|
-
Logger: Deimos.logger,
|
20
|
-
AccessLog: []
|
21
|
-
|
22
|
-
get "/status" do
|
23
|
-
content_type :json
|
24
|
-
Deimos.manager.call
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|