post_remote_log 1.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,31 @@
1
+ = PostRemoteLog
2
+
3
+ Author:: Samuel Williams (http://www.oriontransfer.co.nz/)
4
+ Copyright:: Copyright (C) 2009 Samuel Williams
5
+ License:: GPLv3
6
+
7
+ PostRemoteLog installs a binary tool "post-remote-log" which collects data about the machine it is being run on, and sends it via XMLRPC or SMTP. It is useful in a system administration scenario when you want to measure statistics over a large number of machines. For example, you can use it as part of login and logout scripts to record when users are logging in and logging out. Additionally, this could record the time it took to log in, and then this could be measured as a performance statistic when deciding to upgrade servers, etc.
8
+
9
+ Another usage is for recording faults. For example, QuotaCheck.app can hook into post-remote-log to send a notification when a user bypasses the low quota warning. This means that you have a record of the warning, and when the user comes to complain about corrupt files (because the file was saved without enough free space on the users home directory), you can simply tell them to go away and free up space.
10
+
11
+ PostRemoteLog is very simple and all behavior is controlled using a configuration file. This configuration file specifies how to send the log file and all other details. Here is an example of how to send a log file:
12
+
13
+ $ echo "The user has logged in ($seconds)" > post-remote-log "User Event"
14
+ $ echo "The user has logged out" > post-remote-log "User Event"
15
+
16
+ The configuration file used by default is <tt>/etc/post-remote-log.yaml</tt> but can be specified using <tt>-c</tt> option.
17
+
18
+ $ echo "The user has logged out" > post-remote-log -c specific-config.yaml "User Event"
19
+
20
+ The command also integrates directly with <tt>daemon-exec</tt>. Ensure that rexec is installed before using this option.
21
+
22
+ $ echo "The user has logged out" > post-remote-log -d -c specific-config.yaml "User Event"
23
+
24
+ This command will relaunch itself using <tt>daemon-exec</tt> which allows the command to run seemlessly in the event of a network outage. The main use for this is when post-remote-log is used in login and logout scripts, which shouldn't be delayed if the network is slow.
25
+
26
+ Included with this package is a basic rack backend which can be used to aggregate the XMLRPC messages into a directory. This can be used for testing and evaluation. However, there is a web interface under development which stores information in a database.
27
+
28
+ To use the simple backend, you need to install thin:
29
+
30
+ $ sudo gem install thin
31
+ $ post-remote-log-server
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ if ARGV.delete("-d")
19
+ exec("daemon-exec", "--stdin", "--", $0, *ARGV)
20
+ end
21
+
22
+ require 'post_remote_log'
23
+ require 'post_remote_log/simple_xml'
24
+ require 'post_remote_log/methods/xmlrpc'
25
+ require 'post_remote_log/methods/email'
26
+
27
+ require 'yaml'
28
+
29
+ OPTIONS = {
30
+ :config => "/etc/post-remote-log.conf"
31
+ }
32
+
33
+ ARGV.options do |o|
34
+ script_name = File.basename($0)
35
+
36
+ o.set_summary_indent("\t")
37
+ o.banner = "Usage: #{script_name} [options] [classification] < log-data.txt"
38
+ o.define_head "Copyright (c) 2010 Samuel Williams <http://www.oriontransfer.co.nz/>."
39
+
40
+ o.on("-c config.yaml", String, "Configuration file; defaults to #{OPTIONS[:config]}") do |path|
41
+ OPTIONS[:config] = path
42
+ end
43
+
44
+ o.on("-d", "Run in background as a daemon. Requires daemon-exec.") do
45
+ # This option is handled above.
46
+ end
47
+ end.parse!
48
+
49
+ # Load the configuration
50
+ if File.exists?(OPTIONS[:config])
51
+ $config = YAML::load(File.read(OPTIONS[:config])).symbolize_keys
52
+ $config[:classification] ||= "Generic Log"
53
+ else
54
+ $stderr.puts "Error: Could not load configuration file #{OPTIONS[:config]}!"
55
+ raise
56
+ end
57
+
58
+ # Read the log information from stdin:
59
+ report = $stdin.read.strip
60
+ $stdin.close
61
+
62
+ if report.size == 0
63
+ $stderr.puts "Error: No report supplied, exiting!"
64
+ exit(1)
65
+ end
66
+
67
+ # Build a set of important values which will be logged:
68
+ $values = {
69
+ :classification => ARGV[0] || $config[:classification],
70
+ :uptime => `uptime`.strip,
71
+ :system => `uname -a`.strip,
72
+ :hostname => `hostname`.strip,
73
+ :address => `ifconfig`.match(/[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}:[0-9a-z]{2}/i)[0],
74
+ :user => `whoami`.strip,
75
+ :report => report
76
+ }
77
+
78
+ $methods = {
79
+ :xmlrpc => PostRemoteLog::Methods::XMLRPC,
80
+ :email => PostRemoteLog::Methods::Email
81
+ }
82
+
83
+ $config[:methods].values.each do |config|
84
+ begin
85
+ next if config[:disabled] == true
86
+
87
+ method = $methods[config[:method].to_sym]
88
+
89
+ method.send(config, $values)
90
+ rescue => ex
91
+ puts ex.to_s
92
+ puts ex.backtrace
93
+ end
94
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require 'rack'
19
+ require 'thin'
20
+
21
+ require 'post_remote_log'
22
+ require 'post_remote_log/server'
23
+
24
+
25
+ OPTIONS = {
26
+ :host => "0.0.0.0",
27
+ :port => "9080",
28
+ :dump_path => File.join(Dir.pwd, "logs")
29
+ }
30
+
31
+ Thin::Server.start(OPTIONS[:host], OPTIONS[:port], PostRemoteLog::Server.new(OPTIONS))
@@ -0,0 +1,16 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'post_remote_log/extensions'
@@ -0,0 +1,28 @@
1
+
2
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module HashExtensions
18
+ def symbolize_keys
19
+ inject({}) do |acc, (k,v)|
20
+ key = String === k ? k.to_sym : k
21
+ value = Hash === v ? v.symbolize_keys : v
22
+ acc[key] = value
23
+ acc
24
+ end
25
+ end
26
+ end
27
+
28
+ Hash.send(:include, HashExtensions)
@@ -0,0 +1,101 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'post_remote_log/xml'
17
+ require 'net/smtp'
18
+ require 'digest'
19
+
20
+ module PostRemoteLog
21
+ module Methods
22
+
23
+ class Email
24
+ def self.send(config, values)
25
+ message = PostRemoteLog.build_xml_message(values)
26
+
27
+ email = StringIO.new
28
+ marker = Digest::MD5.hexdigest(Time.now.to_s)
29
+
30
+ from = "#{values[:user]}@#{values[:hostname]}"
31
+ to = config[:to]
32
+
33
+ email.puts "From: #{from}"
34
+ email.puts "To: #{to}"
35
+ email.puts "Subject: Remote Log: #{values[:classification]}"
36
+ email.puts "MIME-Version: 1.0"
37
+ email.puts "Content-Type: multipart/mixed; boundary=#{marker}"
38
+ email.puts
39
+ email.puts "--#{marker}"
40
+ email.puts "Content-Type: text/plain"
41
+ email.puts "Content-Transfer-Encoding: 8bit"
42
+ email.puts
43
+ email.puts "A remote log was created and sent at #{Time.now.to_s}. Here are the details:"
44
+
45
+ [:classification, :user, :uptime, :system, :hostname, :address].each do |key|
46
+ email.puts "\t#{key}: #{values[key]}"
47
+ end
48
+
49
+ email.puts
50
+
51
+ email.puts values[:report]
52
+
53
+ email.puts
54
+ email.puts
55
+ email.puts "--#{marker}"
56
+ email.puts "Content-Type: text/xml; name=\"remote_log.xml\""
57
+ email.puts "Content-Transfer-Encoding:base64"
58
+ email.puts "Content-Disposition: attachment; filename=\"remote_log.xml\""
59
+ email.puts
60
+
61
+ email.puts [message.string].pack("m")
62
+
63
+ email.puts
64
+ email.puts "--#{marker}"
65
+ email.puts "Content-Type: text/plain; name=\"report.txt\""
66
+ email.puts "Content-Transfer-Encoding:base64"
67
+ email.puts "Content-Disposition: attachment; filename=\"report.txt\""
68
+ email.puts
69
+
70
+ email.puts [values[:report]].pack("m")
71
+
72
+ email.puts "--#{marker}--"
73
+
74
+ smtp = Net::SMTP.new(config[:host], config[:port])
75
+
76
+ begin
77
+ if config[:tls]
78
+ unless smtp.respond_to? :enable_starttls
79
+ raise ArgumentError.new("STARTTLS is not supported by this version of Ruby.")
80
+ end
81
+
82
+ context = Net::SMTP.default_ssl_context
83
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
84
+
85
+ smtp.enable_starttls(context)
86
+ end
87
+
88
+ smtp.start(values[:hostname], config[:user], config[:pass], config[:auth])
89
+
90
+ smtp.sendmail(email.string, from, [to])
91
+
92
+ $stderr.puts "Remote log created successfully."
93
+ ensure
94
+ smtp.finish
95
+ end
96
+ end
97
+ end
98
+
99
+ end
100
+ end
101
+
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'post_remote_log/xml'
17
+ require 'net/http'
18
+
19
+ module PostRemoteLog
20
+ module Methods
21
+
22
+ class XMLRPC
23
+ def self.send(config, values)
24
+ message = PostRemoteLog.build_xml_message(values)
25
+
26
+ Net::HTTP.start(config[:host], config[:port]) do |http|
27
+ response = http.post(config[:path], message.string, {"Content-Type" => "text/xml"})
28
+
29
+ unless (200...300).include?(response.code.to_i)
30
+ $stderr.puts "Could not create remote log record..."
31
+
32
+ $stderr.puts "Code: #{response.code}"
33
+ $stderr.puts "Message: #{response.message}"
34
+ $stderr.puts "Body:\n #{response.body}"
35
+ else
36
+ $stderr.puts "Remote log created successfully."
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'fileutils'
17
+ require 'time'
18
+
19
+ module PostRemoteLog
20
+
21
+ class Server
22
+ def initialize(config = {})
23
+ @dump_dir = config[:dump_path]
24
+
25
+ $stderr.puts "Dumping data to #{@dump_dir}"
26
+ FileUtils.mkdir_p(@dump_dir)
27
+ end
28
+
29
+ def call(env)
30
+ request = Rack::Request.new(env)
31
+
32
+ if request.post?
33
+ data = request.body().read()
34
+
35
+ now = Time.now
36
+ file_name = "#{now.strftime('%Y%m%d_%H%M%S')}_#{now.usec}.xml"
37
+ full_path = File.join(@dump_dir, file_name)
38
+
39
+ $stderr.puts "Writing data to #{file_name}..."
40
+
41
+ File.open(full_path, "w") { |f| f.write(data) }
42
+ end
43
+
44
+ return [200, {}, []]
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'stringio'
17
+
18
+ module PostRemoteLog
19
+
20
+ # Very simple XML builder to minimize dependencies:
21
+ class SimpleXMLBuilder < StringIO
22
+ X = {"<" => "&lt;", ">" => "&gt;"}
23
+
24
+ def initialize
25
+ super
26
+
27
+ @level = 0
28
+ end
29
+
30
+ def instruct!
31
+ self.puts '<?xml version="1.0" encoding="UTF-8"?>'
32
+ end
33
+
34
+ def value(name, value)
35
+ value.gsub!(/<|>/) { |s| X[s] }
36
+ self.puts tab + "<#{name}>" + value.to_s + "</#{name}>"
37
+ end
38
+
39
+ def tag(name, &block)
40
+ self.puts tab + "<#{name}>"
41
+ @level += 1
42
+ yield
43
+ @level -= 1
44
+ self.puts tab + "</#{name}>"
45
+ end
46
+
47
+ protected
48
+ def tab
49
+ ("\t" * @level)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module PostRemoteLog
17
+ module VERSION #:nodoc:
18
+ MAJOR = 1
19
+ MINOR = 6
20
+ TINY = 3
21
+
22
+ STRING = [MAJOR, MINOR, TINY].join('.')
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2009 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module PostRemoteLog
17
+
18
+ # Builds an XML formatted message from the supplied values
19
+ def self.build_xml_message (values)
20
+ message = SimpleXMLBuilder.new
21
+
22
+ message.instruct!
23
+
24
+ message.tag("remote_log") do
25
+ [:classification, :uptime, :system, :hostname, :address, :report].each do |key|
26
+ message.value key.to_s, values[key]
27
+ end
28
+ end
29
+
30
+ return message
31
+ end
32
+
33
+
34
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: post_remote_log
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 6
8
+ - 3
9
+ version: 1.6.3
10
+ platform: ruby
11
+ authors:
12
+ - Samuel Williams
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-13 00:00:00 +13:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rexec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description:
33
+ email:
34
+ executables:
35
+ - post-remote-log
36
+ - post-remote-log-server
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - README.rdoc
41
+ files:
42
+ - lib/post_remote_log/extensions.rb
43
+ - lib/post_remote_log/methods/email.rb
44
+ - lib/post_remote_log/methods/xmlrpc.rb
45
+ - lib/post_remote_log/server.rb
46
+ - lib/post_remote_log/simple_xml.rb
47
+ - lib/post_remote_log/version.rb
48
+ - lib/post_remote_log/xml.rb
49
+ - lib/post_remote_log.rb
50
+ - bin/post-remote-log
51
+ - bin/post-remote-log-server
52
+ - README.rdoc
53
+ has_rdoc: true
54
+ homepage: http://www.oriontransfer.co.nz/software/post-remote-log
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --main
60
+ - README.rdoc
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.6
81
+ signing_key:
82
+ specification_version: 2
83
+ summary: A simple messaging system built on top of Ruby, designed for system administration.
84
+ test_files: []
85
+