Create a gist now

Instantly share code, notes, and snippets.

Embed
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_
@Amit-Naudiyal

This comment has been minimized.

Show comment
Hide comment
@Amit-Naudiyal

Amit-Naudiyal Jul 19, 2016

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

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

@smalltown

This comment has been minimized.

Show comment
Hide comment
@smalltown

smalltown Feb 24, 2018

agree with @Amit-Naudiyal, need to add one more line "if does not exist then restart" to restart the process when encountering issue

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 then restart
  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_

agree with @Amit-Naudiyal, need to add one more line "if does not exist then restart" to restart the process when encountering issue

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 then restart
  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_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment