prometheus-splash 0.8.0 → 0.8.5

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -3
  3. data/README.md +400 -178
  4. data/config/splash.yml +28 -14
  5. data/lib/splash/backends.rb +7 -1
  6. data/lib/splash/backends/file.rb +1 -1
  7. data/lib/splash/cli/commands.rb +122 -37
  8. data/lib/splash/cli/config.rb +12 -1
  9. data/lib/splash/cli/daemon.rb +1 -1
  10. data/lib/splash/cli/logs.rb +144 -48
  11. data/lib/splash/cli/process.rb +145 -52
  12. data/lib/splash/cli/transfers.rb +10 -3
  13. data/lib/splash/commands.rb +115 -40
  14. data/lib/splash/config.rb +112 -29
  15. data/lib/splash/config/flush.rb +2 -2
  16. data/lib/splash/constants.rb +3 -4
  17. data/lib/splash/daemon/orchestrator.rb +6 -7
  18. data/lib/splash/daemon/orchestrator/grammar.rb +1 -1
  19. data/lib/splash/dependencies.rb +1 -0
  20. data/lib/splash/exiter.rb +1 -1
  21. data/lib/splash/helpers.rb +1 -1
  22. data/lib/splash/logs.rb +94 -16
  23. data/lib/splash/monkeys.rb +5 -0
  24. data/lib/splash/processes.rb +91 -16
  25. data/lib/splash/sequences.rb +6 -1
  26. data/lib/splash/transfers.rb +13 -8
  27. data/lib/splash/webadmin/api/routes/commands.rb +15 -3
  28. data/lib/splash/webadmin/api/routes/config.rb +140 -2
  29. data/lib/splash/webadmin/api/routes/logs.rb +32 -17
  30. data/lib/splash/webadmin/api/routes/process.rb +21 -9
  31. data/lib/splash/webadmin/api/routes/sequences.rb +2 -2
  32. data/lib/splash/webadmin/main.rb +15 -1
  33. data/lib/splash/webadmin/portal/controllers/commands.rb +101 -1
  34. data/lib/splash/webadmin/portal/controllers/documentation.rb +2 -0
  35. data/lib/splash/webadmin/portal/controllers/home.rb +6 -1
  36. data/lib/splash/webadmin/portal/controllers/logs.rb +71 -1
  37. data/lib/splash/webadmin/portal/controllers/processes.rb +75 -3
  38. data/lib/splash/webadmin/portal/controllers/proxy.rb +2 -1
  39. data/lib/splash/webadmin/portal/controllers/restclient.rb +6 -1
  40. data/lib/splash/webadmin/portal/controllers/sequences.rb +2 -0
  41. data/lib/splash/webadmin/portal/public/css/ultragreen.css +6 -0
  42. data/lib/splash/webadmin/portal/public/favicon.ico +0 -0
  43. data/lib/splash/webadmin/portal/views/command_form.slim +45 -0
  44. data/lib/splash/webadmin/portal/views/command_history.slim +27 -0
  45. data/lib/splash/webadmin/portal/views/commands.slim +70 -20
  46. data/lib/splash/webadmin/portal/views/documentation.slim +1 -1
  47. data/lib/splash/webadmin/portal/views/home.slim +19 -20
  48. data/lib/splash/webadmin/portal/views/layout.slim +2 -2
  49. data/lib/splash/webadmin/portal/views/log_form.slim +27 -0
  50. data/lib/splash/webadmin/portal/views/log_history.slim +24 -0
  51. data/lib/splash/webadmin/portal/views/logs.slim +95 -21
  52. data/lib/splash/webadmin/portal/views/nav.slim +1 -1
  53. data/lib/splash/webadmin/portal/views/not_found.slim +1 -1
  54. data/lib/splash/webadmin/portal/views/process_form.slim +24 -0
  55. data/lib/splash/webadmin/portal/views/process_history.slim +24 -0
  56. data/lib/splash/webadmin/portal/views/processes.slim +80 -7
  57. data/lib/splash/webadmin/portal/views/proxy.slim +2 -2
  58. data/lib/splash/webadmin/portal/views/restclient.slim +7 -4
  59. data/lib/splash/webadmin/portal/views/restclient_result.slim +24 -20
  60. data/lib/splash/webadmin/portal/views/sequences.slim +1 -1
  61. data/prometheus-splash.gemspec +4 -4
  62. data/ultragreen_roodi_coding_convention.yml +4 -4
  63. metadata +18 -10
@@ -11,58 +11,131 @@ module Splash
11
11
  include Splash::ConfigUtilities
12
12
 
13
13
 
14
+ class ConfigLinter
15
+ def initialize
16
+ @lints_present = {:logs => [:label, :log, :pattern ],
17
+ :processes => [:process, :patterns ],
18
+ :commands => [:name, :desc, :command ]}
19
+ @lints_types = {:logs => {:label => Symbol, :log => String, :pattern => String, :retention => Hash},
20
+ :processes => {:process => Symbol, :patterns => Array, :retention => Hash},
21
+ :commands => {:name => Symbol, :desc => String, :command => String, :schedule => Hash,
22
+ :retention => Hash, :on_failure => Symbol, :on_success => Symbol,
23
+ :user => String, :delegate_to => Hash}}
24
+ end
25
+
26
+ def verify(options ={})
27
+ status = :success
28
+ missings = []
29
+ type_errors = []
30
+ useless = []
31
+ options[:record].each do |key,value|
32
+ useless.push key unless @lints_present[options[:type]].include? key or @lints_types[options[:type]].keys.include? key
33
+ type_errors.push key if @lints_types[options[:type]][key] != value.class and (@lints_present[options[:type]].include? key or @lints_types[options[:type]].keys.include? key)
34
+ end
35
+ @lints_present[options[:type]].each do |item|
36
+ missings.push item unless options[:record].keys.include? item
37
+ end
38
+
39
+ status = :failure if (missings.count > 0) or (type_errors.count > 0)
40
+ return {:missings => missings, :type_errors => type_errors, :useless => useless, :status => status}
41
+ end
42
+
43
+ end
44
+
14
45
  # Class to manage configuration in Splash from Splash::Constants override by Yaml CONFIG
15
46
  class Configuration < Hash
16
47
  include Splash::Constants
17
48
 
49
+ attr_accessor :config_from_file
50
+
18
51
  # constructor : read config file and map against Constants
19
52
  def initialize(config_file=CONFIG_FILE)
20
- config_from_file = readconf config_file
53
+ @config_file = config_file
54
+ hash_config_to_default
55
+
56
+ end
57
+
58
+
59
+ def hash_config_to_default
60
+ @config_from_file = readconf @config_file
21
61
  self[:version] = VERSION
22
62
  self[:author] = "#{AUTHOR} <#{EMAIL}>"
23
63
  self[:copyright] = "#{COPYRIGHT} #{LICENSE}"
24
64
 
25
- self[:prometheus_url] = (config_from_file[:prometheus][:url])? config_from_file[:prometheus][:url] : PROMETHEUS_URL
26
- self[:prometheus_pushgateway_url] = (config_from_file[:prometheus][:pushgateway])? config_from_file[:prometheus][:pushgateway] : PROMETHEUS_PUSHGATEWAY_URL
27
- self[:prometheus_alertmanager_url] = (config_from_file[:prometheus][:alertmanager])? config_from_file[:prometheus][:alertmanager] : PROMETHEUS_ALERTMANAGER_URL
65
+ self[:prometheus_url] = (@config_from_file[:prometheus][:url])? @config_from_file[:prometheus][:url] : PROMETHEUS_URL
66
+ self[:prometheus_pushgateway_url] = (@config_from_file[:prometheus][:pushgateway])? @config_from_file[:prometheus][:pushgateway] : PROMETHEUS_PUSHGATEWAY_URL
67
+ self[:prometheus_alertmanager_url] = (@config_from_file[:prometheus][:alertmanager])? @config_from_file[:prometheus][:alertmanager] : PROMETHEUS_ALERTMANAGER_URL
28
68
 
29
- self[:daemon_process_name] = (config_from_file[:daemon][:process_name])? config_from_file[:daemon][:process_name] : DAEMON_PROCESS_NAME
30
- self[:daemon_logmon_scheduling] = (config_from_file[:daemon][:logmon_scheduling])? config_from_file[:daemon][:logmon_scheduling] : DAEMON_LOGMON_SCHEDULING
31
- self[:daemon_metrics_scheduling] = (config_from_file[:daemon][:metrics_scheduling])? config_from_file[:daemon][:metrics_scheduling] : DAEMON_METRICS_SCHEDULING
32
- self[:daemon_procmon_scheduling] = (config_from_file[:daemon][:procmon_scheduling])? config_from_file[:daemon][:procmon_scheduling] : DAEMON_PROCMON_SCHEDULING
33
- self[:daemon_pid_file] = (config_from_file[:daemon][:files][:pid_file])? config_from_file[:daemon][:files][:pid_file] : DAEMON_PID_FILE
34
- self[:daemon_stdout_trace] = (config_from_file[:daemon][:files][:stdout_trace])? config_from_file[:daemon][:files][:stdout_trace] : DAEMON_STDOUT_TRACE
35
- self[:daemon_stderr_trace] = (config_from_file[:daemon][:files][:stderr_trace])? config_from_file[:daemon][:files][:stderr_trace] : DAEMON_STDERR_TRACE
69
+ self[:daemon_process_name] = (@config_from_file[:daemon][:process_name])? @config_from_file[:daemon][:process_name] : DAEMON_PROCESS_NAME
70
+ self[:daemon_logmon_scheduling] = (@config_from_file[:daemon][:logmon_scheduling])? @config_from_file[:daemon][:logmon_scheduling] : DAEMON_LOGMON_SCHEDULING
71
+ self[:daemon_metrics_scheduling] = (@config_from_file[:daemon][:metrics_scheduling])? @config_from_file[:daemon][:metrics_scheduling] : DAEMON_METRICS_SCHEDULING
72
+ self[:daemon_procmon_scheduling] = (@config_from_file[:daemon][:procmon_scheduling])? @config_from_file[:daemon][:procmon_scheduling] : DAEMON_PROCMON_SCHEDULING
73
+ self[:daemon_pid_file] = (@config_from_file[:daemon][:files][:pid_file])? @config_from_file[:daemon][:files][:pid_file] : DAEMON_PID_FILE
74
+ self[:daemon_stdout_trace] = (@config_from_file[:daemon][:files][:stdout_trace])? @config_from_file[:daemon][:files][:stdout_trace] : DAEMON_STDOUT_TRACE
75
+ self[:daemon_stderr_trace] = (@config_from_file[:daemon][:files][:stderr_trace])? @config_from_file[:daemon][:files][:stderr_trace] : DAEMON_STDERR_TRACE
36
76
 
37
77
 
38
- self[:webadmin_port] = (config_from_file[:webadmin][:port])? config_from_file[:webadmin][:port] : WEBADMIN_PORT
39
- self[:webadmin_ip] = (config_from_file[:webadmin][:ip])? config_from_file[:webadmin][:ip] : WEBADMIN_IP
40
- self[:webadmin_proxy] = (config_from_file[:webadmin][:proxy])? config_from_file[:webadmin][:proxy] : WEBADMIN_PROXY
41
- self[:webadmin_process_name] = (config_from_file[:webadmin][:process_name])? config_from_file[:webadmin][:process_name] : WEBADMIN_PROCESS_NAME
42
- self[:webadmin_pid_file] = (config_from_file[:webadmin][:files][:pid_file])? config_from_file[:webadmin][:files][:pid_file] : WEBADMIN_PID_FILE
43
- self[:webadmin_stdout_trace] = (config_from_file[:webadmin][:files][:stdout_trace])? config_from_file[:webadmin][:files][:stdout_trace] : WEBADMIN_STDOUT_TRACE
44
- self[:webadmin_stderr_trace] = (config_from_file[:webadmin][:files][:stderr_trace])? config_from_file[:webadmin][:files][:stderr_trace] : WEBADMIN_STDERR_TRACE
78
+ self[:webadmin_port] = (@config_from_file[:webadmin][:port])? @config_from_file[:webadmin][:port] : WEBADMIN_PORT
79
+ self[:webadmin_ip] = (@config_from_file[:webadmin][:ip])? @config_from_file[:webadmin][:ip] : WEBADMIN_IP
80
+ self[:webadmin_proxy] = (@config_from_file[:webadmin][:proxy])? @config_from_file[:webadmin][:proxy] : WEBADMIN_PROXY
81
+ self[:webadmin_process_name] = (@config_from_file[:webadmin][:process_name])? @config_from_file[:webadmin][:process_name] : WEBADMIN_PROCESS_NAME
82
+ self[:webadmin_pid_file] = (@config_from_file[:webadmin][:files][:pid_file])? @config_from_file[:webadmin][:files][:pid_file] : WEBADMIN_PID_FILE
83
+ self[:webadmin_stdout_trace] = (@config_from_file[:webadmin][:files][:stdout_trace])? @config_from_file[:webadmin][:files][:stdout_trace] : WEBADMIN_STDOUT_TRACE
84
+ self[:webadmin_stderr_trace] = (@config_from_file[:webadmin][:files][:stderr_trace])? @config_from_file[:webadmin][:files][:stderr_trace] : WEBADMIN_STDERR_TRACE
45
85
 
46
86
 
47
- self[:pid_path] = (config_from_file[:paths][:pid_path])? config_from_file[:paths][:pid_path] : PID_PATH
48
- self[:trace_path] = (config_from_file[:paths][:trace_path])? config_from_file[:paths][:trace_path] : TRACE_PATH
87
+ self[:pid_path] = (@config_from_file[:paths][:pid_path])? @config_from_file[:paths][:pid_path] : PID_PATH
88
+ self[:trace_path] = (@config_from_file[:paths][:trace_path])? @config_from_file[:paths][:trace_path] : TRACE_PATH
49
89
 
50
90
 
51
91
  self[:execution_template_tokens] = EXECUTION_TEMPLATE_TOKENS_LIST
52
- self[:execution_template_path] = (config_from_file[:templates][:execution][:path])? config_from_file[:templates][:execution][:path] : EXECUTION_TEMPLATE
92
+ self[:execution_template_path] = (@config_from_file[:templates][:execution][:path])? @config_from_file[:templates][:execution][:path] : EXECUTION_TEMPLATE
53
93
 
54
- self[:transports] = {} ; self[:transports].merge! TRANSPORTS_STRUCT ; self[:transports].merge! config_from_file[:transports] if config_from_file[:transports]
55
- self[:backends] = {} ; self[:backends].merge! BACKENDS_STRUCT ; self[:backends].merge! config_from_file[:backends] if config_from_file[:backends]
56
- self[:loggers] = {} ; self[:loggers].merge! LOGGERS_STRUCT ; self[:loggers].merge! config_from_file[:loggers] if config_from_file[:loggers]
94
+ self[:transports] = {} ; self[:transports].merge! TRANSPORTS_STRUCT ; self[:transports].merge! @config_from_file[:transports] if @config_from_file[:transports]
95
+ self[:backends] = {} ; self[:backends].merge! BACKENDS_STRUCT ; self[:backends].merge! @config_from_file[:backends] if @config_from_file[:backends]
96
+ self[:loggers] = {} ; self[:loggers].merge! LOGGERS_STRUCT ; self[:loggers].merge! @config_from_file[:loggers] if @config_from_file[:loggers]
57
97
 
58
- self[:processes] = (config_from_file[:processes])? config_from_file[:processes] : {}
59
- self[:logs] = (config_from_file[:logs])? config_from_file[:logs] : {}
60
- self[:commands] = (config_from_file[:commands])? config_from_file[:commands] : {}
61
- self[:sequences] = (config_from_file[:sequences])? config_from_file[:sequences] : {}
62
- self[:transfers] = (config_from_file[:transfers])? config_from_file[:transfers] : {}
98
+ self[:processes] = (@config_from_file[:processes])? @config_from_file[:processes] : {}
99
+ self[:logs] = (@config_from_file[:logs])? @config_from_file[:logs] : {}
100
+ self[:commands] = (@config_from_file[:commands])? @config_from_file[:commands] : {}
101
+ self[:sequences] = (@config_from_file[:sequences])? @config_from_file[:sequences] : {}
102
+ self[:transfers] = (@config_from_file[:transfers])? @config_from_file[:transfers] : {}
103
+ end
104
+
105
+
106
+ def add_record(options = {})
107
+ @config_from_file = readconf @config_file
108
+ key = options[:key]
109
+ res = ConfigLinter::new.verify(options)
110
+ if res[:status] == :success then
111
+ if @config_from_file[options[:type]].select{|item| item[options[:key]] == options[:record][options[:key]]}.count > 0 then
112
+ return {:status => :already_exist}
113
+ else
114
+ res[:useless].each {|item| options[:record].delete item} if options[:clean]
115
+ @config_from_file[options[:type]].push options[:record]
116
+ writeconf
117
+ hash_config_to_default
118
+ return {:status => :success}
119
+ end
120
+ else
121
+ return res
122
+ end
123
+ end
63
124
 
125
+
126
+ def delete_record(options = {})
127
+ @config_from_file = readconf @config_file
128
+ unless @config_from_file[options[:type]].select{|item| item[options[:key]] == options[options[:key]]}.count > 0 then
129
+ return {:status => :not_found}
130
+ else
131
+ @config_from_file[options[:type]].delete_if {|value| options[options[:key]] == value[options[:key]] }
132
+ writeconf
133
+ hash_config_to_default
134
+ return {:status => :success}
135
+ end
64
136
  end
65
137
 
138
+
66
139
  # @!group accessors on configurations Items
67
140
 
68
141
  # getter for full Config Hash
@@ -272,6 +345,16 @@ module Splash
272
345
  return YAML.load_file(file)[:splash]
273
346
  end
274
347
 
348
+ # write config to file from @config_from_file
349
+ # @param [String] file default from CONFIG_FILE
350
+ # @return [Bool] if ok
351
+ def writeconf(file = CONFIG_FILE)
352
+ File.open(file,"w") do |f|
353
+ data = {}
354
+ data[:splash] = @config_from_file
355
+ f.write(data.to_yaml)
356
+ end
357
+ end
275
358
 
276
359
  end
277
360
 
@@ -16,8 +16,8 @@ module Splash
16
16
  self.extend Splash::Backends
17
17
  self.extend Splash::Loggers
18
18
  log = get_logger
19
- log.info "Splash backend flushing"
20
- name = (options[:name])? options[:name] : :execution_trace
19
+ name = (options[:name])? options[:name].to_sym : :execution_trace
20
+ log.info "Splash backend #{name.to_s} flushing"
21
21
  backend = get_backend name
22
22
  if backend.flush then
23
23
  return { :case => :quiet_exit, :more => "Splash backend #{name.to_s} flushed" }
@@ -7,8 +7,7 @@ module Splash
7
7
  module Constants
8
8
 
9
9
  # Current splash version
10
- VERSION = "0.8.0"
11
-
10
+ VERSION = "0.8.5"
12
11
  # the path to th config file, not overridable by config
13
12
  CONFIG_FILE = "/etc/splash.yml"
14
13
  # the default execution trace_path if backend file
@@ -87,8 +86,8 @@ module Splash
87
86
  # the default sdterr trace file
88
87
  WEBADMIN_STDERR_TRACE="stderr.txt"
89
88
 
90
- # default transfer retention for trace
91
- TRANSFER_DEFAULT_RETENTION=1
89
+ # default retention for trace
90
+ DEFAULT_RETENTION=1
92
91
 
93
92
  end
94
93
  end
@@ -84,7 +84,7 @@ module Splash
84
84
  if VERBS.include? content[:verb]
85
85
  @log.receive "Valid remote order, verb : #{content[:verb].to_s}", session
86
86
  res = self.send content[:verb], content
87
- get_default_client.publish queue: content[:return_to], message: res.to_yaml
87
+ get_default_client.publish queue: content[:return_to], message: res.to_yaml unless content[:return_to] == :ignore
88
88
  @log.send "Result to #{content[:return_to]}.", session
89
89
  else
90
90
  @log.receive "INVALID remote order, verb : #{content[:verb].to_s}", session
@@ -155,15 +155,14 @@ module Splash
155
155
 
156
156
  # prepare commands Scheduling
157
157
  def init_commands_scheduling
158
- config = get_config.commands
159
- commands = config.select{|key,value| value.include? :schedule}.keys
158
+ commands = @config.commands.select{|command| command.include? :schedule}
160
159
  commands.each do |command|
161
- sched,value = config[command][:schedule].flatten
162
- @log.arrow "Scheduling command #{command.to_s}"
160
+ sched,value = command[:schedule].flatten
161
+ @log.arrow "Scheduling command #{command[:name].to_s}"
163
162
  @server.send sched,value do
164
163
  session = get_session
165
- @log.trigger "Executing Scheduled command #{command.to_s} for Scheduling : #{sched.to_s} #{value.to_s}", session
166
- execute command: command.to_s, session: session
164
+ @log.trigger "Executing Scheduled command #{command[:name].to_s} for Scheduling : #{sched.to_s} #{value.to_s}", session
165
+ execute command: command[:name].to_s, session: session
167
166
  end
168
167
  end
169
168
  end
@@ -66,7 +66,7 @@ module Splash
66
66
  # @return [Hash] Exiter case
67
67
  def execute_command(content)
68
68
  payload = content[:payload]
69
- unless get_config.commands.include? payload[:name].to_sym
69
+ unless get_config.commands.select {|cmd| cmd[:name] == payload[:name].to_sym}.count > 0 then
70
70
  @log.item "Command not found", content[:session]
71
71
  return { :case => :not_found }
72
72
  end
@@ -50,6 +50,7 @@ module Splash
50
50
 
51
51
 
52
52
  # Splash
53
+ require 'splash/monkeys'
53
54
  require 'splash/constants'
54
55
  require 'splash/helpers'
55
56
  require 'splash/config'
@@ -60,7 +60,7 @@ module Splash
60
60
 
61
61
  def splash_return(options = {})
62
62
 
63
- data = EXIT_MAP[options[:case]]
63
+ data = EXIT_MAP[options[:case]].clone
64
64
  data[:status] = (data[:code]>0)? :failure : :success
65
65
  data[:more] = options[:more] if options[:more]
66
66
  return data
@@ -340,7 +340,7 @@ module Splash
340
340
  response = case format
341
341
  when 'application/json' then JSON.pretty_generate(data)
342
342
  when 'text/x-yaml' then data.to_yaml
343
- else JSON.pretty_generate(data)
343
+ else data.to_yaml
344
344
  end
345
345
  return response
346
346
  end
@@ -6,6 +6,83 @@ module Splash
6
6
  # Logs namespace
7
7
  module Logs
8
8
 
9
+ class LogsNotifier
10
+
11
+ @@registry = Prometheus::Client::Registry::new
12
+ @@metric_missing = Prometheus::Client::Gauge.new(:logmissing, docstring: 'SPLASH metric log missing', labels: [:log ])
13
+ @@metric_count = Prometheus::Client::Gauge.new(:logerrors, docstring: 'SPLASH metric log error', labels: [:log ])
14
+ @@metric_lines = Prometheus::Client::Gauge.new(:loglines, docstring: 'SPLASH metric log lines numbers', labels: [:log ])
15
+ @@registry.register(@@metric_count)
16
+ @@registry.register(@@metric_missing)
17
+ @@registry.register(@@metric_lines)
18
+
19
+ def initialize(options={})
20
+ @config = get_config
21
+ @url = @config.prometheus_pushgateway_url
22
+ @name = options[:name]
23
+ @missing = options[:missing]
24
+ @lines = options[:lines]
25
+ @errors = options[:errors]
26
+ end
27
+
28
+ # send metrics to Prometheus PushGateway
29
+ # @return [Bool]
30
+ def notify
31
+ unless verify_service url: @url then
32
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
33
+ end
34
+ @@metric_missing.set(@missing, labels: { log: @name })
35
+ @@metric_count.set(@errors, labels: { log: @name })
36
+ @@metric_lines.set(@lines, labels: { log: @name })
37
+ hostname = Socket.gethostname
38
+ return Prometheus::Client::Push.new("Splash", hostname, @url).add(@@registry)
39
+ end
40
+
41
+ end
42
+
43
+ class LogsRecords
44
+ include Splash::Backends
45
+ include Splash::Constants
46
+ def initialize(name)
47
+ @name = name
48
+ @backend = get_backend :logs_trace
49
+ end
50
+
51
+ def clear
52
+ @backend.del({:key => @name}) if @backend.exist?({key: @name})
53
+ end
54
+
55
+ def purge(retention)
56
+ retention = {} if retention.nil?
57
+ if retention.include? :hours then
58
+ adjusted_datetime = DateTime.now - retention[:hours].to_f / 24
59
+ elsif retention.include? :hours then
60
+ adjusted_datetime = DateTime.now - retention[:days].to_i
61
+ else
62
+ adjusted_datetime = DateTime.now - DEFAULT_RETENTION
63
+ end
64
+
65
+ data = get_all_records
66
+
67
+ data.delete_if { |item|
68
+ DateTime.parse(item.keys.first) <= (adjusted_datetime)}
69
+ @backend.put key: @name, value: data.to_yaml
70
+ end
71
+
72
+ def add_record(record)
73
+ data = get_all_records
74
+ data.push({ DateTime.now.to_s => record })
75
+ @backend.put key: @name, value: data.to_yaml
76
+ end
77
+
78
+ def get_all_records(options={})
79
+ return (@backend.exist?({key: @name}))? YAML::load(@backend.get({key: @name})) : []
80
+ end
81
+
82
+ end
83
+
84
+
85
+
9
86
  # Log scanner and notifier
10
87
  class LogScanner
11
88
  include Splash::Constants
@@ -17,13 +94,7 @@ module Splash
17
94
  def initialize
18
95
  @logs_target = Marshal.load(Marshal.dump(get_config.logs))
19
96
  @config = get_config
20
- @registry = Prometheus::Client::Registry::new
21
- @metric_count = Prometheus::Client::Gauge.new(:logerrors, docstring: 'SPLASH metric log error', labels: [:log ])
22
- @metric_missing = Prometheus::Client::Gauge.new(:logmissing, docstring: 'SPLASH metric log missing', labels: [:log ])
23
- @metric_lines = Prometheus::Client::Gauge.new(:loglines, docstring: 'SPLASH metric log lines numbers', labels: [:log ])
24
- @registry.register(@metric_count)
25
- @registry.register(@metric_missing)
26
- @registry.register(@metric_lines)
97
+
27
98
  end
28
99
 
29
100
 
@@ -62,17 +133,24 @@ module Splash
62
133
  session = (options[:session]) ? options[:session] : log.get_session
63
134
  log.info "Sending metrics to Prometheus Pushgateway", session
64
135
  @logs_target.each do |item|
65
- missing = (item[:status] == :missing)? 1 : 0
66
- log.item "Sending metrics for #{item[:log]}", session
67
- @metric_count.set(item[:count], labels: { log: item[:log] })
68
- @metric_missing.set(missing, labels: { log: item[:log] })
136
+ logsrec = LogsRecords::new item[:label]
137
+ errors = (item[:count])? item[:count] : 0
69
138
  lines = (item[:lines])? item[:lines] : 0
70
- @metric_lines.set(lines, labels: { log: item[:log] })
139
+ missing = (item[:status] == :missing)? 1 : 0
140
+ file = item[:log]
141
+ logsrec.purge(item[:retention])
142
+ logsrec.add_record :status => item[:status],
143
+ :errors => errors,
144
+ :lines => lines,
145
+ :file => file
146
+
147
+ logsmonitor = LogsNotifier::new({name: item[:label], missing: missing, file: file, errors: errors, lines: lines})
148
+ if logsmonitor.notify then
149
+ log.ok "Sending metrics for log #{file} to Prometheus Pushgateway", session
150
+ else
151
+ log.ko "Failed to send metrics for log #{file} to Prometheus Pushgateway", session
152
+ end
71
153
  end
72
- hostname = Socket.gethostname
73
- url = @config.prometheus_pushgateway_url
74
- Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
75
- log.ok "Sending to Prometheus PushGateway done.", session
76
154
  return {:case => :quiet_exit }
77
155
  end
78
156
 
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def blank?
3
+ respond_to?(:empty?) ? !!empty? : !self
4
+ end
5
+ end
@@ -6,6 +6,85 @@ module Splash
6
6
  # Processes namespace
7
7
  module Processes
8
8
 
9
+
10
+ class ProcessNotifier
11
+
12
+ @@registry = Prometheus::Client::Registry::new
13
+ @@metric_status = Prometheus::Client::Gauge.new(:process_status, docstring: 'SPLASH metric process status', labels: [:process ])
14
+ @@metric_cpu_percent = Prometheus::Client::Gauge.new(:process_cpu_percent, docstring: 'SPLASH metric process CPU usage in percent', labels: [:process ])
15
+ @@metric_mem_percent = Prometheus::Client::Gauge.new(:process_mem_percent, docstring: 'SPLASH metric process MEM usage in percent', labels: [:process ])
16
+ @@registry.register(@@metric_status)
17
+ @@registry.register(@@metric_cpu_percent)
18
+ @@registry.register(@@metric_mem_percent)
19
+
20
+
21
+ def initialize(options={})
22
+ @config = get_config
23
+ @url = @config.prometheus_pushgateway_url
24
+ @name = options[:name]
25
+ @status = options[:status]
26
+ @cpu_percent = options[:cpu_percent]
27
+ @mem_percent = options[:mem_percent]
28
+ end
29
+
30
+ # send metrics to Prometheus PushGateway
31
+ # @return [Bool]
32
+ def notify
33
+ unless verify_service url: @url then
34
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
35
+ end
36
+ @@metric_mem_percent.set(@mem_percent, labels: { process: @name })
37
+ @@metric_cpu_percent.set(@cpu_percent, labels: { process: @name })
38
+ @@metric_status.set(@status, labels: { process: @name })
39
+ hostname = Socket.gethostname
40
+ return Prometheus::Client::Push.new("Splash", hostname, @url).add(@@registry)
41
+ end
42
+
43
+ end
44
+
45
+
46
+ class ProcessRecords
47
+ include Splash::Backends
48
+ include Splash::Constants
49
+
50
+ def initialize(name)
51
+ @name = name
52
+ @backend = get_backend :process_trace
53
+ end
54
+
55
+ def clear
56
+ @backend.del({:key => @name}) if @backend.exist?({key: @name})
57
+ end
58
+
59
+ def purge(retention)
60
+ retention = {} if retention.nil?
61
+ if retention.include? :hours then
62
+ adjusted_datetime = DateTime.now - retention[:hours].to_f / 24
63
+ elsif retention.include? :hours then
64
+ adjusted_datetime = DateTime.now - retention[:days].to_i
65
+ else
66
+ adjusted_datetime = DateTime.now - DEFAULT_RETENTION
67
+ end
68
+
69
+ data = get_all_records
70
+
71
+ data.delete_if { |item|
72
+ DateTime.parse(item.keys.first) <= (adjusted_datetime)}
73
+ @backend.put key: @name, value: data.to_yaml
74
+ end
75
+
76
+ def add_record(record)
77
+ data = get_all_records
78
+ data.push({ DateTime.now.to_s => record })
79
+ @backend.put key: @name, value: data.to_yaml
80
+ end
81
+
82
+ def get_all_records(options={})
83
+ return (@backend.exist?({key: @name}))? YAML::load(@backend.get({key: @name})) : []
84
+ end
85
+
86
+ end
87
+
9
88
  # Processes scanner and notifier
10
89
  class ProcessScanner
11
90
  include Splash::Constants
@@ -17,14 +96,6 @@ module Splash
17
96
  def initialize
18
97
  @processes_target = Marshal.load(Marshal.dump(get_config.processes))
19
98
  @config = get_config
20
- @registry = Prometheus::Client::Registry::new
21
- @metric_status = Prometheus::Client::Gauge.new(:process_status, docstring: 'SPLASH metric process status', labels: [:process ])
22
- @metric_cpu_percent = Prometheus::Client::Gauge.new(:process_cpu_percent, docstring: 'SPLASH metric process CPU usage in percent', labels: [:process ])
23
- @metric_mem_percent = Prometheus::Client::Gauge.new(:process_mem_percent, docstring: 'SPLASH metric process MEM usage in percent', labels: [:process ])
24
- @registry.register(@metric_status)
25
- @registry.register(@metric_cpu_percent)
26
- @registry.register(@metric_mem_percent)
27
-
28
99
  end
29
100
 
30
101
 
@@ -64,17 +135,21 @@ module Splash
64
135
  session = (options[:session]) ? options[:session] : log.get_session
65
136
  log.info "Sending metrics to Prometheus Pushgateway", session
66
137
  @processes_target.each do |item|
138
+ processrec = ProcessRecords::new item[:process]
67
139
  missing = (item[:status] == :missing)? 1 : 0
68
- log.item "Sending metrics for #{item[:process]}", session
69
140
  val = (item[:status] == :running )? 1 : 0
70
- @metric_status.set(val, labels: { process: item[:process] })
71
- @metric_cpu_percent.set(item[:cpu], labels: { process: item[:process] })
72
- @metric_mem_percent.set(item[:mem], labels: { process: item[:process] })
141
+ processrec.purge(item[:retention])
142
+ processrec.add_record :status => item[:status],
143
+ :cpu_percent => item[:cpu],
144
+ :mem_percent => item[:mem] ,
145
+ :process => item[:process]
146
+ processmonitor = ProcessNotifier::new({name: item[:process], status: val , cpu_percent: item[:cpu], mem_percent: item[:mem]})
147
+ if processmonitor.notify then
148
+ log.ok "Sending metrics for process #{item[:process]} to Prometheus Pushgateway", session
149
+ else
150
+ log.ko "Failed to send metrics for process #{item[:process]} to Prometheus Pushgateway", session
151
+ end
73
152
  end
74
- hostname = Socket.gethostname
75
- url = @config.prometheus_pushgateway_url
76
- Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
77
- log.ok "Sending to Prometheus PushGateway done.", session
78
153
  return {:case => :quiet_exit }
79
154
  end
80
155