notifyme 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/INSTALL +1 -0
- data/README.rdoc +30 -0
- data/bin/notifyme +5 -0
- data/bin/notifyme_daemon +5 -0
- data/lib/notifyme/log/file.rb +15 -0
- data/lib/notifyme/log/mail.rb +61 -0
- data/lib/notifyme/log/stdout.rb +10 -0
- data/lib/notifyme/log.rb +84 -0
- data/lib/notifyme/start.rb +85 -0
- data/lib/notifyme/task.rb +22 -0
- data/lib/notifyme.rb +3 -0
- data/lib/vendor/smtp_add_tls_support.rb +113 -0
- data/notifyme_config.rb +46 -0
- metadata +111 -0
data/CHANGELOG
ADDED
data/INSTALL
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
See the README file.
|
data/README.rdoc
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
== Introduction
|
2
|
+
|
3
|
+
NotifyMe is a script running as a cronjob in background, can take care more than one tasks (by Ruby Threads), and push the result to different endpoints(stdout, mail, file etc.) with different formats such as xml, json, csv etc. depends on what's you need.
|
4
|
+
|
5
|
+
== Instalation
|
6
|
+
|
7
|
+
gem install notifyme
|
8
|
+
|
9
|
+
== Run it
|
10
|
+
|
11
|
+
# run in the background
|
12
|
+
$ notifyme_daemon start -- /path/to/notifyme_config.rb
|
13
|
+
|
14
|
+
# debug (use Ctrl + C to stop it)
|
15
|
+
$ notifyme_daemon run -- /path/to/notifyme_config.rb
|
16
|
+
|
17
|
+
# stop
|
18
|
+
$ notifyme_daemon stop
|
19
|
+
|
20
|
+
== Output
|
21
|
+
|
22
|
+
The output from every task's command will be processed (send to endpoint) only if the output is not empty, otherwise do noghing.
|
23
|
+
|
24
|
+
== Version
|
25
|
+
|
26
|
+
v 0.1-dev
|
27
|
+
|
28
|
+
== Author
|
29
|
+
|
30
|
+
xianhua.zhou@gmail.com
|
data/bin/notifyme
ADDED
data/bin/notifyme_daemon
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module NotifyMe
|
2
|
+
module Log
|
3
|
+
class File < Logger
|
4
|
+
def <<(task)
|
5
|
+
file_path = @parameters.is_a?(String) ?
|
6
|
+
@parameters : @parameters[:path]
|
7
|
+
|
8
|
+
::File.open(file_path, 'a') do |f|
|
9
|
+
f.write generate(task)
|
10
|
+
f.write "\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module NotifyMe
|
2
|
+
module Log
|
3
|
+
class Mail < Logger
|
4
|
+
def <<(task)
|
5
|
+
require 'vendor/smtp_add_tls_support.rb'
|
6
|
+
|
7
|
+
param = @parameters
|
8
|
+
param = {} unless param.is_a?(Hash)
|
9
|
+
|
10
|
+
# some default settings
|
11
|
+
|
12
|
+
default_host = 'localhost'
|
13
|
+
if param[:tls]
|
14
|
+
default_port = 587
|
15
|
+
Net::SMTP.enable_tls
|
16
|
+
else
|
17
|
+
default_port = 25
|
18
|
+
Net::SMTP.disable_tls
|
19
|
+
end
|
20
|
+
|
21
|
+
default_from_email = 'notifyme@' + default_host
|
22
|
+
|
23
|
+
param[:subject] = "NotifyMe report: %s"
|
24
|
+
param[:subject] = param[:subject] % task.name
|
25
|
+
|
26
|
+
param[:from_email] ||= param[:account]
|
27
|
+
param[:from_email] ||= default_from_email
|
28
|
+
|
29
|
+
param[:body] = param[:body_header].to_s +
|
30
|
+
generate(task) +
|
31
|
+
param[:body_footer].to_s
|
32
|
+
|
33
|
+
smtp = Net::SMTP.new(
|
34
|
+
(param[:address] || param[:host]) || default_host,
|
35
|
+
param[:port] || default_port
|
36
|
+
)
|
37
|
+
|
38
|
+
# go go go!
|
39
|
+
smtp.start(param[:helo_domain] || default_host,
|
40
|
+
param[:account],
|
41
|
+
param[:password],
|
42
|
+
param[:authtype] || :plain) do |mail|
|
43
|
+
mail.send_message message(param, task), param[:from_email], param[:to_email]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def message(param, task)
|
49
|
+
time = Time.now
|
50
|
+
"From: #{param[:from_name] || param[:from_email]} <#{param[:from_email]}>\r\n" \
|
51
|
+
<< "To: #{param[:to_name] || param[:to_email]} <#{param[:to_email]}>\r\n" \
|
52
|
+
<< "Subject: #{param[:subject]}\r\n" \
|
53
|
+
<< "Date: #{time.to_s}\r\n" \
|
54
|
+
<< "Content-type: text/plain; charset=UTF-8\r\n" \
|
55
|
+
<< "Message-Id: <notifyme.#{task.name}.#{time.to_i}@example.com>\r\n" \
|
56
|
+
<< "\r\n" \
|
57
|
+
<< param[:body]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/notifyme/log.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module NotifyMe
|
2
|
+
module Log
|
3
|
+
class Base
|
4
|
+
@logger = nil
|
5
|
+
@parameters = {}
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@logger = args.first.to_s.downcase
|
9
|
+
@parameters = args.last
|
10
|
+
end
|
11
|
+
|
12
|
+
def logger
|
13
|
+
begin
|
14
|
+
require "notifyme/log/#{@logger}.rb"
|
15
|
+
rescue Exception => e
|
16
|
+
end
|
17
|
+
NotifyMe::Log.const_get(@logger.capitalize).new @parameters
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.default
|
21
|
+
require 'notifyme/log/stdout.rb'
|
22
|
+
NotifyMe::Log::Stdout.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Logger
|
27
|
+
def initialize(parameters = {})
|
28
|
+
@parameters = parameters
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def generate(task)
|
33
|
+
method("to_#{task.log_format}").call task
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def to_json(task)
|
39
|
+
require 'json'
|
40
|
+
JSON to_hash(task)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_xml(task)
|
44
|
+
require 'rexml/document'
|
45
|
+
xml = REXML::Element.new 'task'
|
46
|
+
fields.each do |f|
|
47
|
+
el = REXML::Element.new f.to_s
|
48
|
+
el.text = task.send(f)
|
49
|
+
xml.add_element el
|
50
|
+
end
|
51
|
+
xml.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_csv(task)
|
55
|
+
require 'csv'
|
56
|
+
row = []
|
57
|
+
fields.each do |f|
|
58
|
+
row << task.send(f)
|
59
|
+
end
|
60
|
+
CSV.generate_line row
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_text(task)
|
64
|
+
output = ''
|
65
|
+
fields.each do |f|
|
66
|
+
output << "#{f}: #{task.send(f)}\n"
|
67
|
+
end
|
68
|
+
output << "\n"
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_hash(task)
|
72
|
+
hash = {}
|
73
|
+
fields.each do |f|
|
74
|
+
hash[f] = task.send(f)
|
75
|
+
end
|
76
|
+
hash
|
77
|
+
end
|
78
|
+
|
79
|
+
def fields
|
80
|
+
[:name, :sleep_time, :start_run_time, :end_run_time, :result]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module NotifyMe
|
2
|
+
|
3
|
+
VERSION = '0.1'
|
4
|
+
|
5
|
+
autoload :Task, 'notifyme/task'
|
6
|
+
autoload :Log, 'notifyme/log'
|
7
|
+
|
8
|
+
class Start
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# log
|
12
|
+
@@log_args = nil
|
13
|
+
@@log_format = nil
|
14
|
+
|
15
|
+
# tasks list
|
16
|
+
@@tasks = []
|
17
|
+
|
18
|
+
def run!
|
19
|
+
puts 'NotifyMe v' + NotifyMe::VERSION
|
20
|
+
new(ARGV[0]).run
|
21
|
+
end
|
22
|
+
|
23
|
+
def config(&block)
|
24
|
+
class_eval &block
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def task(name)
|
30
|
+
raise 'Invalid task calls' unless block_given?
|
31
|
+
task = Task.new
|
32
|
+
task.name = name
|
33
|
+
task.logger ||= NotifyMe::Log::Base.new(@@log_args).logger
|
34
|
+
task.log_format ||= @@log_format
|
35
|
+
yield task
|
36
|
+
@@tasks << task
|
37
|
+
end
|
38
|
+
|
39
|
+
def log(*args)
|
40
|
+
@@log_args = args
|
41
|
+
end
|
42
|
+
|
43
|
+
def log_format(format)
|
44
|
+
@@log_format = format
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def run
|
49
|
+
tasks_thread = []
|
50
|
+
@mutex = Mutex.new
|
51
|
+
@@tasks.each do |task|
|
52
|
+
tasks_thread << Thread.new(task) do
|
53
|
+
loop do
|
54
|
+
Thread.current[:name] = task.name
|
55
|
+
sleep task.sleep_time
|
56
|
+
run_task(task) if task.command.respond_to? :call
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
tasks_thread.each do |t| t.join end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def run_task(task)
|
67
|
+
begin
|
68
|
+
task.start_run_time = Time.now.to_i
|
69
|
+
task.result = task.command.call
|
70
|
+
task.end_run_time = Time.now.to_i
|
71
|
+
rescue Exception => e
|
72
|
+
task.result = e.to_s
|
73
|
+
end
|
74
|
+
unless task.result.to_s.empty?
|
75
|
+
@mutex.synchronize do
|
76
|
+
task.logger << task
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def initialize(config_file)
|
82
|
+
require config_file
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module NotifyMe
|
2
|
+
class Task
|
3
|
+
attr_accessor :name, :sleep_time, :start_run_time, :end_run_time,
|
4
|
+
:logger, :command, :result,
|
5
|
+
:log_format
|
6
|
+
|
7
|
+
def command=(cmd)
|
8
|
+
return if cmd.nil?
|
9
|
+
|
10
|
+
unless cmd.is_a?(Proc)
|
11
|
+
cmd = cmd.new if cmd.class.is_a?(Class)
|
12
|
+
end
|
13
|
+
|
14
|
+
if cmd.respond_to? :call
|
15
|
+
@command = cmd
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
raise 'Invalid command parameter'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/notifyme.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# http://happiness-is-slavery.net/wp-content/rails-plugins/smtp_add_tls_support/lib/smtp_add_tls_support.rb
|
2
|
+
|
3
|
+
require 'net/smtp'
|
4
|
+
require 'timeout'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'openssl'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
Net::SMTP.class_eval do
|
12
|
+
|
13
|
+
alias_method :old_initialize, :initialize
|
14
|
+
def initialize(hostname, port)
|
15
|
+
@usetls = @@usetls
|
16
|
+
old_initialize hostname, port
|
17
|
+
end
|
18
|
+
|
19
|
+
@@usetls = false
|
20
|
+
|
21
|
+
def self.enable_tls()
|
22
|
+
@@usetls = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.disable_tls()
|
26
|
+
@@usetls = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.use_tls?()
|
30
|
+
@@usetls
|
31
|
+
end
|
32
|
+
|
33
|
+
def use_tls?()
|
34
|
+
@usetls
|
35
|
+
end
|
36
|
+
|
37
|
+
def enable_tls()
|
38
|
+
@usetls = true
|
39
|
+
end
|
40
|
+
|
41
|
+
def disable_tls()
|
42
|
+
@usetls = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def use_tls?()
|
46
|
+
@usetls
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def do_start(helodomain, user, secret, authtype)
|
51
|
+
raise IOError 'SMTP session already started' if @started
|
52
|
+
check_auth_args user, secret if user or secret
|
53
|
+
|
54
|
+
sock = timeout(@open_timeout) {
|
55
|
+
TCPSocket.open(@address, @port)
|
56
|
+
}
|
57
|
+
@socket = Net::InternetMessageIO.new(sock)
|
58
|
+
@socket.read_timeout = @read_timeout
|
59
|
+
@socket.debug_output = nil
|
60
|
+
|
61
|
+
check_response(critical{
|
62
|
+
recv_response()
|
63
|
+
})
|
64
|
+
do_helo(helodomain)
|
65
|
+
|
66
|
+
if @usetls
|
67
|
+
raise 'openssl is not installed' unless defined?(OpenSSL)
|
68
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
69
|
+
starttls
|
70
|
+
ssl.sync_close = true
|
71
|
+
ssl.connect
|
72
|
+
|
73
|
+
@socket = Net::InternetMessageIO.new(ssl)
|
74
|
+
@socket.read_timeout = @read_timeout
|
75
|
+
@socket.debug_output = nil
|
76
|
+
do_helo(helodomain)
|
77
|
+
end
|
78
|
+
|
79
|
+
authenticate user, secret, authtype if user
|
80
|
+
@started = true
|
81
|
+
ensure
|
82
|
+
@socket.close if not @started and @socket and not @socket.closed?
|
83
|
+
end
|
84
|
+
|
85
|
+
def do_helo(helodomain)
|
86
|
+
begin
|
87
|
+
if @esmtp
|
88
|
+
ehlo helodomain
|
89
|
+
else
|
90
|
+
helo helodomain
|
91
|
+
end
|
92
|
+
rescue Net::ProtocolError
|
93
|
+
if @esmtp
|
94
|
+
@esmtp = false
|
95
|
+
@error_occured = false
|
96
|
+
retry
|
97
|
+
end
|
98
|
+
raise
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def starttls
|
103
|
+
getok('STARTTLS')
|
104
|
+
end
|
105
|
+
|
106
|
+
def quit
|
107
|
+
begin
|
108
|
+
getok('QUIT')
|
109
|
+
rescue EOFError
|
110
|
+
# gmail sucks
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/notifyme_config.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
class MyTask
|
2
|
+
def call
|
3
|
+
Time.now.to_s
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
NotifyMe::Start.config do
|
9
|
+
|
10
|
+
log :stdout
|
11
|
+
|
12
|
+
=begin
|
13
|
+
log :mail,
|
14
|
+
:host => 'smtp.gmail.com',
|
15
|
+
:helo_domain => 'gmail.com',
|
16
|
+
:tls => true,
|
17
|
+
|
18
|
+
:account => 'xxx@gmail.com',
|
19
|
+
:password => '***',
|
20
|
+
|
21
|
+
:from_email => 'from@gmail.com',
|
22
|
+
:from_name => 'from name',
|
23
|
+
:to_email => 'to@gmail.com',
|
24
|
+
:to_name => 'to name'
|
25
|
+
|
26
|
+
=end
|
27
|
+
# log :file, '/tmp/test.txt'
|
28
|
+
# log :stdout
|
29
|
+
# log :mail, :to_email => 'to@email.com'
|
30
|
+
|
31
|
+
# :csv, :text, :xml, :json
|
32
|
+
log_format :json
|
33
|
+
|
34
|
+
|
35
|
+
# add some tasks
|
36
|
+
|
37
|
+
task :checking_disk do |t|
|
38
|
+
t.sleep_time = 1
|
39
|
+
t.command = Proc.new { %x{df -h} }
|
40
|
+
end
|
41
|
+
|
42
|
+
task :checking_http do |t|
|
43
|
+
t.sleep_time = 2
|
44
|
+
t.command = MyTask
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: notifyme
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- xianhua.zhou
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-10 00:00:00 +08:00
|
18
|
+
default_executable: notifyme_daemon
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: daemons
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 19
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
version: 1.1.0
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: json_pure
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 4
|
48
|
+
- 2
|
49
|
+
version: 1.4.2
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
description: NotifyMe takes care more than one tasks and process their results for you, it's similar to the *NIX's cronjob.
|
53
|
+
email: xianhua.zhou@gmail.com
|
54
|
+
executables:
|
55
|
+
- notifyme_daemon
|
56
|
+
- notifyme
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- lib/notifyme/start.rb
|
63
|
+
- lib/notifyme/log.rb
|
64
|
+
- lib/notifyme/log/mail.rb
|
65
|
+
- lib/notifyme/log/file.rb
|
66
|
+
- lib/notifyme/log/stdout.rb
|
67
|
+
- lib/notifyme/task.rb
|
68
|
+
- lib/vendor/smtp_add_tls_support.rb
|
69
|
+
- lib/notifyme.rb
|
70
|
+
- README.rdoc
|
71
|
+
- CHANGELOG
|
72
|
+
- INSTALL
|
73
|
+
- notifyme_config.rb
|
74
|
+
- bin/notifyme
|
75
|
+
- bin/notifyme_daemon
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/xianhuazhou/NotifyMe
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: notifyme
|
106
|
+
rubygems_version: 1.3.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: It's a kind of cronjob.
|
110
|
+
test_files: []
|
111
|
+
|