prometheus-splash 0.6.1 → 0.8.3
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/CHANGELOG.md +43 -1
- data/README.md +1 -1
- data/config/splash.yml +45 -5
- data/lib/splash/backends.rb +1 -0
- data/lib/splash/cli.rb +2 -1
- data/lib/splash/cli/commands.rb +125 -5
- data/lib/splash/cli/daemon.rb +41 -1
- data/lib/splash/cli/logs.rb +111 -47
- data/lib/splash/cli/process.rb +112 -52
- data/lib/splash/cli/sequences.rb +2 -0
- data/lib/splash/cli/transfers.rb +213 -0
- data/lib/splash/cli/webadmin.rb +3 -3
- data/lib/splash/commands.rb +85 -19
- data/lib/splash/config.rb +142 -52
- data/lib/splash/constants.rb +7 -3
- data/lib/splash/daemon/metrics.rb +6 -6
- data/lib/splash/daemon/orchestrator.rb +76 -36
- data/lib/splash/daemon/orchestrator/grammar.rb +16 -1
- data/lib/splash/dependencies.rb +6 -1
- data/lib/splash/exiter.rb +1 -1
- data/lib/splash/helpers.rb +12 -3
- data/lib/splash/loggers/cli.rb +2 -10
- data/lib/splash/logs.rb +90 -16
- data/lib/splash/processes.rb +87 -16
- data/lib/splash/transfers.rb +229 -0
- data/lib/splash/webadmin.rb +3 -3
- data/lib/splash/webadmin/api/routes/commands.rb +2 -2
- data/lib/splash/webadmin/api/routes/config.rb +53 -2
- data/lib/splash/webadmin/api/routes/logs.rb +32 -17
- data/lib/splash/webadmin/api/routes/process.rb +4 -4
- data/lib/splash/webadmin/api/routes/sequences.rb +28 -0
- data/lib/splash/webadmin/main.rb +1 -0
- data/lib/splash/webadmin/portal/controllers/commands.rb +2 -0
- data/lib/splash/webadmin/portal/controllers/documentation.rb +3 -1
- data/lib/splash/webadmin/portal/controllers/home.rb +24 -0
- data/lib/splash/webadmin/portal/controllers/logs.rb +44 -1
- data/lib/splash/webadmin/portal/controllers/processes.rb +2 -0
- data/lib/splash/webadmin/portal/controllers/proxy.rb +13 -4
- data/lib/splash/webadmin/portal/controllers/restclient.rb +7 -2
- data/lib/splash/webadmin/portal/controllers/sequences.rb +9 -0
- data/lib/splash/webadmin/portal/init.rb +2 -2
- data/lib/splash/webadmin/portal/public/css/ultragreen.css +6 -0
- data/lib/splash/webadmin/portal/public/favicon.ico +0 -0
- data/lib/splash/webadmin/portal/views/commands.slim +1 -1
- data/lib/splash/webadmin/portal/views/documentation.slim +1 -1
- data/lib/splash/webadmin/portal/views/home.slim +53 -9
- data/lib/splash/webadmin/portal/views/layout.slim +2 -2
- data/lib/splash/webadmin/portal/views/logs.slim +68 -21
- data/lib/splash/webadmin/portal/views/logs_form.slim +24 -0
- data/lib/splash/webadmin/portal/views/nav.slim +1 -1
- data/lib/splash/webadmin/portal/views/not_found.slim +1 -1
- data/lib/splash/webadmin/portal/views/processes.slim +1 -1
- data/lib/splash/webadmin/portal/views/proxy.slim +5 -2
- data/lib/splash/webadmin/portal/views/restclient.slim +7 -4
- data/lib/splash/webadmin/portal/views/restclient_result.slim +24 -20
- data/lib/splash/webadmin/portal/views/sequences.slim +50 -0
- data/prometheus-splash.gemspec +7 -4
- data/ultragreen_roodi_coding_convention.yml +4 -4
- metadata +75 -12
@@ -16,7 +16,7 @@ module Splash
|
|
16
16
|
include Splash::Loggers
|
17
17
|
|
18
18
|
# list of known verbs for Splash orchestrator
|
19
|
-
VERBS=[:ping,:list_commands,:execute_command,:ack_command, :shutdown]
|
19
|
+
VERBS=[:ping,:list_commands,:execute_command,:ack_command, :shutdown, :get_jobs, :reset]
|
20
20
|
|
21
21
|
# shutdown verb : stop the Splash daemon gracefully
|
22
22
|
# @param [Hash] content message content Hash Structure, ignored
|
@@ -46,6 +46,21 @@ module Splash
|
|
46
46
|
return execute command: content[:payload][:name], ack: true
|
47
47
|
end
|
48
48
|
|
49
|
+
|
50
|
+
# get_jobs verb : return list of scheduled jobs for internal scheduler
|
51
|
+
# @param [Hash] content message content Hash Structure, ignored
|
52
|
+
# @return [String] YAML dataset
|
53
|
+
def get_jobs(content)
|
54
|
+
return @server.jobs.to_yaml
|
55
|
+
end
|
56
|
+
|
57
|
+
# reset verb : reset the internal scheduler
|
58
|
+
# @param [Hash] content message content Hash Structure, ignored
|
59
|
+
# @return [String] "Scheduler reset" static
|
60
|
+
def reset(content)
|
61
|
+
return "Scheduler reset" if reset_orchestrator
|
62
|
+
end
|
63
|
+
|
49
64
|
# execute_command verb : execute command specified in payload
|
50
65
|
# @param [Hash] content message content Hash Structure, include mandatory payload[:name]
|
51
66
|
# @return [Hash] Exiter case
|
data/lib/splash/dependencies.rb
CHANGED
@@ -17,8 +17,12 @@ module Splash
|
|
17
17
|
|
18
18
|
|
19
19
|
|
20
|
+
|
21
|
+
|
20
22
|
# Rubygems
|
21
23
|
begin
|
24
|
+
require 'net/ssh'
|
25
|
+
require 'net/scp'
|
22
26
|
require 'prometheus/client'
|
23
27
|
require 'prometheus/client/push'
|
24
28
|
require 'thor'
|
@@ -35,6 +39,7 @@ module Splash
|
|
35
39
|
require 'rest-client'
|
36
40
|
require 'kramdown'
|
37
41
|
require 'rack/reverse_proxy'
|
42
|
+
require 'tty-table'
|
38
43
|
|
39
44
|
|
40
45
|
rescue Gem::GemNotFoundException
|
@@ -57,9 +62,9 @@ module Splash
|
|
57
62
|
|
58
63
|
require 'splash/commands'
|
59
64
|
require 'splash/sequences'
|
60
|
-
|
61
65
|
require 'splash/logs'
|
62
66
|
require 'splash/processes'
|
67
|
+
require 'splash/transfers'
|
63
68
|
|
64
69
|
require 'splash/daemon'
|
65
70
|
require 'splash/webadmin'
|
data/lib/splash/exiter.rb
CHANGED
data/lib/splash/helpers.rb
CHANGED
@@ -252,7 +252,7 @@ module Splash
|
|
252
252
|
# check folder
|
253
253
|
# @return [Array] of Symbol with error type : [:inexistant,:mode,:owner,:group]
|
254
254
|
# @param [Hash] options
|
255
|
-
# @option options [String] :
|
255
|
+
# @option options [String] :name folder path (relative or absolute)
|
256
256
|
# @option options [String] :mode String for OCTAL rights like "644", optionnal
|
257
257
|
# @option options [String] :owner file owner for folder, optionnal
|
258
258
|
# @option options [String] :group file group for folder, optionnal
|
@@ -336,12 +336,11 @@ module Splash
|
|
336
336
|
end
|
337
337
|
#!@endgroup
|
338
338
|
|
339
|
-
|
340
339
|
def format_response(data, format)
|
341
340
|
response = case format
|
342
341
|
when 'application/json' then JSON.pretty_generate(data)
|
343
342
|
when 'text/x-yaml' then data.to_yaml
|
344
|
-
else
|
343
|
+
else data.to_yaml
|
345
344
|
end
|
346
345
|
return response
|
347
346
|
end
|
@@ -355,6 +354,16 @@ module Splash
|
|
355
354
|
return result[extension]
|
356
355
|
end
|
357
356
|
|
357
|
+
# check if unicode must be used with term ENV
|
358
|
+
# @return [Boolean]
|
359
|
+
def check_unicode_term
|
360
|
+
return false unless ENV.include? "TERM"
|
361
|
+
if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.first.include?("UTF-8") and ENV.values_at('TERM').first.include? "xterm" then
|
362
|
+
return true
|
363
|
+
else
|
364
|
+
return false
|
365
|
+
end
|
366
|
+
end
|
358
367
|
|
359
368
|
end
|
360
369
|
end
|
data/lib/splash/loggers/cli.rb
CHANGED
@@ -10,6 +10,7 @@ module Splash
|
|
10
10
|
class Cli < Splash::Loggers::LoggerTemplate
|
11
11
|
|
12
12
|
include Splash::Config
|
13
|
+
include Splash::Helpers
|
13
14
|
|
14
15
|
# mapping of UTf-8 emoji for log levels or alias
|
15
16
|
EMOJI = { :unknown => "\u{1F4A5}",
|
@@ -82,16 +83,7 @@ module Splash
|
|
82
83
|
get_config.loggers[:cli][:color] = status
|
83
84
|
end
|
84
85
|
|
85
|
-
|
86
|
-
# @return [Boolean]
|
87
|
-
def check_unicode_term
|
88
|
-
return false unless ENV.include? "TERM"
|
89
|
-
if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.first.include?("UTF-8") and ENV.values_at('TERM').first.include? "xterm" then
|
90
|
-
return true
|
91
|
-
else
|
92
|
-
return false
|
93
|
-
end
|
94
|
-
end
|
86
|
+
|
95
87
|
|
96
88
|
end
|
97
89
|
|
data/lib/splash/logs.rb
CHANGED
@@ -6,6 +6,79 @@ 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 purge(retention)
|
52
|
+
retention = {} if retention.nil?
|
53
|
+
if retention.include? :hours then
|
54
|
+
adjusted_datetime = DateTime.now - retention[:hours].to_f / 24
|
55
|
+
elsif retention.include? :hours then
|
56
|
+
adjusted_datetime = DateTime.now - retention[:days].to_i
|
57
|
+
else
|
58
|
+
adjusted_datetime = DateTime.now - DEFAULT_RETENTION
|
59
|
+
end
|
60
|
+
|
61
|
+
data = get_all_records
|
62
|
+
|
63
|
+
data.delete_if { |item|
|
64
|
+
DateTime.parse(item.keys.first) <= (adjusted_datetime)}
|
65
|
+
@backend.put key: @name, value: data.to_yaml
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_record(record)
|
69
|
+
data = get_all_records
|
70
|
+
data.push({ DateTime.now.to_s => record })
|
71
|
+
@backend.put key: @name, value: data.to_yaml
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_all_records(options={})
|
75
|
+
return (@backend.exist?({key: @name}))? YAML::load(@backend.get({key: @name})) : []
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
9
82
|
# Log scanner and notifier
|
10
83
|
class LogScanner
|
11
84
|
include Splash::Constants
|
@@ -17,13 +90,7 @@ module Splash
|
|
17
90
|
def initialize
|
18
91
|
@logs_target = Marshal.load(Marshal.dump(get_config.logs))
|
19
92
|
@config = get_config
|
20
|
-
|
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)
|
93
|
+
|
27
94
|
end
|
28
95
|
|
29
96
|
|
@@ -62,17 +129,24 @@ module Splash
|
|
62
129
|
session = (options[:session]) ? options[:session] : log.get_session
|
63
130
|
log.info "Sending metrics to Prometheus Pushgateway", session
|
64
131
|
@logs_target.each do |item|
|
65
|
-
|
66
|
-
|
67
|
-
@metric_count.set(item[:count], labels: { log: item[:log] })
|
68
|
-
@metric_missing.set(missing, labels: { log: item[:log] })
|
132
|
+
logsrec = LogsRecords::new item[:label]
|
133
|
+
errors = (item[:count])? item[:count] : 0
|
69
134
|
lines = (item[:lines])? item[:lines] : 0
|
70
|
-
|
135
|
+
missing = (item[:status] = :missing)? 1 : 0
|
136
|
+
file = item[:log]
|
137
|
+
logsrec.purge(item[:retention])
|
138
|
+
logsrec.add_record :status => item[:status],
|
139
|
+
:errors => errors,
|
140
|
+
:lines => lines,
|
141
|
+
:file => file
|
142
|
+
|
143
|
+
logsmonitor = LogsNotifier::new({name: item[:label], missing: missing, file: file, errors: errors, lines: lines})
|
144
|
+
if logsmonitor.notify then
|
145
|
+
log.ok "Sending metrics for log #{file} to Prometheus Pushgateway", session
|
146
|
+
else
|
147
|
+
log.ko "Failed to send metrics for log #{file} to Prometheus Pushgateway", session
|
148
|
+
end
|
71
149
|
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
150
|
return {:case => :quiet_exit }
|
77
151
|
end
|
78
152
|
|
data/lib/splash/processes.rb
CHANGED
@@ -6,6 +6,81 @@ 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 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
|
+
|
9
84
|
# Processes scanner and notifier
|
10
85
|
class ProcessScanner
|
11
86
|
include Splash::Constants
|
@@ -17,14 +92,6 @@ module Splash
|
|
17
92
|
def initialize
|
18
93
|
@processes_target = Marshal.load(Marshal.dump(get_config.processes))
|
19
94
|
@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
95
|
end
|
29
96
|
|
30
97
|
|
@@ -64,17 +131,21 @@ module Splash
|
|
64
131
|
session = (options[:session]) ? options[:session] : log.get_session
|
65
132
|
log.info "Sending metrics to Prometheus Pushgateway", session
|
66
133
|
@processes_target.each do |item|
|
134
|
+
processrec = ProcessRecords::new item[:process]
|
67
135
|
missing = (item[:status] == :missing)? 1 : 0
|
68
|
-
log.item "Sending metrics for #{item[:process]}", session
|
69
136
|
val = (item[:status] == :running )? 1 : 0
|
70
|
-
|
71
|
-
|
72
|
-
|
137
|
+
processrec.purge(item[:retention])
|
138
|
+
processrec.add_record :status => item[:status],
|
139
|
+
:cpu_percent => item[:cpu],
|
140
|
+
:mem_percent => item[:mem] ,
|
141
|
+
:process => item[:process]
|
142
|
+
processmonitor = ProcessNotifier::new({name: item[:process], status: val , cpu_percent: item[:cpu], mem_percent: item[:mem]})
|
143
|
+
if processmonitor.notify then
|
144
|
+
log.ok "Sending metrics for process #{item[:process]} to Prometheus Pushgateway", session
|
145
|
+
else
|
146
|
+
log.ko "Failed to send metrics for process #{item[:process]} to Prometheus Pushgateway", session
|
147
|
+
end
|
73
148
|
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
149
|
return {:case => :quiet_exit }
|
79
150
|
end
|
80
151
|
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# base Splash Module
|
4
|
+
module Splash
|
5
|
+
|
6
|
+
# Transfers module
|
7
|
+
module Transfers
|
8
|
+
|
9
|
+
include Splash::Config
|
10
|
+
include Splash::Loggers
|
11
|
+
include Splash::Helpers
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
class TxNotifier
|
16
|
+
@@registry = Prometheus::Client::Registry::new
|
17
|
+
@@metric_nbfiles = Prometheus::Client::Gauge.new(:txnbfiles, docstring: 'SPLASH metric transfer number of files')
|
18
|
+
@@metric_nbfiles_failed = Prometheus::Client::Gauge.new(:txnbfilesfailed, docstring: 'SPLASH metric transfer number of failed files')
|
19
|
+
@@metric_time = Prometheus::Client::Gauge.new(:txtime, docstring: 'SPLASH metric transfer execution time')
|
20
|
+
@@registry.register(@@metric_nbfiles)
|
21
|
+
@@registry.register(@@metric_nbfiles_failed)
|
22
|
+
@@registry.register(@@metric_time)
|
23
|
+
|
24
|
+
def initialize(options={})
|
25
|
+
@config = get_config
|
26
|
+
@url = @config.prometheus_pushgateway_url
|
27
|
+
@name = "tx_#{options[:name].to_s}"
|
28
|
+
@nbfiles = options[:nbfiles]
|
29
|
+
@nbfiles_failed = options[:nbfiles_failed]
|
30
|
+
@time = options[:time]
|
31
|
+
end
|
32
|
+
|
33
|
+
# send metrics to Prometheus PushGateway
|
34
|
+
# @return [Bool]
|
35
|
+
def notify
|
36
|
+
unless verify_service url: @url then
|
37
|
+
return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
|
38
|
+
end
|
39
|
+
@@metric_nbfiles.set(@nbfiles)
|
40
|
+
@@metric_nbfiles_failed.set(@nbfiles_failed)
|
41
|
+
@@metric_time.set(@time)
|
42
|
+
hostname = Socket.gethostname
|
43
|
+
return Prometheus::Client::Push.new(@name, hostname, @url).add(@@registry)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
class TxRecords
|
51
|
+
include Splash::Backends
|
52
|
+
include Splash::Constants
|
53
|
+
|
54
|
+
def initialize(name)
|
55
|
+
@name = name
|
56
|
+
@backend = get_backend :transfers_trace
|
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
|
+
def check_prepared
|
87
|
+
return :never_run_prepare unless @backend.exist?({key: @name})
|
88
|
+
return :never_prepare unless YAML::load(@backend.get({key: @name})).select {|item|
|
89
|
+
record =item.keys.first
|
90
|
+
value=item[record]
|
91
|
+
value[:status] == :prepared
|
92
|
+
}.count > 0
|
93
|
+
return :prepared
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def run_txs(options = {})
|
99
|
+
log = get_logger
|
100
|
+
log.info 'Running Transfers'
|
101
|
+
count=0
|
102
|
+
get_config.transfers.each do |record|
|
103
|
+
txrec = TxRecords::new record[:name]
|
104
|
+
txrec.purge(record[:retention])
|
105
|
+
log.item "Execute : #{record[:name]}, #{record[:desc]}"
|
106
|
+
case txrec.check_prepared
|
107
|
+
when :prepared
|
108
|
+
if record[:type] == :push then
|
109
|
+
unless push record
|
110
|
+
count += 1
|
111
|
+
end
|
112
|
+
elsif record[:type] == :pull then
|
113
|
+
unless pull record
|
114
|
+
count += 1
|
115
|
+
end
|
116
|
+
else
|
117
|
+
log.ko "Transfer type unkown"
|
118
|
+
count += 1
|
119
|
+
end
|
120
|
+
when :never_prepare
|
121
|
+
log.ko "#{record[:name]} : Never prepared, ignored"
|
122
|
+
txrec.add_record :status => :never_prepared
|
123
|
+
count += 1
|
124
|
+
when :never_run_prepare
|
125
|
+
log.ko "#{record[:name]} : Never Executed and never prepared, ignored"
|
126
|
+
txrec.add_record :status => :never_prepared
|
127
|
+
count += 1
|
128
|
+
end
|
129
|
+
end
|
130
|
+
return {:case => :error_exit, :more => "#{count} Transfer(s) failed"} if count > 0
|
131
|
+
return {:case => :quiet_exit }
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
def prepare_tx(name)
|
137
|
+
log = get_logger
|
138
|
+
record = get_config.transfers.select { |item| item[:name] == name.to_sym }.first
|
139
|
+
home = Etc.getpwnam(record[:local][:user]).dir
|
140
|
+
identity = ::File::readlines("#{home}/.ssh/id_rsa.pub").first.chomp
|
141
|
+
folder = {:mode => "755",
|
142
|
+
:owner => record[:local][:user] ,
|
143
|
+
:group => Etc.getgrgid(Etc.getpwnam(record[:local][:user]).gid).name,
|
144
|
+
:name => record[:local][:path],
|
145
|
+
:path => record[:local][:path]}
|
146
|
+
log.info "Ensure local folder : #{record[:local][:path]}"
|
147
|
+
make_folder(folder) unless verify_folder(folder).empty?
|
148
|
+
begin
|
149
|
+
log.info "Ensure RSA Key sharing for local user : #{record[:local][:user]} to remote user : #{record[:remote][:user]}@#{record[:remote][:host]}"
|
150
|
+
ssh = Net::SSH.start(record[:remote][:host],record[:remote][:user])
|
151
|
+
output = ssh.exec!(%[
|
152
|
+
/bin/bash -cl '
|
153
|
+
umask 077;
|
154
|
+
mkdir #{record[:remote][:path]};
|
155
|
+
test -d ~/.ssh || mkdir ~/.ssh;
|
156
|
+
if [ ! -f ~/.ssh/authorized_keys -o `grep "#{identity}" ~/.ssh/authorized_keys 2> /dev/null | wc -l` -eq 0 ]; then echo "#{identity}" >> ~/.ssh/authorized_keys
|
157
|
+
fi'])
|
158
|
+
log.info "Prepare remote folder : #{record[:remote][:path]}"
|
159
|
+
log.info "Prepare data file for transfer : #{record[:name]}"
|
160
|
+
txrec = TxRecords::new record[:name]
|
161
|
+
txrec.add_record :status => :prepared
|
162
|
+
log.ok "Transfer : #{record[:name]} prepared successfully"
|
163
|
+
return {:case => :quiet_exit }
|
164
|
+
rescue Interrupt
|
165
|
+
splash_exit case: :interrupt, more: "Remote command exection"
|
166
|
+
rescue TTY::Reader::InputInterrupt
|
167
|
+
splash_exit case: :interrupt, more: "Remote command exection"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
def save_data
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
def push(record)
|
180
|
+
config = get_config
|
181
|
+
log = get_logger
|
182
|
+
txrec = TxRecords::new record[:name]
|
183
|
+
start = Time.now
|
184
|
+
res = true
|
185
|
+
count = 0
|
186
|
+
done =[]
|
187
|
+
start_date = DateTime.now.to_s
|
188
|
+
list = Dir.glob("#{record[:local][:path]}/#{record[:pattern]}")
|
189
|
+
count = list.count
|
190
|
+
log.arrow "Transfering #{count} file(s)"
|
191
|
+
|
192
|
+
begin
|
193
|
+
scp = Net::SCP.start(record[:remote][:host],record[:remote][:user])
|
194
|
+
list.each do|f|
|
195
|
+
log.arrow "Copy file : #{f} to #{record[:remote][:user]}@#{record[:remote][:host]}:#{record[:remote][:path]}"
|
196
|
+
scp.upload! f, record[:remote][:path]
|
197
|
+
done.push f
|
198
|
+
if record[:backup] then
|
199
|
+
log.arrow "File #{f} backuped"
|
200
|
+
FileUtils::mv(f, "#{f}.#{Time.now.getutc.to_i}")
|
201
|
+
else
|
202
|
+
FileUtils::unlink(f)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
rescue
|
207
|
+
res = false
|
208
|
+
end
|
209
|
+
|
210
|
+
end_date = DateTime.now.to_s
|
211
|
+
time = Time.now - start
|
212
|
+
status = (res)? :success : :failure
|
213
|
+
txrec.add_record :status => status,
|
214
|
+
:end_date => end_date,
|
215
|
+
:time => time,
|
216
|
+
:count => count,
|
217
|
+
:wanted => list,
|
218
|
+
:done => done
|
219
|
+
count_failed = list.count - done.count
|
220
|
+
txmonitor = TxNotifier::new({name: record[:name], nbfiles: count,nbfiles_failed: count_failed, time: time})
|
221
|
+
if txmonitor.notify then
|
222
|
+
log.ok "Sending metrics to Prometheus Pushgateway"
|
223
|
+
else
|
224
|
+
log.ko "Failed to send metrics to Prometheus Pushgateway"
|
225
|
+
end
|
226
|
+
return res
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|