prometheus-splash 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6674f3e9608370fdb5cd83f68ad51c91f749230f1698009ddd811d795000af1b
4
+ data.tar.gz: 314e8c80cdcc580bf1ccc45fc887adb3907d5d2d9af1b3930d0fee04ff740e27
5
+ SHA512:
6
+ metadata.gz: c8cbdb6c3b296602a997d95727abb23da02ef27227afe7654a9a6213795f156d70d117569a71192aa5768837d650e4f3e9b760196e5e471c743ae0999be06989
7
+ data.tar.gz: bfc21d04dafd15d23c5e6ddf9de3851d103f64e800be0875ffd6ca8d6d68bedeef29fe9d4c205caf8b3bdb130ee57062630bd1f2f572e4337edc7d16dbb2093a
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in codetree.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+ Splash Copyright (c) 2020 Ultragreen Software, Romain GEORGES
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions
6
+ are met:
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
+ SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # Splash
2
+
3
+ SPLASH is *Supervision with Prometheus of Logs and Asynchronous tasks for Services or Hosts*
4
+
5
+
6
+ Prometheus Logs and Batchs supervision over PushGateway
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'splash'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install splash
21
+
22
+ ## Usage
23
+
24
+ TODO: Write usage instructions here
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin my-new-feature`)
32
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rubygems'
3
+ require 'rspec'
4
+ require 'rake'
5
+ require "rake/clean"
6
+ require "rubygems/package_task"
7
+ require "rdoc/task"
8
+ require 'code_statistics'
9
+ require 'rspec/core/rake_task'
10
+ require 'yard'
11
+ require 'yard/rake/yardoc_task.rb'
12
+ require "rake/tasklib"
13
+ require "roodi"
14
+ require "roodi_task"
15
+
16
+
17
+ RoodiTask.new() do | t |
18
+ t.patterns = %w(lib/**/*.rb)
19
+ t.config = "ultragreen_roodi_coding_convention.yml"
20
+ end
21
+
22
+
23
+ CLEAN.include('*.tmp','*.old')
24
+ CLOBBER.include('*.tmp', 'build/*','#*#')
25
+
26
+
27
+ content = File::readlines(File.join(File.dirname(__FILE__), 'splash.gemspec')).join
28
+ spec = eval(content)
29
+
30
+ RSpec::Core::RakeTask.new('spec')
31
+
32
+ YARD::Rake::YardocTask.new do |t|
33
+ t.files = [ 'lib/**/*.rb', '-', 'doc/**/*','spec/**/*_spec.rb']
34
+ t.options += ['--title', "Gem Documentation"]
35
+ t.options += ['-o', "yardoc"]
36
+ t.options += ['-r', "doc/manual.rdoc"]
37
+ end
38
+ YARD::Config.load_plugin('yard-rspec')
39
+
40
+ namespace :yardoc do
41
+ task :clobber do
42
+ rm_r "yardoc" rescue nil
43
+ rm_r ".yardoc" rescue nil
44
+ end
45
+ end
46
+ task :clobber => "yardoc:clobber"
47
+
48
+
49
+ Gem::PackageTask.new(spec) do |pkg|
50
+ pkg.need_tar = true
51
+ pkg.need_zip = true
52
+ end
53
+
54
+ Rake::RDocTask.new('rdoc') do |d|
55
+ d.rdoc_files.include('doc/**/*','bin/*')
56
+ d.main = 'doc/manual.rdoc'
57
+ d.title = 'Dorsal : Yard'
58
+ d.options << '--line-numbers' << '--diagram' << '-SHN'
59
+ end
60
+
61
+ task :default => [:gem]
data/bin/splash ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env ruby -W:no-deprecated
2
+
3
+ require 'prometheus/client'
4
+ require 'prometheus/client/push'
5
+
6
+ begin
7
+ require 'thor'
8
+ rescue Gem::GemNotFoundException
9
+ $stderr.puts "Loadind error, it's like you try to run Splash, with a lake of dependencies."
10
+ $stderr.puts "If you run on RVM, please run with rvmsudo and not with sudo."
11
+ $stderr.puts "If problem is percistant, please, proceed to new install and Setup."
12
+ end
13
+
14
+ require 'yaml'
15
+
16
+ require 'splash/constants'
17
+ require 'splash/helpers'
18
+ require 'splash/config'
19
+
20
+ require 'splash/command'
21
+ require 'splash/logs'
22
+ require 'splash/controller'
23
+
24
+ #inhibit warning : due to prometheus-client call to URI.encode warning
25
+ $-w = nil
26
+
27
+ include Splash::Helpers
28
+
29
+ module CLISplash
30
+
31
+
32
+ class Commands < Thor
33
+
34
+ option :ack, :type => :boolean
35
+ desc "wrap NAME", "wrapping for command or ack result"
36
+ def wrap(name)
37
+ command = Splash::CommandWrapper::new(name)
38
+ command.ack if options[:ack]
39
+ command.call_and_notify
40
+ end
41
+ end
42
+
43
+
44
+ class CLIController < Thor
45
+ include Splash::LogsMonitor::DaemonController
46
+
47
+ option :foreground, :type => :boolean
48
+ desc "start", "Starting Logs Monitor Daemon"
49
+ def start
50
+ run_as_root :startdaemon
51
+ end
52
+
53
+ desc "stop", "Stopping Logs Monitor Daemon"
54
+ def stop
55
+ run_as_root :stopdaemon
56
+ end
57
+
58
+
59
+ end
60
+
61
+ class Config < Thor
62
+ include Splash::Config
63
+ include Splash::Helpers
64
+
65
+ desc "setup", "Setup installation fo Splash"
66
+ def setup
67
+ run_as_root :setupsplash
68
+
69
+ end
70
+
71
+ desc "sanitycheck", "Verify installation fo Splash"
72
+ def sanitycheck
73
+ run_as_root :checkconfig
74
+ end
75
+
76
+ desc "version", "display current Splash version"
77
+ def version
78
+ config = get_config
79
+ puts "Splash version : #{config.version}, Author : #{config.author}"
80
+ puts config.copyright
81
+ end
82
+
83
+
84
+ end
85
+
86
+
87
+ class Logs < Thor
88
+
89
+ desc "analyse", "analyze logs in config"
90
+ def analyse
91
+ result = Splash::LogScanner::new
92
+ result.analyse
93
+ p result.output
94
+ end
95
+
96
+ desc "monitor", "monitor logs in config"
97
+ def monitor
98
+ result = Splash::LogScanner::new
99
+ result.analyse
100
+ result.notify
101
+ end
102
+
103
+
104
+ end
105
+ end
106
+
107
+ class CLI < Thor
108
+ def self.exit_on_failure?
109
+ true
110
+ end
111
+
112
+ include CLISplash
113
+ desc "commands SUBCOMMAND ...ARGS", "Managing commands/batchs supervision"
114
+ subcommand "commands", Commands
115
+ desc "logs SUBCOMMAND ...ARGS", "Managing Files/Logs supervision"
116
+ subcommand "logs", Logs
117
+ desc "daemon SUBCOMMAND ...ARGS", "Logs monitor daemon contoller"
118
+ subcommand "daemon", CLIController
119
+ desc "config SUBCOMMAND ...ARGS", "config tools for Splash"
120
+ subcommand "config", Config
121
+ end
122
+
123
+
124
+
125
+
126
+
127
+
128
+ CLI.start(ARGV)
data/config/splash.yml ADDED
@@ -0,0 +1,17 @@
1
+ :splash:
2
+ :logs:
3
+ - :log: /tmp/test
4
+ :pattern: ERROR
5
+ - :log: /var/log/message
6
+ :pattern: error
7
+ :daemon:
8
+ :user: daemon
9
+ :group: daemon
10
+ :process_name: "Splash : Prometheus logs monitoring."
11
+ :paths:
12
+ :pid_path: /tmp
13
+ :trace_path: /tmp/splash
14
+ :files:
15
+ :stdout_trace: stdout.txt
16
+ :stderr_trace: stderr.txt
17
+ :pid_file: splash.pid
@@ -0,0 +1,29 @@
1
+ module Splash
2
+ class CommandWrapper
3
+ def initialize(name)
4
+ @name = name
5
+ end
6
+
7
+ def ack
8
+ puts "Sending ack for command : '#{@name}'"
9
+ notify(0)
10
+ exit 0
11
+ end
12
+
13
+ def notify(value)
14
+ registry = Prometheus::Client.registry
15
+ metric = Prometheus::Client::Gauge.new(:errorcode, docstring: 'SPLASH metric batch errorcode')
16
+ registry.register(metric)
17
+ metric.set(value)
18
+ Prometheus::Client::Push.new(@name).add(registry)
19
+ end
20
+
21
+
22
+ def call_and_notify
23
+ puts "Executing command : '#{@name}' and notify Prometheus PushGateway"
24
+ system("#{@name} > /dev/null")
25
+ exit_code = $?.exitstatus
26
+ notify(exit_code)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,151 @@
1
+ module Splash
2
+ module Config
3
+ include Splash::Helpers
4
+ include Splash::Constants
5
+
6
+
7
+
8
+ class Configuration < Hash
9
+ include Splash::Constants
10
+ def initialize(config_file=CONFIG_FILE)
11
+ config_from_file = readconf config_file
12
+ self[:version] = VERSION
13
+ self[:author] = "#{AUTHOR} <#{EMAIL}>"
14
+ self[:copyright] = "#{COPYRIGHT} #{LICENSE}"
15
+ self[:daemon_process_name] = (config_from_file[:daemon][:process_name])? config_from_file[:daemon][:process_name] : DAEMON_PROCESS_NAME
16
+ self[:daemon_user] = (config_from_file[:daemon][:user])? config_from_file[:daemon][:user] : DAEMON_USER
17
+ self[:daemon_group] = (config_from_file[:daemon][:group])? config_from_file[:daemon][:group] : DAEMON_GROUP
18
+ self[:pid_path] = (config_from_file[:daemon][:paths][:pid_path])? config_from_file[:daemon][:paths][:pid_path] : PID_PATH
19
+ self[:trace_path] = (config_from_file[:daemon][:paths][:trace_path])? config_from_file[:daemon][:paths][:trace_path] : TRACE_PATH
20
+ self[:pid_file] = (config_from_file[:daemon][:files][:pid_file])? config_from_file[:daemon][:files][:pid_file] : PID_FILE
21
+ self[:stdout_trace] = (config_from_file[:daemon][:files][:stdout_trace])? config_from_file[:daemon][:files][:stdout_trace] : STDOUT_TRACE
22
+ self[:stderr_trace] = (config_from_file[:daemon][:files][:stderr_trace])? config_from_file[:daemon][:files][:stderr_trace] : STDERR_TRACE
23
+ self[:logs] = (config_from_file[:logs])? config_from_file[:logs] : {}
24
+ end
25
+
26
+ def logs
27
+ return self[:logs]
28
+ end
29
+
30
+ def author
31
+ return self[:author]
32
+ end
33
+
34
+ def copyright
35
+ return self[:copyright]
36
+ end
37
+
38
+ def version
39
+ return self[:version]
40
+ end
41
+
42
+ def daemon_process_name
43
+ return self[:daemon_process_name]
44
+ end
45
+
46
+ def daemon_user
47
+ return self[:daemon_user]
48
+ end
49
+
50
+ def daemon_group
51
+ return self[:daemon_group]
52
+ end
53
+
54
+ def full_pid_path
55
+ return "#{self[:pid_path]}/#{self[:pid_file]}"
56
+ end
57
+
58
+ def full_stdout_trace_path
59
+ return "#{self[:trace_path]}/#{self[:stdout_trace]}"
60
+ end
61
+
62
+ def full_stderr_trace_path
63
+ return "#{self[:trace_path]}/#{self[:stderr_trace]}"
64
+ end
65
+
66
+ private
67
+ def readconf(file = CONFIG_FILE)
68
+ return YAML.load_file(file)[:splash]
69
+ end
70
+
71
+
72
+ end
73
+
74
+
75
+ def get_config(config_file=CONFIG_FILE)
76
+ return Configuration::new config_file
77
+ end
78
+
79
+
80
+ def setupsplash
81
+ conf_in_path = search_file_in_gem "splash", "config/splash.yml"
82
+
83
+ print "* Installing Configuration file : #{CONFIG_FILE} : "
84
+ if install_file source: conf_in_path, target: CONFIG_FILE, mode: "644", owner: "root", group: "wheel" then
85
+ puts "[OK]"
86
+ else
87
+ puts "[KO]"
88
+ end
89
+ config = get_config
90
+
91
+ print "* Checking pid file path : #{config[:pid_path]}"
92
+ if make_folder path: config[:pid_path], mode: "644", owner: "root", group: "wheel" then
93
+ puts "[OK]"
94
+ else
95
+ puts "[KO]"
96
+ end
97
+
98
+ print "* Checking trace file path : #{config[:trace_path]}"
99
+ if make_folder path: config[:trace_path], mode: "777", owner: config.daemon_user, group: config.daemon_group then
100
+ puts "[OK]"
101
+ else
102
+ puts "[KO]"
103
+ end
104
+
105
+ puts "Splash config done. "
106
+
107
+ end
108
+
109
+ def checkconfig
110
+ config = get_config
111
+ print "Config file : #{CONFIG_FILE}"
112
+ res = verify_file(name: CONFIG_FILE, mode: "644", owner: "root", group: "wheel")
113
+ if res.empty? then
114
+ print "[OK]\n"
115
+ else
116
+ print "[KO]\n"
117
+ print res
118
+ end
119
+
120
+
121
+ end
122
+
123
+ private
124
+
125
+ def search_file_in_gem(_gem,_file)
126
+ if Gem::Specification.respond_to?(:find_by_name)
127
+ begin
128
+ spec = Gem::Specification.find_by_name(_gem)
129
+ rescue LoadError
130
+ spec = nil
131
+ end
132
+ else
133
+ spec = Gem.searcher.find(_gem)
134
+ end
135
+ if spec then
136
+ if Gem::Specification.respond_to?(:find_by_name)
137
+ res = spec.lib_dirs_glob.split('/')
138
+ else
139
+ res = Gem.searcher.lib_dirs_for(spec).split('/')
140
+ end
141
+ res.pop
142
+ services_path = res.join('/').concat("/#{_file}")
143
+ return services_path if File::exist?(services_path)
144
+ return false
145
+ else
146
+ return false
147
+ end
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,18 @@
1
+ module Splash
2
+ module Constants
3
+ VERSION = "0.0.1"
4
+ CONFIG_FILE = "/etc/splash.yml"
5
+ DAEMON_USER = "root"
6
+ DAEMON_GROUP = "wheel"
7
+ PID_PATH="/var/run"
8
+ TRACE_PATH="/var/run/splash"
9
+ PID_FILE="splash.pid"
10
+ STDOUT_TRACE="stdout.txt"
11
+ STDERR_TRACE="stderr.txt"
12
+ DAEMON_PROCESS_NAME="Splash : Prometheus logs monitoring."
13
+ AUTHOR="Romain GEORGES"
14
+ EMAIL = "gems@ultragreen.net"
15
+ COPYRIGHT="Ultragreen (c) 2020"
16
+ LICENSE="BSD-2-Clause"
17
+ end
18
+ end
@@ -0,0 +1,48 @@
1
+
2
+ module Splash
3
+ module LogsMonitor
4
+ module DaemonController
5
+ include Splash::Constants
6
+ include Splash::Helpers
7
+ include Splash::Config
8
+
9
+ def startdaemon(options = {})
10
+ config = get_config
11
+ unless File::exist? config.full_pid_path then
12
+ return daemonize :description => config.daemon_process_name,
13
+ :pid_file => config.full_pid_path,
14
+ :daemon_user => config.daemon_user,
15
+ :daemon_group => config.daemon_group,
16
+ :stdout_trace => config.full_stdout_trace_path,
17
+ :stderr_trace => config.full_stderr_trace_path do
18
+ result = LogScanner::new
19
+ while true
20
+ sleep 5
21
+ puts "Notify"
22
+ result.analyse
23
+ result.notify
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def stopdaemon(options = {})
30
+ config = get_config
31
+ if File.exist?(config.full_pid_path) then
32
+
33
+ begin
34
+ pid = `cat #{config.full_pid_path}`.to_i
35
+ Process.kill("TERM", pid)
36
+ rescue Errno::ESRCH
37
+ $stderr.puts "Process of PID : #{pid} not found"
38
+ end
39
+ FileUtils::rm config.full_pid_path if File::exist? config.full_pid_path
40
+ return true
41
+ else
42
+ return false
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,205 @@
1
+ # coding: utf-8
2
+ require 'fileutils'
3
+ require 'etc'
4
+
5
+ # coding: utf-8
6
+ module Splash
7
+ module Helpers
8
+
9
+ def is_root?
10
+ case (Process.uid)
11
+ when 0
12
+ return true
13
+ else
14
+ return false
15
+ end
16
+ end
17
+
18
+ def run_as_root(method)
19
+ unless is_root?
20
+ $stderr.puts "You need to be root to execute this subcommands : #{method.to_s}"
21
+ $stderr.puts "Please execute with sudo, or rvmsudo."
22
+ exit 10
23
+ else
24
+ self.send method
25
+ end
26
+ end
27
+
28
+ # method for daemonize blocks
29
+ # @param [Hash] _options the list of options, keys are symbols
30
+ # @option _options [String] :description the description of the process, use for $0
31
+ # @option _options [String] :pid_file the pid filenam
32
+ # @yield a process definion or block given
33
+ # @example usage inline
34
+ # class Test
35
+ # include Splash::Helpers::Application
36
+ # private :daemonize
37
+ # def initialize
38
+ # @loop = Proc::new do
39
+ # loop do
40
+ # sleep 1
41
+ # end
42
+ # end
43
+ # end
44
+ #
45
+ # def run
46
+ # daemonize({:description => "A loop daemon", :pid_file => '/tmp/pid.file'}, &@loop)
47
+ # end
48
+ # end
49
+ #
50
+ # @example usage block
51
+ # class Test
52
+ # include Splash::Helpers::Application
53
+ # include Dorsal::Privates
54
+ # private :daemonize
55
+ # def initialize
56
+ # end
57
+ #
58
+ # def run
59
+ # daemonize :description => "A loop daemon", :pid_file => '/tmp/pid.file' do
60
+ # loop do
61
+ # sleep 1
62
+ # end
63
+ # end
64
+ # end
65
+ # end
66
+ # @return [Fixnum] pid the pid of the forked processus
67
+ def daemonize(options)
68
+ #Process.euid = 0
69
+ #Process.egid = 0
70
+ return yield if options[:debug]
71
+ trap("SIGINT"){ exit! 0 }
72
+ trap("SIGTERM"){ exit! 0 }
73
+ trap("SIGHUP"){ exit! 0 }
74
+
75
+ fork do
76
+ #Process.daemon
77
+ File.open(options[:pid_file],"w"){|f| f.puts Process.pid } if options[:pid_file]
78
+ uid = Etc.getpwnam(options[:daemon_user]).uid
79
+ gid = Etc.getgrnam(options[:daemon_group]).gid
80
+ Process::UID.change_privilege(uid)
81
+ # Process::GID.change_privilege(gid)
82
+ $stdout.reopen(options[:stdout_trace], "w")
83
+ $stderr.reopen(options[:stderr_trace], "w")
84
+
85
+ #$0 = options[:description]
86
+ Process.setproctitle options[:description]
87
+
88
+ yield
89
+
90
+ end
91
+ return true
92
+ end
93
+
94
+ # @!group facilités sur le système de fichier
95
+
96
+ # facilité d'installation de fichier
97
+ # @param [Hash] options
98
+ # @option options [String] :source le chemin source du fichier
99
+ # @option options [String] :target le chemin cible du fichier
100
+ def install_file(options = {})
101
+ #begin
102
+ FileUtils::copy options[:source], options[:target] #unless File::exist? options[:target]
103
+ FileUtils.chmod options[:mode].to_i(8), options[:target] if options[:mode]
104
+ FileUtils.chown options[:owner], options[:group], options[:target] if options[:owner] and options[:group]
105
+ return true
106
+ #rescue StandardError
107
+ # return false
108
+ #end
109
+ end
110
+
111
+ # facilité de création de répertoire
112
+ # @param [Hash] options
113
+ # @option options [String] :path le répertoire à créer (relatif ou absolut)
114
+ def make_folder(options = {})
115
+ begin
116
+ FileUtils::mkdir_p options[:path] unless File::exist? options[:path]
117
+ FileUtils.chmod options[:mode].to_i(8), options[:path] if options[:mode]
118
+ FileUtils.chown options[:owner], options[:group], options[:path] if options[:owner] and options[:group]
119
+ return true
120
+ rescue StandardError
121
+ return false
122
+ end
123
+ end
124
+
125
+ # facilité de liaison symbolique de fichier
126
+ # @param [Hash] options
127
+ # @option options [String] :source le chemin source du fichier
128
+ # @option options [String] :link le chemin du lien symbolique
129
+ def make_link(options = {})
130
+ begin
131
+ FileUtils::rm options[:link] if (File::symlink? options[:link] and not File::exist? options[:link])
132
+ FileUtils::ln_s options[:source], options[:link] unless File::exist? options[:link]
133
+ return true
134
+ rescue StandardError
135
+ return false
136
+ end
137
+ end
138
+ # @!endgroup
139
+
140
+
141
+ #@!group Vérifiers de l'application
142
+
143
+ # verifier d'existence d'un repertoire
144
+ # @return [Bool] vrai ou faux
145
+ # @param [Hash] options
146
+ # @option options [String] :path le répertoire à créer (relatif ou absolut)
147
+ def verify_folder(options ={})
148
+ return File.directory?(options[:path])
149
+ end
150
+
151
+ # verifier d'existence d'un lien
152
+ # @return [Bool] vrai ou faux
153
+ # @param [Hash] options
154
+ # @option options [String] :name path du lien
155
+ def verify_link(options ={})
156
+ return File.file?(options[:name])
157
+ end
158
+
159
+ # verifier d'existence d'un fichier
160
+ # @return [Bool] vrai ou faux
161
+ # @param [Hash] options
162
+ # @option options [String] :name path du fichier
163
+ def verify_file(options ={})
164
+ res = Array::new
165
+ return [:inexistant] unless File.file?(options[:name])
166
+ stat = File.stat(options[:name])
167
+ if options[:mode] then
168
+ mode = "%o" % stat.mode
169
+ res << :mode if mode[-3..-1] != options[:mode]
170
+ end
171
+ if options[:owner] then
172
+ res << :owner if Etc.getpwuid(stat.uid).name != options[:owner]
173
+ end
174
+ if options[:group] then
175
+ res << :group if Etc.getgrgid(stat.gid).name != options[:group]
176
+ end
177
+ return res
178
+ end
179
+
180
+ # verifier de l'ecoute d'un service sur un host et port donné en TCP
181
+ # @return [Bool] vrai ou faux
182
+ # @param [Hash] options
183
+ # @option options [String] :host le nom d'hote
184
+ # @option options [String] :port le port TCP
185
+ def verify_service(options ={})
186
+ begin
187
+ Timeout::timeout(1) do
188
+ begin
189
+ s = TCPSocket.new(options[:host], options[:port])
190
+ s.close
191
+ return true
192
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
193
+ return false
194
+ end
195
+ end
196
+ rescue Timeout::Error
197
+ return false
198
+ end
199
+ end
200
+ #!@endgroup
201
+
202
+
203
+
204
+ end
205
+ end
@@ -0,0 +1,39 @@
1
+ module Splash
2
+ class LogScanner
3
+ include Splash::Constants
4
+ include Splash::Config
5
+
6
+ def initialize
7
+ @logs_target = get_config.logs
8
+
9
+ @registry = Prometheus::Client.registry
10
+ @metric = Prometheus::Client::Gauge.new(:logerror, docstring: 'SPLASH metric log error', labels: [:log ])
11
+ @registry.register(@metric)
12
+ end
13
+
14
+ def analyse
15
+ @logs_target.each do |record|
16
+ record[:count]=0 if record[:count].nil?
17
+ record[:status] = :clean if record[:status].nil?
18
+ if File.exist?(record[:log]) then
19
+ record[:count] = File.readlines(record[:log]).grep(/#{record[:pattern]}/).size
20
+ record[:status] = :matched if record[:count] > 0
21
+ else
22
+ record[:status] = :mssing
23
+ end
24
+ end
25
+ end
26
+
27
+ def output
28
+ return @logs_target
29
+ end
30
+
31
+ def notify
32
+ @logs_target.each do |item|
33
+ @metric.set(item[:count], labels: { log: item[:log] })
34
+ end
35
+ Prometheus::Client::Push.new('Splash').add(@registry)
36
+ end
37
+
38
+ end
39
+ end
data/splash.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'splash/constants'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "prometheus-splash"
8
+ spec.version = Splash::Constants::VERSION
9
+ spec.authors = [Splash::Constants::AUTHOR]
10
+ spec.email = [Splash::Constants::EMAIL]
11
+ spec.description = %q{Prometheus Logs and Batchs supervision over PushGateway}
12
+ spec.summary = %q{Supervision with Prometheus of Logs and Asynchronous tasks for Services or Hosts }
13
+ spec.homepage = "http://www.ultragreen.net"
14
+ spec.license = Splash::Constants::LICENSE
15
+ spec.require_paths << 'bin'
16
+ spec.bindir = 'bin'
17
+ spec.executables = Dir["bin/*"].map!{|item| item.gsub("bin/","")}
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+ spec.add_runtime_dependency 'thor','~> 1.0.1'
23
+ spec.add_runtime_dependency 'prometheus-client','~> 2.0.0'
24
+ spec.add_development_dependency 'rake', '~> 13.0.1'
25
+ spec.add_development_dependency 'rspec', '~> 3.9.0'
26
+ spec.add_development_dependency 'yard', '~> 0.9.24'
27
+ spec.add_development_dependency 'rdoc', '~> 6.2.1'
28
+ spec.add_development_dependency 'roodi', '~> 5.0.0'
29
+ spec.add_development_dependency 'code_statistics', '~> 0.2.13'
30
+ spec.add_development_dependency 'yard-rspec', '~> 0.1'
31
+
32
+
33
+ end
@@ -0,0 +1,20 @@
1
+ [Unit]
2
+ Description=Splash Daemon
3
+ After=network-online.target
4
+
5
+ [Service]
6
+ Type=simple
7
+
8
+ User=splash
9
+ Group=splash
10
+ UMask=007
11
+
12
+ ExecStart=/splash daemon start
13
+
14
+ Restart=on-failure
15
+
16
+ # Configures the time to wait before service is stopped forcefully.
17
+ TimeoutStopSec=300
18
+
19
+ [Install]
20
+ WantedBy=multi-user.target
@@ -0,0 +1,25 @@
1
+ AssignmentInConditionalCheck:
2
+ CaseMissingElseCheck:
3
+ ClassLineCountCheck:
4
+ line_count: 300
5
+ ClassNameCheck:
6
+ pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
7
+ #ClassVariableCheck:
8
+ CyclomaticComplexityBlockCheck:
9
+ complexity: 5
10
+ CyclomaticComplexityMethodCheck:
11
+ complexity: 10
12
+ EmptyRescueBodyCheck:
13
+ ForLoopCheck:
14
+ MethodLineCountCheck:
15
+ line_count: 30
16
+ MethodNameCheck:
17
+ pattern: !ruby/regexp /^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
18
+ # MissingForeignKeyIndexCheck:
19
+ ModuleLineCountCheck:
20
+ line_count: 500
21
+ ModuleNameCheck:
22
+ pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
23
+ ParameterNumberCheck:
24
+ parameter_count: 5
25
+
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prometheus-splash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Romain GEORGES
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: prometheus-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 13.0.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 13.0.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.9.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.9.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.24
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.24
83
+ - !ruby/object:Gem::Dependency
84
+ name: rdoc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 6.2.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 6.2.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: roodi
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 5.0.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 5.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: code_statistics
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.2.13
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.2.13
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.1'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.1'
139
+ description: Prometheus Logs and Batchs supervision over PushGateway
140
+ email:
141
+ - gems@ultragreen.net
142
+ executables:
143
+ - splash
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - Gemfile
148
+ - LICENSE.txt
149
+ - README.md
150
+ - Rakefile
151
+ - bin/splash
152
+ - config/splash.yml
153
+ - lib/splash/command.rb
154
+ - lib/splash/config.rb
155
+ - lib/splash/constants.rb
156
+ - lib/splash/controller.rb
157
+ - lib/splash/helpers.rb
158
+ - lib/splash/logs.rb
159
+ - splash.gemspec
160
+ - templates/splashd.service
161
+ - ultragreen_roodi_coding_convention.yml
162
+ homepage: http://www.ultragreen.net
163
+ licenses:
164
+ - BSD-2-Clause
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubygems_version: 3.1.2
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: Supervision with Prometheus of Logs and Asynchronous tasks for Services or
185
+ Hosts
186
+ test_files: []