|
|
# $Id:$
require 'puppet'
Puppet::Reports.register_report(:logcache) do
Puppet.settings.use(:reporting)
desc "Record the last 1000 lines of log messages per server."
def mkclientdir(client, dir)
config = Puppet::Util::Settings.new
config.setdefaults("reportclient-#{client}",
"clientdir-#{client}" => { :default => dir,
:mode => 0750,
:desc => "Client dir for %s" % client,
:owner => Puppet[:user],
:group => Puppet[:group]
}
)
config.use("reportclient-#{client}")
end
def getconfig
# Create a new config object and read in configurations related to
# reports
config = Puppet::Util::Settings.new
config.setdefaults(:reporting,
:reportdir => {:default => "/var/lib/puppet/reports",
:mode => 0750,
:owner => "$user",
:group => "$group",
:desc => "The directory in which to store reports
received from the client. Each client gets a separate
subdirectory."},
:reportlocation => ["file",
"Indicate if reports should be stored to file or database."],
:reportdbserver => ["localhost",
"Database server that hosts the reports database."],
:reportdbuser => ["puppetmaster",
"Username to connect to reports database with."],
:reportdbpw => ["dbpassword",
"Password to connect to reports database with."],
:reportdb => ["puppetreports",
"Database name of the reports database."]
)
config.parse(Puppet[:reportconfig])
return config
end
def tablegood(db)
isgood = false
begin
query = db.query("SHOW TABLES LIKE 'logcache'")
if query.num_rows == 0 then
db.query("CREATE TABLE `logcache` (
`pid` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`node` VARCHAR( 255 ) NOT NULL COMMENT 'FQDN of node',
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`logline` VARCHAR( 4096 ) NOT NULL COMMENT 'Log lines',
INDEX ( `node` ));")
Puppet.warning "Created table 'logcache' in reports database"
isgood = true
elsif query.num_rows == 1 then
isgood = true
else
Puppet.warning "Found more than one logcache table???"
isgood = false
end
rescue
Puppet.warning "Had problems checking for logcache table"
isgood = false
end
return isgood
end
def writefile(config)
# We don't want any tracking back in the fs. Unlikely, but there
# you go.
client = self.host.gsub("..",".")
# Create the directory for reports if it doesn't exist
dir = File.join(Puppet[:reportdir], client)
unless FileTest.exists?(dir)
mkclientdir(client, dir)
end
file = File.join(dir, "logcache")
# Read in the exist log cache
if File.exists?(file)
cache = IO.readlines(file)
cache.collect! { |line| line.chomp }
else
cache = []
end
# Collect all the log messages
messages = self.logs.collect { |m| m.to_report }
cache.concat(messages)
cache = cache.last(1000)
begin
File.open(file, "w", 0640) do |f|
f.puts cache.join("\n")
end
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
Puppet.warning "Could not write report for %s at %s: %s" %
[client, file, detail]
end
end
def writedb(config)
# We don't want any tracking back in the fs. Unlikely, but there
# you go.
client = self.host.gsub("..",".")
db = Mysql.connect(config[:reportdbserver],
config[:reportdbuser],
config[:reportdbpw], config[:reportdb])
if tablegood(db) then
messages = self.logs.collect { |m| m.to_report }
messages.each { |line|
cleanline = Mysql.escape_string(line)
db.query("INSERT INTO logcache(node,logline) VALUES(\'%s\', \'%s\')" %
[client, cleanline])
}
Puppet.debug "Stored logcache report to database for %s" % client
else
Puppet.warning "Had problems with logcache table"
end
db.close
end
def process
config = getconfig
now = Time.now.getlocal
if config[:reportlocation] == "file" then
writefile(config)
elsif config[:reportlocation] == "mysql" then
writedb(config)
end
# Only testing cares about the return value
return
end
end
|