Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
How to post alerts from Monit to Slack
# encoding: UTF-8
require 'optparse'
require 'net/http'
require 'json'
def parse_options(argv)
opts = {}
@parser = OptionParser.new do |o|
o.on '--channel CHANNEL', "name of the channel to post to" do |arg|
opts[:channel] = arg
end
o.on '--name NAME', "name of the bot" do |arg|
opts[:name] = arg
end
o.on '--emoji EMOJI', "emoji icon" do |arg|
opts[:emoji] = arg
end
o.on '--token TOKEN', "authentication token" do |arg|
opts[:token] = arg
end
o.on '--status [error,ok]', "kind of message" do |arg|
opts[:status] = arg
end
o.on '--color #HEX_COLOR', "color of the message" do |arg|
opts[:color] = arg
end
o.on '--slack-url URL', "URL to post to" do |arg|
opts[:slack_url] = arg
end
o.on '--monit-url URL', "URL of Monit" do |arg|
opts[:monit_url] = arg
end
o.on '--text TEXT', "text of the message" do |arg|
opts[:text] = arg
end
o.on '--service SERVICE', "Monit service affected" do |arg|
opts[:service] = arg
end
end
@parser.banner = "post_to_slack [options]"
# @parser.on_tail "-h", "--help", "Show help" do
# logger.info @parser
# die 1
# end
@parser.parse!(argv)
opts[:channel] ||= ENV.fetch('CHANNEL') { '#general' }
opts[:name] ||= ENV.fetch('NAME') { 'Monit' }
opts[:emoji] ||= ENV.fetch('EMOJI') { ':vertical_traffic_light:' }
opts[:token] ||= ENV.fetch('TOKEN') { '_your_token_' }
opts[:status] ||= ENV.fetch('STATUS') { 'unknown' }
opts[:slack_url] ||= ENV.fetch('SLACK_URL') { "https://_you_.slack.com/services/hooks/incoming-webhook" }
opts[:monit_url] ||= ENV.fetch('MONIT_URL') { "http://#{`hostname -f`.chomp}:2812/" }
opts[:color] ||= case opts[:status]
when 'ok'
'#59A452'
when 'error'
'#d00000'
else
'#cccccc'
end
opts
end
def format_payload(opts = {})
{
"channel" => opts[:channel],
"icon_emoji" => opts[:emoji],
"username" => opts[:name],
"text" => "Issue on #{`hostname`.chomp} : #{opts[:text]}",
"attachments" => [{
"fallback" => "#{opts[:text]}\n#{opts[:monit_url]}#{opts.fetch(:service){'#'}}",
"color" => opts[:color],
"fields" => [{
"title" => "Message",
"value" => opts[:text],
"short" => true
},{
"title" => "URL",
"value" => "<#{opts[:monit_url]}#{opts.fetch(:service){'#'}}|#{opts.fetch(:service){'?'}}>",
"short" => true
}]
}]
}
end
def post(url, payload)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.post("#{uri.path}?#{uri.query}", payload.to_json)
end
options = parse_options(ARGV)
payload = format_payload(options)
url = "#{options.fetch(:slack_url)}?token=#{options.fetch(:token)}"
post(url, payload)
check process _process_name_
with pidfile /path/to/pidfile.pid
start program = "/path/to/start" as uid _user_ and gid _group_ with timeout 30 seconds
stop program = "/path/to/stop" as uid _user_ and gid _group_ with timeout 30 seconds
if does not exist for 1 cycle
then exec "/path/to/ruby /path/to/post_to_slack.rb --service _process_name_ --status error --text 'Process X is down'"
else if succeeded for 1 cycle then exec "/path/to/ruby /path/to/post_to_slack.rb --service _process_name_ --status ok --text 'Process X is up'"
group _process_group_

It seems it will only post an alert to Slack but will not start it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment