violet_rails icon indicating copy to clipboard operation
violet_rails copied to clipboard

example of an External API Connection (Bishop Monitoring)

Open donrestarone opened this issue 3 years ago • 0 comments

The following 2 Ruby classes implement bishop.restarone.com in Violet Rails

BishopMonitoring for rendering pages

class BishopMonitoring
  def initialize(parameters)  
    @external_api_client = parameters[:external_api_client]
    @log_incidents_to_namespace = @external_api_client.api_namespace.properties["log_incidents_to"]
    @targets = @external_api_client.api_namespace.api_resources
    @timeout_in_seconds = 30
  end
  def start
    logger_namespace = ApiNamespace.find_by!(slug: @log_incidents_to_namespace)
    @targets.each do |target|
      url = target.properties["url"]
      start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      latency = 0
      begin
        response = HTTParty.get(url, follow_redirects: true, timeout: @timeout_in_seconds)
        finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
        latency = ((finish - start) * 1000).round
      rescue StandardError => e
        logger_namespace.api_resources.create!(
          properties: {
            slug: url,
            error: e.message,
            notification_sent: false,
            latency: latency
          }
        )
        updated_target_properties = {
          "healthy": false,
          "alarm_raised": false,
          "last_checked_at": Time.now,
          "latency": 0,
          "error_message": e.message
        }
        target.update!(
          properties: target.properties.merge(updated_target_properties)
        )
        #after handling the error case, we need to bubble it up to the job
        raise
      else
        updated_target_properties = {
          "healthy": true,
          "alarm_raised": false,
          "last_checked_at": Time.now,
          "latency": latency,
          "error_message": nil
        }
        target.update!(
          properties: target.properties.merge(updated_target_properties)
        )
      end
    end
  end

  def log
    return true
  end
end
# at the end of the file we have to implicitly return the class 
BishopMonitoring

BishopTlsMonitoring for testing TLS/SSL certificates

class BishopTlsMonitoring
  def initialize(parameters)  
    @external_api_client = parameters[:external_api_client]
    @log_incidents_to_namespace = @external_api_client.api_namespace.properties["log_incidents_to"]
    @targets = @external_api_client.api_namespace.api_resources
    @timeout_in_seconds = 30
  end
  def start
    logger_namespace = ApiNamespace.find_by!(slug: @log_incidents_to_namespace)
    @targets.each do |target|
      url = target.properties["url"]
      start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      latency = 0
      begin
        uri = URI::HTTPS.build(host: URI(url).host)
        response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true)
        cert = response.peer_cert
        two_weeks = 14 * 86400 # 14 * One Day
        if Time.now + two_weeks > cert.not_after
          raise "TLS/SSL certificate for #{uri} is expiring soon. Expiry at: #{cert.not_after}"
        end
        finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
        latency = ((finish - start) * 1000).round
      rescue StandardError => e
        logger_namespace.api_resources.create!(
          properties: {
            slug: url,
            error: e.message,
            notification_sent: false,
            latency: latency
          }
        )
        updated_target_properties = {
          "healthy": false,
          "alarm_raised": false,
          "last_checked_at": Time.now,
          "latency": 0,
          "error_message": e.message
        }
        target.update!(
          properties: target.properties.merge(updated_target_properties)
        )
        #after handling the error case, we need to bubble it up to the job
        raise
      else
        updated_target_properties = {
          "healthy": true,
          "alarm_raised": false,
          "last_checked_at": Time.now,
          "latency": latency,
          "error_message": nil
        }
        target.update!(
          properties: target.properties.merge(updated_target_properties)
        )
      end
    end
  end

  def log
    return true
  end
end
# at the end of the file we have to implicitly return the class 
BishopTlsMonitoring

donrestarone avatar May 31 '22 21:05 donrestarone