prometheus-splash 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +58 -60
  3. data/bin/splash +3 -0
  4. data/config/splash.yml +15 -2
  5. data/lib/splash/backends.rb +6 -0
  6. data/lib/splash/backends/file.rb +36 -0
  7. data/lib/splash/backends/redis.rb +44 -1
  8. data/lib/splash/cli.rb +7 -3
  9. data/lib/splash/cli/commands.rb +11 -4
  10. data/lib/splash/cli/config.rb +9 -1
  11. data/lib/splash/cli/daemon.rb +8 -1
  12. data/lib/splash/cli/documentation.rb +5 -2
  13. data/lib/splash/cli/logs.rb +14 -6
  14. data/lib/splash/cli/process.rb +9 -0
  15. data/lib/splash/cli/webadmin.rb +46 -0
  16. data/lib/splash/commands.rb +23 -2
  17. data/lib/splash/config.rb +141 -1
  18. data/lib/splash/config/flush.rb +9 -1
  19. data/lib/splash/config/sanitycheck.rb +6 -1
  20. data/lib/splash/config/service.rb +8 -1
  21. data/lib/splash/config/setup.rb +8 -3
  22. data/lib/splash/constants.rb +30 -2
  23. data/lib/splash/daemon.rb +5 -1
  24. data/lib/splash/daemon/controller.rb +21 -1
  25. data/lib/splash/daemon/metrics.rb +22 -7
  26. data/lib/splash/daemon/orchestrator.rb +21 -3
  27. data/lib/splash/daemon/orchestrator/grammar.rb +25 -5
  28. data/lib/splash/daemon/orchestrator/hooks.rb +10 -0
  29. data/lib/splash/dependencies.rb +10 -1
  30. data/lib/splash/exiter.rb +14 -0
  31. data/lib/splash/helpers.rb +69 -45
  32. data/lib/splash/loggers.rb +30 -4
  33. data/lib/splash/loggers/cli.rb +18 -3
  34. data/lib/splash/loggers/daemon.rb +14 -3
  35. data/lib/splash/loggers/dual.rb +14 -1
  36. data/lib/splash/loggers/web.rb +51 -0
  37. data/lib/splash/logs.rb +15 -4
  38. data/lib/splash/processes.rb +17 -5
  39. data/lib/splash/templates.rb +10 -0
  40. data/lib/splash/transports.rb +9 -0
  41. data/lib/splash/transports/rabbitmq.rb +33 -3
  42. data/lib/splash/webadmin.rb +122 -0
  43. data/lib/splash/webadmin/api/routes/commands.rb +28 -0
  44. data/lib/splash/webadmin/api/routes/config.rb +10 -0
  45. data/lib/splash/webadmin/api/routes/init.rb +2 -0
  46. data/lib/splash/webadmin/api/routes/logs.rb +59 -0
  47. data/lib/splash/webadmin/api/routes/process.rb +60 -0
  48. data/lib/splash/webadmin/main.rb +26 -0
  49. data/lib/splash/webadmin/portal/controllers/commands.rb +7 -0
  50. data/lib/splash/webadmin/portal/controllers/documentation.rb +6 -0
  51. data/lib/splash/webadmin/portal/controllers/home.rb +12 -0
  52. data/lib/splash/webadmin/portal/controllers/logs.rb +14 -0
  53. data/lib/splash/webadmin/portal/controllers/notfound.rb +5 -0
  54. data/lib/splash/webadmin/portal/controllers/processes.rb +14 -0
  55. data/lib/splash/webadmin/portal/controllers/proxy.rb +30 -0
  56. data/lib/splash/webadmin/portal/controllers/restclient.rb +19 -0
  57. data/lib/splash/webadmin/portal/init.rb +11 -0
  58. data/lib/splash/webadmin/portal/public/css/ultragreen.css +8544 -0
  59. data/lib/splash/webadmin/portal/public/fonts/FontAwesome.otf +0 -0
  60. data/lib/splash/webadmin/portal/public/fonts/fontawesome-webfont.ttf +0 -0
  61. data/lib/splash/webadmin/portal/public/fonts/fontawesome-webfont.woff +0 -0
  62. data/lib/splash/webadmin/portal/public/fonts/fontawesome-webfont.woff2 +0 -0
  63. data/lib/splash/webadmin/portal/public/images/logo_splash.png +0 -0
  64. data/lib/splash/webadmin/portal/public/images/logo_splash_reduce.png +0 -0
  65. data/lib/splash/webadmin/portal/public/images/logo_splash_tiny.png +0 -0
  66. data/lib/splash/webadmin/portal/views/commands.slim +49 -0
  67. data/lib/splash/webadmin/portal/views/documentation.slim +3 -0
  68. data/lib/splash/webadmin/portal/views/home.slim +78 -0
  69. data/lib/splash/webadmin/portal/views/layout.slim +43 -0
  70. data/lib/splash/webadmin/portal/views/logs.slim +32 -0
  71. data/lib/splash/webadmin/portal/views/nav.slim +17 -0
  72. data/lib/splash/webadmin/portal/views/not_found.slim +3 -0
  73. data/lib/splash/webadmin/portal/views/processes.slim +29 -0
  74. data/lib/splash/webadmin/portal/views/proxy.slim +13 -0
  75. data/lib/splash/webadmin/portal/views/restclient.slim +41 -0
  76. data/lib/splash/webadmin/portal/views/restclient_result.slim +29 -0
  77. data/prometheus-splash.gemspec +6 -0
  78. data/spec/helpers_spec.rb +119 -0
  79. metadata +128 -5
@@ -1,12 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ # base Splash module
1
4
  module Splash
5
+
6
+ # Splash Loggers module
2
7
  module Loggers
3
8
 
9
+ # Dual multiplexer specific logger
10
+ # log against CLi and Daemon
4
11
  class Dual #< Splash::Loggers::LoggerTemplate
5
12
 
6
13
 
7
14
  include Splash::Config
8
15
 
9
-
16
+ # build levels and alias forwarders
10
17
  LEVELS.each do |method|
11
18
  define_method(method) do |message,session = ''|
12
19
  self.log({ :level => method, :message => message, :session => session})
@@ -18,6 +25,7 @@ module Splash
18
25
  end
19
26
  end
20
27
 
28
+ # Constructor build two attributes for each loggers : Cli, Daemon
21
29
  def initialize
22
30
  super
23
31
  @log1 = Splash::Loggers::Cli::new
@@ -28,10 +36,15 @@ module Splash
28
36
  @log1.log options
29
37
  @log2.log options
30
38
  end
39
+
40
+ # getter for root level
41
+ # @return [Symbol] a level
31
42
  def level
32
43
  @level
33
44
  end
34
45
 
46
+ # setter for global level, both Cli and Daemon
47
+ # @param [Symbol] level a level in Splash::Loggers::LEVELS or Splash::Loggers::ALIAS
35
48
  def level=(level)
36
49
  @level = level
37
50
  @log1.level=level
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+
3
+ # base Splash module
4
+ module Splash
5
+
6
+ # Splash Loggers module
7
+ module Loggers
8
+
9
+ # Web specific logger
10
+ class Web < Splash::Loggers::LoggerTemplate
11
+
12
+
13
+ # contructor, open log file
14
+ # @return [Splash::Loggers::Web]
15
+ def initialize
16
+ self.level = get_config.loggers[:level]
17
+ @log_file = get_config.loggers[:web][:file]
18
+ @stream = File::open(@log_file, 'a')
19
+ @stream.sync = true
20
+ end
21
+
22
+ # log wrapper
23
+ # @param [Hash] options
24
+ # @option options [Symbol] :level defined in Splash::Loggers::LEVEL or Splash::Loggers::ALIAS
25
+ # @option options [String] :message
26
+ # @option options [String] :session a session number
27
+ # write formatted string to log file
28
+ def log(options)
29
+ pid = Process.pid.to_s
30
+ date = DateTime.now.to_s
31
+ level = (ALIAS.keys.include? options[:level])? ALIAS[options[:level]] : options[:level]
32
+ if @active_levels.include? level then
33
+ unless options[:session].empty? then
34
+ @stream.puts "[#{date}] (#{pid}) (#{options[:session]}) #{alt(options[:level])} : #{options[:message]}"
35
+ else
36
+ @stream.puts "[#{date}] (#{pid}) #{alt(options[:level])} : #{options[:message]}"
37
+ end
38
+ end
39
+ end
40
+
41
+ # close log file descriptor
42
+ def close
43
+ @stream.close
44
+ end
45
+
46
+
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -1,15 +1,21 @@
1
1
  # coding: utf-8
2
+
3
+ # base Splash module
2
4
  module Splash
5
+
6
+ # Logs namespace
3
7
  module Logs
8
+
9
+ # Log scanner and notifier
4
10
  class LogScanner
5
11
  include Splash::Constants
6
12
  include Splash::Config
7
13
 
8
14
 
9
- # LogScanner Constructor
10
- # return [LogScanner]
15
+ # LogScanner Constructor : initialize prometheus metrics
16
+ # return [Splash::Logs::LogScanner]
11
17
  def initialize
12
- @logs_target = get_config.logs
18
+ @logs_target = Marshal.load(Marshal.dump(get_config.logs))
13
19
  @config = get_config
14
20
  @registry = Prometheus::Client::Registry::new
15
21
  @metric_count = Prometheus::Client::Gauge.new(:logerrors, docstring: 'SPLASH metric log error', labels: [:log ])
@@ -22,6 +28,7 @@ module Splash
22
28
 
23
29
 
24
30
  # start log analyse for log target in config
31
+ # @return [Hash] Exiter case :quiet_exit
25
32
  def analyse
26
33
  @logs_target.each do |record|
27
34
  record[:count]=0 if record[:count].nil?
@@ -38,11 +45,15 @@ module Splash
38
45
  end
39
46
 
40
47
  # pseudo-accessor on @logs_target
48
+ # @return [Hash] the logs structure
41
49
  def output
42
50
  return @logs_target
43
51
  end
44
52
 
45
53
  # start notification on prometheus for metric logerrors, logmissing; loglines
54
+ # @param [Hash] options
55
+ # @option options [String] :session a session number for log daemon
56
+ # @return [Hash] Exiter case :quiet_exit
46
57
  def notify(options = {})
47
58
  log = get_logger
48
59
  unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
@@ -59,7 +70,7 @@ module Splash
59
70
  @metric_lines.set(lines, labels: { log: item[:log] })
60
71
  end
61
72
  hostname = Socket.gethostname
62
- url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
73
+ url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}/#{@config.prometheus_pushgateway_path}"
63
74
  Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
64
75
  log.ok "Sending to Prometheus PushGateway done.", session
65
76
  return {:case => :quiet_exit }
@@ -1,14 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ # base Splash Module
1
4
  module Splash
5
+
6
+ # Processes namespace
2
7
  module Processes
8
+
9
+ # Processes scanner and notifier
3
10
  class ProcessScanner
4
11
  include Splash::Constants
5
12
  include Splash::Config
6
13
 
7
14
 
8
- # LogScanner Constructor
9
- # return [LogScanner]
15
+ # ProcessScanner Constructor : initialize prometheus metrics
16
+ # @return [Splash::Processes::ProcessScanner]
10
17
  def initialize
11
- @processes_target = get_config.processes
18
+ @processes_target = Marshal.load(Marshal.dump(get_config.processes))
12
19
  @config = get_config
13
20
  @registry = Prometheus::Client::Registry::new
14
21
  @metric_status = Prometheus::Client::Gauge.new(:process_status, docstring: 'SPLASH metric process status', labels: [:process ])
@@ -21,7 +28,8 @@ module Splash
21
28
  end
22
29
 
23
30
 
24
- # start log analyse for log target in config
31
+ # start process analyse for process target in config
32
+ # @return [Hash] Exiter case :quiet_exit
25
33
  def analyse
26
34
  @processes_target.each do |record|
27
35
  list = get_processes patterns: record[:patterns], full: true
@@ -39,11 +47,15 @@ module Splash
39
47
  end
40
48
 
41
49
  # pseudo-accessor on @processes_target
50
+ # @return [Hash] the processes structure
42
51
  def output
43
52
  return @processes_target
44
53
  end
45
54
 
46
55
  # start notification on prometheus for metrics
56
+ # @param [Hash] options
57
+ # @option options [String] :session a session number for log daemon
58
+ # @return [Hash] Exiter case :quiet_exit
47
59
  def notify(options = {})
48
60
  log = get_logger
49
61
  unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
@@ -60,7 +72,7 @@ module Splash
60
72
  @metric_mem_percent.set(item[:mem], labels: { process: item[:process] })
61
73
  end
62
74
  hostname = Socket.gethostname
63
- url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
75
+ url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}/#{@config.prometheus_pushgateway_path}"
64
76
  Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
65
77
  log.ok "Sending to Prometheus PushGateway done.", session
66
78
  return {:case => :quiet_exit }
@@ -1,12 +1,19 @@
1
1
  # coding: utf-8
2
+
3
+ # base Splash Module
2
4
  module Splash
5
+
6
+ # Templates namespace
3
7
  module Templates
4
8
 
5
9
  # KISS template Engine
6
10
  class Template
7
11
 
12
+ # getter of the list of token
8
13
  attr_reader :list_token
14
+ # getter of the template file
9
15
  attr_reader :template_file
16
+ # getter of the flat content of the template
10
17
  attr_reader :content
11
18
 
12
19
  # constructor : generate the pseudo accessor for template Class from token list
@@ -72,8 +79,11 @@ module Splash
72
79
 
73
80
  end
74
81
 
82
+ # Exception for an invalid Token list
75
83
  class InvalidTokenList < Exception; end
84
+ # Exception for an malformed token
76
85
  class NotAToken < Exception; end
86
+ # Exception for an invalid template file
77
87
  class NoTemplateFile < Exception; end
78
88
 
79
89
  end
@@ -1,9 +1,16 @@
1
1
  # coding: utf-8
2
2
 
3
+ # base Splash module
3
4
  module Splash
5
+
6
+ # Splash Transports namespace
4
7
  module Transports
5
8
  include Splash::Config
6
9
 
10
+
11
+ # factory for Splash::Transports::Rabbitmq::Subscriber
12
+ # @param [Hash] options
13
+ # @return [Splash::Transports::Rabbitmq::Subscriber|Hash] Subscriber or Exiter case :configuration_error
7
14
  def get_default_subscriber(options)
8
15
  config = get_config.transports
9
16
  transport = config[:active]
@@ -20,6 +27,8 @@ module Splash
20
27
  end
21
28
  end
22
29
 
30
+ # factory for Splash::Transports::Rabbitmq::Client
31
+ # @return [Splash::Transports::Rabbitmq::Client|Hash] Client or Exiter case :configuration_error
23
32
  def get_default_client
24
33
  config = get_config.transports
25
34
  transport = config[:active]
@@ -1,14 +1,24 @@
1
1
  # coding: utf-8
2
+
3
+ # base Splash module
2
4
  module Splash
5
+
6
+ # Splash Transports namespace
3
7
  module Transports
8
+
9
+ # RabbitMQ Transport
4
10
  module Rabbitmq
5
11
 
12
+ # Subscriber Mode RabbitMQ Client
6
13
  class Subscriber
7
14
  include Splash::Config
8
15
  extend Forwardable
9
16
 
10
17
  def_delegators :@queue, :subscribe
11
18
 
19
+ # Constructor Forward subscribe method and initialize a Bunny Client atribute @queue
20
+ # @param [Hash] options
21
+ # @option options [String] :queue the name of the subscribed queue
12
22
  def initialize(options = {})
13
23
  @config = get_config.transports
14
24
 
@@ -32,12 +42,13 @@ module Splash
32
42
 
33
43
  end
34
44
 
35
-
45
+ # publish / get Mode RabbitMQ Client
36
46
  class Client
37
47
  include Splash::Config
38
48
  include Splash::Transports
39
49
  include Splash::Loggers
40
50
 
51
+ # Constructor initialize a Bunny Client
41
52
  def initialize
42
53
  @config = get_config.transports
43
54
  host = @config[:rabbitmq][:host]
@@ -48,7 +59,7 @@ module Splash
48
59
  conf = { :host => host, :vhost => vhost, :user => user, :password => passwd, :port => port.to_i}
49
60
 
50
61
  begin
51
- @connection = Bunny.new conf
62
+ @connection = Bunny.new conf
52
63
  @connection.start
53
64
  @channel = @connection.create_channel
54
65
  rescue Bunny::Exception
@@ -56,19 +67,32 @@ module Splash
56
67
  end
57
68
  end
58
69
 
59
-
70
+ # purge a queue
71
+ # @param [Hash] options
72
+ # @option options [String] :queue the name of the queue to purge
60
73
  def purge(options)
61
74
  @channel.queue(options[:queue]).purge
62
75
  end
63
76
 
77
+ # publish to a queue
78
+ # @param [Hash] options
79
+ # @option options [String] :queue the name of the queue to purge
80
+ # @option options [String] :message the message to send
64
81
  def publish(options ={})
65
82
  return @channel.default_exchange.publish(options[:message], :routing_key => options[:queue])
66
83
  end
67
84
 
85
+ # ack a specific message for manual ack with a delivery tag to a queue
86
+ # @param [String] ack
87
+ # @return [Boolean]
68
88
  def ack(ack)
69
89
  return @channel.acknowledge(ack, false)
70
90
  end
71
91
 
92
+
93
+ # send an execution order message (verb+payload) via RabbitMQ to an slash input queue
94
+ # @param [Hash] order
95
+ # @return [Void] unserialized Void object from YAML
72
96
  def execute(order)
73
97
  queue = order[:return_to]
74
98
  lock = Mutex.new
@@ -85,6 +109,11 @@ module Splash
85
109
  return res
86
110
  end
87
111
 
112
+ # Get a message from a RabbitMQ queue
113
+ # @param [Hash] options
114
+ # @option options [String] :queue the name of the queue to query
115
+ # @option options [String] :manual_ack flag to inhibit ack
116
+ # @return [Hash] Payload + ack tag if :manual_ack
88
117
  def get(options ={})
89
118
  queue = @channel.queue(options[:queue])
90
119
  opt = {}; opt[:manual_ack] = (options[:manual_ack])? true : false
@@ -94,6 +123,7 @@ module Splash
94
123
  return res
95
124
  end
96
125
 
126
+ # close the RabbitMQ connection
97
127
  def close
98
128
  @connection.close
99
129
  end
@@ -0,0 +1,122 @@
1
+ # coding: utf-8
2
+
3
+
4
+
5
+ # base Splash module
6
+ module Splash
7
+
8
+ # global daemon module
9
+ module WebAdmin
10
+
11
+ # Daemon Controller Module
12
+ module Controller
13
+ include Splash::Constants
14
+ include Splash::Helpers
15
+ include Splash::Config
16
+ include Splash::Exiter
17
+ include Splash::Loggers
18
+
19
+
20
+ # Start the Splash Daemon
21
+ # @param [Hash] options
22
+ # @option options [Symbol] :quiet activate quiet mode for log (limit to :fatal)
23
+ # @return [Hash] Exiter Case (:quiet_exit, :already_exist, :unknown_error or other)
24
+ def startdaemon(options = {})
25
+ require 'splash/webadmin/main'
26
+ config = get_config
27
+ log = get_logger
28
+ log.level = :fatal if options[:quiet]
29
+ realpid = get_processes pattern: get_config.webadmin_process_name
30
+
31
+
32
+ unless File::exist? config.full_pid_path then
33
+ unless realpid.empty? then
34
+ return {:case => :already_exist, :more => "Splash WebAdmin Process already launched "}
35
+ end
36
+
37
+ daemon_config = {:description => config.webadmin_process_name,
38
+ :pid_file => config.webadmin_full_pid_path,
39
+ :stdout_trace => config.webadmin_full_stdout_trace_path,
40
+ :stderr_trace => config.webadmin_full_stderr_trace_path
41
+ }
42
+
43
+ ["int","term","hup"].each do |type| daemon_config["sig#{type}_handler".to_sym] = Proc::new { WebAdminApp.quit! } end
44
+ res = daemonize daemon_config do
45
+ log = get_logger logger: :web, force: true
46
+ log.info "Starting Splash WebAdmin"
47
+ WebAdminApp.run!
48
+ end
49
+ sleep 1
50
+ if res == 0 then
51
+ pid = `cat #{config.webadmin_full_pid_path}`.to_i
52
+ log.ok "Splash WebAdmin Started, with PID : #{pid}"
53
+ return {:case => :quiet_exit, :more => "Splash WebAdmin successfully loaded."}
54
+ else
55
+ return {:case => :unknown_error, :more => "Splash WebAdmin loading error, see logs for more details."}
56
+ end
57
+
58
+ else
59
+ return {:case => :already_exist, :more => "Pid File, please verify if Splash WebAdmin is running."}
60
+ end
61
+ end
62
+
63
+ # Stop the Splash WebAdmin
64
+ # @param [Hash] options
65
+ # @option options [Symbol] :quiet activate quiet mode for log (limit to :fatal)
66
+ # @return [Hash] Exiter Case (:quiet_exit, :not_found, other)
67
+ def stopdaemon(options = {})
68
+ config = get_config
69
+ log = get_logger
70
+ log.level = :fatal if options[:quiet]
71
+ if File.exist?(config.webadmin_full_pid_path) then
72
+ begin
73
+ pid = `cat #{config.webadmin_full_pid_path}`.to_i
74
+ Process.kill("TERM", pid)
75
+ acase = {:case => :quiet_exit, :more => 'Splash WebAdmin stopped succesfully'}
76
+ rescue Errno::ESRCH
77
+ acase = {:case => :not_found, :more => "Process of PID : #{pid} not found"}
78
+ end
79
+ FileUtils::rm config.webadmin_full_pid_path if File::exist? config.webadmin_full_pid_path
80
+ else
81
+ acase = {:case => :not_found, :more => "Splash WebAdmin is not running"}
82
+ end
83
+ return acase
84
+ end
85
+
86
+ # Status of the Splash WebAdmin, display status
87
+ # @param [Hash] options ignored
88
+ # @return [Hash] Exiter Case (:status_ko, :status_ok)
89
+ def statusdaemon(options = {})
90
+ log = get_logger
91
+ config = get_config
92
+ pid = realpid = ''
93
+ pid = `cat #{config.webadmin_full_pid_path}`.to_s if File.exist?(config.webadmin_full_pid_path)
94
+ listpid = get_processes({ :pattern => get_config.webadmin_process_name})
95
+ pid.chomp!
96
+ if listpid.empty? then
97
+ realpid = ''
98
+ else
99
+ realpid = listpid.first
100
+ end
101
+ unless realpid.empty? then
102
+ log.item "Splash WebAdmin Process is running with PID #{realpid} "
103
+ else
104
+ log.item 'Splash WebAdminProcess not found '
105
+ end
106
+ unless pid.empty? then
107
+ log.item "and PID file exist with PID #{pid}"
108
+ else
109
+ log.item "and PID file don't exist"
110
+ end
111
+ if pid == realpid then
112
+ return {:case => :status_ok }
113
+ elsif pid.empty? then
114
+ return {:case => :status_ko, :more => "PID File error, you have to kill process manualy, with : '(sudo )kill -TERM #{realpid}'"}
115
+ elsif realpid.empty? then
116
+ return {:case => :status_ko, :more => "Process Splash WebAdmin missing, run 'splash webadmin stop' before reload properly"}
117
+ end
118
+ end
119
+
120
+ end
121
+ end
122
+ end