prometheus-splash 0.1.0 → 0.1.1
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/README.md +31 -1
- data/bin/splash +6 -364
- data/lib/splash/backends.rb +1 -0
- data/lib/splash/backends/file.rb +1 -0
- data/lib/splash/backends/redis.rb +1 -3
- data/lib/splash/cli.rb +20 -0
- data/lib/splash/cli/commands.rb +164 -0
- data/lib/splash/cli/config.rb +37 -0
- data/lib/splash/cli/daemon.rb +52 -0
- data/lib/splash/cli/documentation.rb +24 -0
- data/lib/splash/cli/logs.rb +72 -0
- data/lib/splash/commands.rb +10 -15
- data/lib/splash/config.rb +7 -9
- data/lib/splash/constants.rb +2 -1
- data/lib/splash/controller.rb +12 -24
- data/lib/splash/dependencies.rb +51 -0
- data/lib/splash/exiter.rb +52 -0
- data/lib/splash/helpers.rb +2 -8
- data/lib/splash/logs.rb +4 -5
- data/lib/splash/orchestrator.rb +4 -5
- data/lib/splash/templates.rb +1 -0
- data/lib/splash/transports.rb +1 -0
- data/lib/splash/transports/rabbitmq.rb +1 -4
- data/prometheus-splash.gemspec +3 -1
- metadata +38 -2
data/lib/splash/cli.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
Dir[File.dirname(__FILE__) + '/cli/*.rb'].each {|file| require file }
|
3
|
+
|
4
|
+
class CLI < Thor
|
5
|
+
def self.exit_on_failure?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
|
9
|
+
include CLISplash
|
10
|
+
desc "commands SUBCOMMAND ...ARGS", "Managing commands/batchs supervision"
|
11
|
+
subcommand "commands", Commands
|
12
|
+
desc "logs SUBCOMMAND ...ARGS", "Managing Files/Logs supervision"
|
13
|
+
subcommand "logs", Logs
|
14
|
+
desc "daemon SUBCOMMAND ...ARGS", "Logs monitor daemon contoller"
|
15
|
+
subcommand "daemon", CLIController
|
16
|
+
desc "config SUBCOMMAND ...ARGS", "config tools for Splash"
|
17
|
+
subcommand "config", Config
|
18
|
+
desc "documentation SUBCOMMAND ...ARGS", "Documentation for Splash"
|
19
|
+
subcommand "documentation", Documentation
|
20
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module CLISplash
|
3
|
+
|
4
|
+
|
5
|
+
class Commands < Thor
|
6
|
+
include Splash::Config
|
7
|
+
include Splash::Backends
|
8
|
+
include Splash::Exiter
|
9
|
+
|
10
|
+
desc "execute NAME", "run for command/sequence or ack result"
|
11
|
+
long_desc <<-LONGDESC
|
12
|
+
execute command or sequence or ack result
|
13
|
+
with --no-trace prevent storing execution trace in configured backend (see config file)
|
14
|
+
with --ack, notify errorcode=0 to Prometheus PushGateway
|
15
|
+
with --no-notify, bypass Prometheus notification
|
16
|
+
with --no-callback, never execute callback (:on_failure, :on_success)
|
17
|
+
never follow sequences
|
18
|
+
LONGDESC
|
19
|
+
option :trace, :type => :boolean, :default => true
|
20
|
+
option :ack, :type => :boolean, negate: false
|
21
|
+
option :notify, :type => :boolean, :default => true
|
22
|
+
option :callback, :type => :boolean, :default => true
|
23
|
+
def execute(name)
|
24
|
+
if is_root? then
|
25
|
+
command = Splash::CommandWrapper::new(name)
|
26
|
+
if options[:ack] then
|
27
|
+
splash_exit command.ack
|
28
|
+
end
|
29
|
+
acase = command.call_and_notify trace: options[:trace], notify: options[:notify], callback: options[:callback]
|
30
|
+
splash_exit acase
|
31
|
+
else
|
32
|
+
splash_exit case: :not_root, :more => "Command execution"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
desc "treeview", "Show commands sequence tree"
|
38
|
+
def treeview(command, depht = 0)
|
39
|
+
puts "Command : #{command.to_s}" if depht == 0
|
40
|
+
cmd = get_config.commands[command.to_sym]
|
41
|
+
if cmd[:on_failure] then
|
42
|
+
print " " * depht + " "
|
43
|
+
puts "* on failure => #{cmd[:on_failure]}"
|
44
|
+
treeview(cmd[:on_failure], depht+2)
|
45
|
+
end
|
46
|
+
if cmd[:on_success] then
|
47
|
+
print " " * depht + " "
|
48
|
+
puts "* on success => #{cmd[:on_success]}"
|
49
|
+
treeview(cmd[:on_success],depht+2)
|
50
|
+
end
|
51
|
+
splash_exit case: :quiet_exit
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
desc "list", "Show configured commands"
|
56
|
+
long_desc <<-LONGDESC
|
57
|
+
Show configured commands
|
58
|
+
with --detail, show command details
|
59
|
+
LONGDESC
|
60
|
+
option :detail, :type => :boolean
|
61
|
+
def list
|
62
|
+
puts "Splash configured commands :"
|
63
|
+
list = get_config.commands
|
64
|
+
puts 'No configured commands found' if list.keys.empty?
|
65
|
+
list.keys.each do |command|
|
66
|
+
puts " * #{command.to_s}"
|
67
|
+
if options[:detail] then
|
68
|
+
puts " - command line : '#{list[command][:command]}'"
|
69
|
+
puts " - command description : '#{list[command][:desc]}'"
|
70
|
+
puts " - command failure callback : '#{list[command.to_sym][:on_failure]}'" if list[command.to_sym][:on_failure]
|
71
|
+
puts " - command success callback : '#{list[command.to_sym][:on_success]}'" if list[command.to_sym][:on_success]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
splash_exit case: :quiet_exit
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
desc "show COMMAND", "Show specific configured command COMMAND"
|
79
|
+
def show(command)
|
80
|
+
list = get_config.commands
|
81
|
+
if list.keys.include? command.to_sym then
|
82
|
+
puts "Splash command : #{command}"
|
83
|
+
puts " - command line : '#{list[command.to_sym][:command]}'"
|
84
|
+
puts " - command description : '#{list[command.to_sym][:desc]}'"
|
85
|
+
puts " - command failure callback : '#{list[command.to_sym][:on_failure]}'" if list[command.to_sym][:on_failure]
|
86
|
+
puts " - command success callback : '#{list[command.to_sym][:on_success]}'" if list[command.to_sym][:on_success]
|
87
|
+
splash_exit case: :quiet_exit
|
88
|
+
else
|
89
|
+
splash_exit case: :not_found, :more => 'Command not configured'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
desc "lastrun COMMAND", "Show last running result for specific configured command COMMAND"
|
95
|
+
long_desc <<-LONGDESC
|
96
|
+
Show last running result for specific configured command COMMAND
|
97
|
+
with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)
|
98
|
+
LONGDESC
|
99
|
+
option :hostname, :type => :string
|
100
|
+
def lastrun(command)
|
101
|
+
backend = get_backend :execution_trace
|
102
|
+
redis = (backend.class == Splash::Backends::Redis)? true : false
|
103
|
+
if not redis and options[:hostname] then
|
104
|
+
splash_exit case: :specific_config_required, :more => "Redis backend is requiered for Remote execution report request"
|
105
|
+
end
|
106
|
+
list = get_config.commands
|
107
|
+
if list.keys.include? command.to_sym then
|
108
|
+
print "Splash command #{command} previous execution report:\n\n"
|
109
|
+
req = { :key => command}
|
110
|
+
req[:hostname] = options[:hostname] if options[:hostname]
|
111
|
+
if backend.exist? req then
|
112
|
+
print backend.get req
|
113
|
+
else
|
114
|
+
puts "Command not already runned."
|
115
|
+
end
|
116
|
+
splash_exit case: :quiet_exit
|
117
|
+
else
|
118
|
+
splash_exit case: :command_not_configured
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "getreportlist", "list all executions report results "
|
123
|
+
long_desc <<-LONGDESC
|
124
|
+
list all executions report results
|
125
|
+
with --pattern <SEARCH>, search type string, wilcard * (group) ? (char)\n
|
126
|
+
with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)\n
|
127
|
+
with --all, get all execution report for all servers (only with Redis backend configured)\n
|
128
|
+
--all and --hostname are exclusives
|
129
|
+
LONGDESC
|
130
|
+
option :pattern, :type => :string
|
131
|
+
option :hostname, :type => :string
|
132
|
+
option :all, :type => :boolean, :negate => false
|
133
|
+
def getreportlist
|
134
|
+
if options[:hostname] and options[:all] then
|
135
|
+
splash_exit case: :options_incompatibility, more: "--all, --hostname"
|
136
|
+
end
|
137
|
+
backend = get_backend :execution_trace
|
138
|
+
redis = (backend.class == Splash::Backends::Redis)? true : false
|
139
|
+
if not redis and (options[:hostname] or options[:all]) then
|
140
|
+
splash_exit case: :redis_back_required, more: "Remote execution report Request"
|
141
|
+
end
|
142
|
+
pattern = (options[:pattern])? options[:pattern] : '*'
|
143
|
+
if options[:all] then
|
144
|
+
res = backend.listall pattern
|
145
|
+
elsif options[:hostname]
|
146
|
+
res = backend.list pattern, options[:hostname]
|
147
|
+
else
|
148
|
+
res = backend.list pattern
|
149
|
+
end
|
150
|
+
print "List of Executions reports :\n\n"
|
151
|
+
puts "Not reports found" if res.empty?
|
152
|
+
res.each do |item|
|
153
|
+
if options[:all]
|
154
|
+
host,command = item.split('#')
|
155
|
+
puts " * Command : #{command} @ host : #{host}"
|
156
|
+
else
|
157
|
+
puts " * Command : #{item}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
splash_exit case: :quiet_exit
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module CLISplash
|
3
|
+
|
4
|
+
class Config < Thor
|
5
|
+
include Splash::Config
|
6
|
+
include Splash::Helpers
|
7
|
+
include Splash::Exiter
|
8
|
+
|
9
|
+
|
10
|
+
desc "setup", "Setup installation fo Splash"
|
11
|
+
long_desc <<-LONGDESC
|
12
|
+
Setup installation fo Splash
|
13
|
+
with --preserve, preserve from reinstallation of the config
|
14
|
+
LONGDESC
|
15
|
+
option :preserve, :type => :boolean
|
16
|
+
def setup
|
17
|
+
acase = run_as_root :setupsplash
|
18
|
+
splash_exit acase
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "sanitycheck", "Verify installation fo Splash"
|
22
|
+
def sanitycheck
|
23
|
+
acase = run_as_root :checkconfig
|
24
|
+
splash_exit acase
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "version", "display current Splash version"
|
28
|
+
def version
|
29
|
+
config = get_config
|
30
|
+
puts "Splash version : #{config.version}, Author : #{config.author}"
|
31
|
+
puts config.copyright
|
32
|
+
splash_exit case: :quiet_exit
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module CLISplash
|
3
|
+
|
4
|
+
class CLIController < Thor
|
5
|
+
include Splash::LogsMonitor::DaemonController
|
6
|
+
include Splash::Transports
|
7
|
+
include Splash::Exiter
|
8
|
+
|
9
|
+
|
10
|
+
option :foreground, :type => :boolean
|
11
|
+
desc "start", "Starting Logs Monitor Daemon"
|
12
|
+
def start
|
13
|
+
acase = run_as_root :startdaemon
|
14
|
+
splash_exit acase
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "stop", "Stopping Logs Monitor Daemon"
|
18
|
+
def stop
|
19
|
+
acase = run_as_root :stopdaemon
|
20
|
+
splash_exit acase
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "status", "Logs Monitor Daemon status"
|
24
|
+
def status
|
25
|
+
acase = run_as_root :statusdaemon
|
26
|
+
splash_exit acase
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "ping HOSTNAME", "send a ping to HOSTNAME daemon over transport (need an active tranport), Typicallly RabbitMQ"
|
30
|
+
def ping(hostname=Socket.gethostname)
|
31
|
+
puts "ctrl+c for interrupt"
|
32
|
+
queue = "splash.#{Socket.gethostname}.returncli"
|
33
|
+
order = {:verb => :ping, :payload => {:hostname => Socket.gethostname}, :return_to => queue}
|
34
|
+
|
35
|
+
lock = Mutex.new
|
36
|
+
condition = ConditionVariable.new
|
37
|
+
begin
|
38
|
+
get_default_subscriber(queue: queue).subscribe(timeout: 10) do |delivery_info, properties, payload|
|
39
|
+
puts YAML::load(payload)
|
40
|
+
lock.synchronize { condition.signal }
|
41
|
+
end
|
42
|
+
get_default_client.publish queue: "splash.#{hostname}.input", message: order.to_yaml
|
43
|
+
lock.synchronize { condition.wait(lock) }
|
44
|
+
splash_exit case: :quiet_exit
|
45
|
+
rescue Interrupt
|
46
|
+
splash_exit status: :error, case: :interrupt, more: "Ping Command"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module CLISplash
|
3
|
+
|
4
|
+
class Documentation < Thor
|
5
|
+
include Splash::Config
|
6
|
+
include Splash::Exiter
|
7
|
+
|
8
|
+
|
9
|
+
desc "readme", "Display README file"
|
10
|
+
option :formatted, :type => :boolean, :default => true
|
11
|
+
def readme
|
12
|
+
filename = search_file_in_gem("prometheus-splash","README.md")
|
13
|
+
|
14
|
+
if options[:formatted] then
|
15
|
+
content = TTY::Markdown.parse_file(filename)
|
16
|
+
else
|
17
|
+
conten = File::readlines(filename).join
|
18
|
+
end
|
19
|
+
pager = TTY::Pager.new
|
20
|
+
pager.page(content)
|
21
|
+
splash_exit case: :quiet_exit
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module CLISplash
|
3
|
+
|
4
|
+
class Logs < Thor
|
5
|
+
include Splash::Config
|
6
|
+
include Splash::Exiter
|
7
|
+
|
8
|
+
|
9
|
+
desc "analyse", "analyze logs in config"
|
10
|
+
def analyse
|
11
|
+
results = Splash::LogScanner::new
|
12
|
+
res = results.analyse
|
13
|
+
puts "SPlash Configured logs status :"
|
14
|
+
full_status = true
|
15
|
+
results.output.each do |result|
|
16
|
+
status = (result[:status] == :clean)? "OK": "KO"
|
17
|
+
puts " * Log : #{result[:log]} : [#{status}]"
|
18
|
+
puts " - Detected pattern : #{result[:pattern]}"
|
19
|
+
puts " - detailled Status : #{result[:status].to_s}"
|
20
|
+
puts " count = #{result[:count]}" if result[:status] == :matched
|
21
|
+
puts " nb lines = #{result[:lines]}" if result[:status] != :missing
|
22
|
+
full_status = false unless result[:status] == :clean
|
23
|
+
end
|
24
|
+
display_status = (full_status)? "OK": "KO"
|
25
|
+
puts "Global Status : [#{display_status}]"
|
26
|
+
splash_exit case: :quiet_exit
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "monitor", "monitor logs in config"
|
30
|
+
def monitor
|
31
|
+
result = Splash::LogScanner::new
|
32
|
+
result.analyse
|
33
|
+
result.notify
|
34
|
+
splash_exit result.notify
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "show LOG", "show configured log monitoring for LOG"
|
39
|
+
def show(log)
|
40
|
+
log_record_set = get_config.logs.select{|item| item[:log] == log }
|
41
|
+
unless log_record_set.empty? then
|
42
|
+
record = log_record_set.first
|
43
|
+
puts "Splash log monitor : #{record[:log]}"
|
44
|
+
puts " -> pattern : /#{record[:pattern]}/"
|
45
|
+
splash_exit case: :quiet_exit
|
46
|
+
else
|
47
|
+
splash_exit case: :not_found, :more => "log not configured"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "list", "Show configured logs monitoring"
|
52
|
+
long_desc <<-LONGDESC
|
53
|
+
Show configured logs monitoring
|
54
|
+
with --detail, show logs monitor details
|
55
|
+
LONGDESC
|
56
|
+
option :detail, :type => :boolean
|
57
|
+
def list
|
58
|
+
puts "Splash configured log monitoring :"
|
59
|
+
log_record_set = get_config.logs
|
60
|
+
puts 'No configured commands found' if log_record_set.empty?
|
61
|
+
log_record_set.each do |record|
|
62
|
+
puts " * log monitor : #{record[:log]}"
|
63
|
+
if options[:detail] then
|
64
|
+
puts " -> pattern : /#{record[:pattern]}/"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
splash_exit case: :quiet_exit
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/lib/splash/commands.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
|
-
|
2
|
-
require 'date'
|
3
|
-
require 'socket'
|
4
|
-
|
1
|
+
# coding: utf-8
|
5
2
|
module Splash
|
6
3
|
class CommandWrapper
|
7
4
|
include Splash::Templates
|
8
5
|
include Splash::Config
|
9
6
|
include Splash::Helpers
|
10
7
|
include Splash::Backends
|
8
|
+
include Splash::Exiter
|
11
9
|
|
12
10
|
def initialize(name)
|
13
11
|
@config = get_config
|
14
12
|
@name = name
|
15
13
|
unless @config.commands.keys.include? @name.to_sym then
|
16
|
-
|
17
|
-
exit 40
|
14
|
+
splash_exit case: :not_found, more: "command #{@name} is not defined in configuration"
|
18
15
|
end
|
19
16
|
@registry = Prometheus::Client.registry
|
20
17
|
@url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
|
@@ -26,26 +23,25 @@ module Splash
|
|
26
23
|
|
27
24
|
def ack
|
28
25
|
puts "Sending ack for command : '#{@name}'"
|
29
|
-
notify(0)
|
30
|
-
exit 0
|
26
|
+
notify(0,0)
|
31
27
|
end
|
32
28
|
|
33
29
|
def notify(value,time)
|
34
30
|
unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
|
35
|
-
|
36
|
-
$stderr.puts "Exit without notification."
|
37
|
-
exit 30
|
31
|
+
return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
|
38
32
|
end
|
39
33
|
@metric_exitcode.set(value)
|
40
34
|
@metric_time.set(time)
|
41
35
|
hostname = Socket.gethostname
|
42
36
|
Prometheus::Client::Push.new(@name, hostname, @url).add(@registry)
|
43
37
|
puts " * Prometheus Gateway notified."
|
38
|
+
return { :case => :quiet_exit}
|
44
39
|
end
|
45
40
|
|
46
41
|
|
47
42
|
def call_and_notify(options)
|
48
43
|
puts "Executing command : '#{@name}' "
|
44
|
+
acase = { :case => :quiet_exit }
|
49
45
|
start = Time.now
|
50
46
|
start_date = DateTime.now.to_s
|
51
47
|
unless options[:trace] then
|
@@ -89,7 +85,7 @@ module Splash
|
|
89
85
|
|
90
86
|
puts " => exitcode #{exit_code}"
|
91
87
|
if options[:notify] then
|
92
|
-
notify(exit_code,time.to_i)
|
88
|
+
acase = notify(exit_code,time.to_i)
|
93
89
|
else
|
94
90
|
puts " * Without Prometheus notification"
|
95
91
|
end
|
@@ -103,7 +99,7 @@ module Splash
|
|
103
99
|
@name = on_failure.to_s
|
104
100
|
call_and_notify options
|
105
101
|
else
|
106
|
-
|
102
|
+
acase = { :case => :configuration_error , :more => "on_failure call error : #{on_failure} command inexistant."}
|
107
103
|
end
|
108
104
|
end
|
109
105
|
if on_success and exit_code == 0 then
|
@@ -118,8 +114,7 @@ module Splash
|
|
118
114
|
else
|
119
115
|
puts " * Without callbacks sequences"
|
120
116
|
end
|
121
|
-
|
122
|
-
exit exit_code
|
117
|
+
return acase
|
123
118
|
end
|
124
119
|
end
|
125
120
|
end
|