W
wmwilson01
I know I must be doing something dumb here, but I can't figure out
what, and I'm about to give up. I'm setting a trap("HUP") to call a
couple of functions (basically to re-read a config). The first time
running a "kill -HUP" on the process works fine, but the second time it
exits with a "hangup". If I modify the trap to look like:
trap("HUP") {
trap("HUP", "IGNORE")
fun1
fun2
}
It doesn't hangup, but only the first "kill -HUP" actually re-reads the
configuration.
This is ruby 1.8.1
Code follows:
<code>
require "yaml"
require "socket"
require "net/smtp"
require "file/tail"
require "getoptlong"
$config = {}
$reread = false
thishost = Socket.gethostname
tivenv = "/etc/Tivoli/setup_env.sh"
usetiv = false
daemon = false
logfile = nil
config_file = nil
opts = GetoptLong.new(
["--config-file", "-c", GetoptLong::REQUIRED_ARGUMENT],
["--daemon", "-d", GetoptLong::NO_ARGUMENT],
["--logfile", "-l", GetoptLong::REQUIRED_ARGUMENT]
)
logan_struct = Struct::new("LoganStruct",
attern, :tmout, :mailhost, :email, ost, :expire)
def daemonize()
fork and exit
Process.setsid
fork and exit
File.open("/dev/null", "r+") do |devnull|
$stdin.reopen(devnull)
$stdout.reopen(devnull)
$stderr.reopen(devnull)
end
Dir.chdir("/")
end
def source(file)
response_match = Regexp.new(/^([^=]*)=(.*)/)
`#{ENV['SHELL']} -c ". #{file}; set"`.each_line do |line|
if response_match.match(line)
k, v = line.gsub(/^([^=]*)=(.*)/, '\1 \2').split
ENV[k] = v
end
end
end
def parseYamlConfig(file)
if File.exists?(file) and File.stat(file).readable?
$config = YAML::load(File.open(file))
else
raise "Unusable file #{file}"
end
$config
end
def setDefaultConfigVals(tmout = 3600)
$config["patterns"].each do |pat|
pat.expire = 0
case pat.pattern
when String
pat.pattern = Regexp.new(pat.pattern)
end
if not pat.mailhost
if $config["mailhost"]
pat.mailhost = $config["mailhost"]
end
end
if not pat.tmout
if $config["tmout"]
pat.tmout = $config["tmout"]
else
pat.tmout = tmout
end
end
end
end
def lookForPatternsInLogfile(file)
if File.exists?(file) and File.stat(file).readable?
File::Tail::Logfile.open(file, :rewind=>0) do |log|
log.tail do |line|
$config["patterns"].each do |pat|
if pat.pattern.match(line)
yield pat, line
end
end
end
end
end
end
def sendMail(email, alert, host, mailhost = "mailhost")
message = <<EndOfMsg
Subject: Log Analyzer Alert for #{host}
To: #{email}
From: LOGAN
The following pattern match was made on #{host} at #{Time.now}
#{alert}
EndOfMsg
Net::SMTP.start(mailhost, 25) do |smtp|
smtp.send_mail(message, '"LOGAN"', email)
end
end
def postMessage(msg)
system("postemsg #{msg} > /dev/null 2>&1")
end
opts.each do |opt, arg|
case opt
when "--daemon"
daemon = true
when "--logfile"
logfile = File.expand_path(arg)
when "--config-file"
config_file = File.expand_path(arg)
end
end
if not logfile or not config_file
fail "Usage: #$0 [-d] -c config_file -l logfile"
end
trap("HUP") do
trap("HUP", "IGNORE")
parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
end
parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
daemonize if daemon
if File.exists?(tivenv)
source(tivenv)
usetiv = true
end
lookForPatternsInLogfile(logfile) do |pat, msg|
if pat.expire <= Time.now.to_i
pat.expire = 0
end
if pat.expire == 0
pat.expire = Time.now.to_i + pat.tmout
if pat.email
sendMail(pat.email, msg, thishost, pat.mailhost)
end
if pat.post
postMessage(pat.post) if usetiv
end
end
end
</code>
what, and I'm about to give up. I'm setting a trap("HUP") to call a
couple of functions (basically to re-read a config). The first time
running a "kill -HUP" on the process works fine, but the second time it
exits with a "hangup". If I modify the trap to look like:
trap("HUP") {
trap("HUP", "IGNORE")
fun1
fun2
}
It doesn't hangup, but only the first "kill -HUP" actually re-reads the
configuration.
This is ruby 1.8.1
Code follows:
<code>
require "yaml"
require "socket"
require "net/smtp"
require "file/tail"
require "getoptlong"
$config = {}
$reread = false
thishost = Socket.gethostname
tivenv = "/etc/Tivoli/setup_env.sh"
usetiv = false
daemon = false
logfile = nil
config_file = nil
opts = GetoptLong.new(
["--config-file", "-c", GetoptLong::REQUIRED_ARGUMENT],
["--daemon", "-d", GetoptLong::NO_ARGUMENT],
["--logfile", "-l", GetoptLong::REQUIRED_ARGUMENT]
)
logan_struct = Struct::new("LoganStruct",
attern, :tmout, :mailhost, :email, ost, :expire)
def daemonize()
fork and exit
Process.setsid
fork and exit
File.open("/dev/null", "r+") do |devnull|
$stdin.reopen(devnull)
$stdout.reopen(devnull)
$stderr.reopen(devnull)
end
Dir.chdir("/")
end
def source(file)
response_match = Regexp.new(/^([^=]*)=(.*)/)
`#{ENV['SHELL']} -c ". #{file}; set"`.each_line do |line|
if response_match.match(line)
k, v = line.gsub(/^([^=]*)=(.*)/, '\1 \2').split
ENV[k] = v
end
end
end
def parseYamlConfig(file)
if File.exists?(file) and File.stat(file).readable?
$config = YAML::load(File.open(file))
else
raise "Unusable file #{file}"
end
$config
end
def setDefaultConfigVals(tmout = 3600)
$config["patterns"].each do |pat|
pat.expire = 0
case pat.pattern
when String
pat.pattern = Regexp.new(pat.pattern)
end
if not pat.mailhost
if $config["mailhost"]
pat.mailhost = $config["mailhost"]
end
end
if not pat.tmout
if $config["tmout"]
pat.tmout = $config["tmout"]
else
pat.tmout = tmout
end
end
end
end
def lookForPatternsInLogfile(file)
if File.exists?(file) and File.stat(file).readable?
File::Tail::Logfile.open(file, :rewind=>0) do |log|
log.tail do |line|
$config["patterns"].each do |pat|
if pat.pattern.match(line)
yield pat, line
end
end
end
end
end
end
def sendMail(email, alert, host, mailhost = "mailhost")
message = <<EndOfMsg
Subject: Log Analyzer Alert for #{host}
To: #{email}
From: LOGAN
The following pattern match was made on #{host} at #{Time.now}
#{alert}
EndOfMsg
Net::SMTP.start(mailhost, 25) do |smtp|
smtp.send_mail(message, '"LOGAN"', email)
end
end
def postMessage(msg)
system("postemsg #{msg} > /dev/null 2>&1")
end
opts.each do |opt, arg|
case opt
when "--daemon"
daemon = true
when "--logfile"
logfile = File.expand_path(arg)
when "--config-file"
config_file = File.expand_path(arg)
end
end
if not logfile or not config_file
fail "Usage: #$0 [-d] -c config_file -l logfile"
end
trap("HUP") do
trap("HUP", "IGNORE")
parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
end
parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
daemonize if daemon
if File.exists?(tivenv)
source(tivenv)
usetiv = true
end
lookForPatternsInLogfile(logfile) do |pat, msg|
if pat.expire <= Time.now.to_i
pat.expire = 0
end
if pat.expire == 0
pat.expire = Time.now.to_i + pat.tmout
if pat.email
sendMail(pat.email, msg, thishost, pat.mailhost)
end
if pat.post
postMessage(pat.post) if usetiv
end
end
end
</code>