Read chef-client log

Hi guys, I’m trying to send clien run log via email,

Chef.event_handler do
on :run_failed do
Email.new(Chef.run_context.node.name, true, def_emails).runtime_send;
end
end

Inside Email.runtime_send I just read log file /var/chef/run.log, but it appears ruby pulls before chef-client stops working
Chef reads this:
[2017-02-01T23:47:08+00:00] ERROR: Running exception handlers
[2017-02-01T23:47:08+00:00] ERROR: Exception handlers complete

Log file much bigger:
[2017-02-01T23:47:08+00:00] ERROR: Running exception handlers
[2017-02-01T23:47:08+00:00] ERROR: Exception handlers complete
[2017-02-01T23:47:18+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2017-02-01T23:47:18+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2017-02-01T23:47:18+00:00] ERROR: server_type is not defined
[2017-02-01T23:47:18+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Any chance to fix this?

Thanks

Well, the relevant error is:

So without the actual code of your Email Class/Module this will be quite impossible to solve.

server_type - it’s raise I send in recipe when some conditions happen, so the mail idea send the whole log, here’s the code

recipe/default.rb

exceptions handler

Chef.event_handler do
on :run_failed do
sleep(10);
Email.new(Chef.run_context.node.name, true, def_emails).runtime_send;
end
on :run_completed do
Email.new(Chef.run_context.node.name, false, def_emails).runtime_send;
end
end

require ‘net/smtp’

class Email < ::Chef::EventDispatch::Base
def initialize(node_name=“unk”,exec_status=true, def_emails={“from” => “emailmy.com”, “to” => “emailmy.com”})
node_name=node_name
exec_status=exec_status
def_emails=def_emails
end

def runtime_send
node_name=node_name
def_emails=def_emails
log_file=’/var/chef/run.log’

if(exec_status == true)
    subject = 'Chef job failed'
    log_content = File.read(log_file)
else
    subject = 'Chef job completed'
    log_content='';
end
message = "From: #{def_emails['from']}>\n"
message << "To: #{def_emails['to']}\n"
message << "Subject: #{subject}\n"
message << "Date: #{Time.now.rfc2822}\n\n"
message << "Node: #{node_name} \n\n #{log_content} \n"
Net::SMTP.start('mailhost', 25) do |smtp|
  smtp.send_message message, "#{def_emails['from']}", "#{def_emails['to']}"
end

end
end

First off: Please use proper formatting in your messages.

Is that handler code really what you have in your recipe? If so, than this is wrong. The handler code should be shipped using a cookbook_file, template, ruby gem or any similar way. The recipe should then contain a block pointing to that handler code, see the chef_hander cookbook [1].

[1] GitHub - chef-boneyard/chef_handler: DEPRECATED: Development repository for Chef Cookbook chef_handler

Hmm, I used this manual to create it ( https://docs.chef.io/handlers.html) ,
Actually it’s not possible to handle fatal errors during that cookbook, tried to do that - it would fail to send any emails.

And my code shipped as a cookbook, then I run on clients

Taking my words back, it works. Thanks!