class Slackiq

Constants

VERSION

Attributes

options[R]

Public Class Methods

configure(webhook_urls={}) click to toggle source

@param options [Hash]

# File lib/slackiq.rb, line 19
def self.configure(webhook_urls={})
  @webhook_urls = webhook_urls
end
new(options) click to toggle source

@param options [Hash]

# File lib/slackiq.rb, line 24
def initialize(options)
  @options = options
end
notify(options) click to toggle source

@param options [Hash]

# File lib/slackiq.rb, line 13
def self.notify(options)
  raise "Need to run Slackiq.configure first" if @webhook_urls.nil?
  new(options.merge(webhook_urls: @webhook_urls)).execute
end

Public Instance Methods

execute() click to toggle source

Send a notification to Slack with Sidekiq info about the batch

# File lib/slackiq.rb, line 29
  def execute
    time_now = Time.now

    title    = options[:title]
    status   = options[:status]

    if (bid = options[:bid]) && status.nil?
      raise <<~EOT.chomp unless defined?(Sidekiq::Batch::Status)
               Sidekiq::Batch::Status is not defined. \
               Are you sure Sidekiq Pro is set up correctly?
               EOT
      status = Sidekiq::Batch::Status.new(bid)
    end

    return if status.nil?

    color      = options[:color] || color_for(status)

    duration   = elapsed_time_humanized(status.created_at, time_now)
    time_title = status.complete? ? "Completed" : "Now"
    jobs_run   = status.total - status.pending

    completion_percentage = percentage(jobs_run        / status.total.to_f)
    failure_percentage    = percentage(status.failures / status.total.to_f)

    fields = [
      {
        title: title,
        value: status.description,
        short: false
      },
      {
        title: "Batch ID",
        value: status.bid,
        short: false
      },
      {
        title: "Created",
        value: time_format(status.created_at),
        short: true
      },
      {
        title: time_title,
        value: time_format(time_now),
        short: true
      },
      {
        title: "Duration",
        value: duration,
        short: true
      },
      {
        title: "Total Jobs",
        value: status.total,
        short: true
      },
      {
        title: "Jobs Run",
        value: jobs_run,
        short: true
      },
      {
        title: "Completion %",
        value: completion_percentage,
        short: true
      },
      {
        title: "Failures",
        value: status.failures,
        short: true
      },
      {
        title: "Failure %",
        value: failure_percentage,
        short: true
      }
    ]

    body = {
      attachments: [
        fields: fields,
        color:  color
      ]
    }
    http_post(body)
  end

Private Instance Methods

color_for(status) click to toggle source

@param status [Sidekiq::Batch::Status]

# File lib/slackiq.rb, line 140
        def color_for(status)
  colors = {
    red:    "f00000",
    yellow: "ffc000",
    green:  "009800"
  }

  if status.total == 0
    colors[:yellow]
  elsif status.failures > 0
    colors[:red]
  elsif status.failures == 0
    colors[:green]
  else
    colors[:yellow]
  end
end
elapsed_seconds(t0, t1, precision: 2) click to toggle source

@param t0 [DateTime] @param t1 [DateTime]

# File lib/slackiq.rb, line 169
        def elapsed_seconds(t0, t1, precision: 2)
  dt0 = t0.to_datetime
  dt1 = t1.to_datetime
  ((dt1 - dt0) * 24 * 60 * 60).to_f.round(precision)
end
elapsed_time_humanized(t0, t1, precision: 2) click to toggle source

@param t0 [DateTime] @param t1 [DateTime]

# File lib/slackiq.rb, line 160
        def elapsed_time_humanized(t0, t1, precision: 2)
  time_humanize(
    elapsed_seconds(t0, t1, precision: precision),
    precision: precision
  )
end
http_post(data) click to toggle source

@param data [Hash]

# File lib/slackiq.rb, line 117
        def http_post(data)
  url  = options[:webhook_urls].fetch(options[:webhook_name])
  uri  = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true if uri.port == 443

  header  = {"Content-Type": "application/json"}
  request = Net::HTTP::Post.new(uri.request_uri, header)
  request.body = data.to_json
  http.request(request)
end
percentage(number, precision: 2, multiply100: true) click to toggle source

@param number [Numeric] @param precision [Integer] @param multiply100 [Boolean]

# File lib/slackiq.rb, line 132
        def percentage(number, precision: 2, multiply100: true)
  number  = number * 100 if multiply100
  rounded = number.to_f.round(precision)
  format  = number == rounded.to_i ? "%.f" : "%.#{precision}f"
  (format % rounded) + "%"
end
time_format(time) click to toggle source

@param time [DateTime]

# File lib/slackiq.rb, line 192
        def time_format(time)
  time.strftime("%D @ %I:%M:%S %P")
end
time_humanize(secs, precision: 2) click to toggle source

stackoverflow.com/questions/4136248/how-to-generate-a-human-readable-time-range-using-ruby-on-rails @param secs [Integer]

# File lib/slackiq.rb, line 177
        def time_humanize(secs, precision: 2)
  [[60, :s], [60, :m], [24, :h], [1000, :d]].map do |count, name|
    if secs > 0
      secs, n = secs.divmod(count)
      if name == :s
        num = n.to_f == n.to_i ? n.to_i : n.to_f
        "%.#{precision}f#{name}" % num
      else
        "#{n.to_i}#{name}"
      end
    end
  end.compact.reverse.join(" ")
end