有时ping网站的代码

时间:2010-04-20 05:46:51

标签: ruby-on-rails ruby http

我正在测试一段代码来定期ping我拥有的一堆网站,以确保它们正常运行。

我正在使用rails,到目前为止,我正在尝试使用这种可怕的测试操作(见下文)。
但问题是,有时候它会起作用,有时它不会......有时候它会很好地运行代码,有时它似乎完全忽略了开始/救援块...

一个。我需要帮助找出问题所在 湾并重构这一点,使其看起来很可敬。

非常感谢您的帮助。

编辑1:这是更新后的代码,抱歉花了这么长时间,pastie.org自昨天开始下降http://pastie.org/927201

它仍在做同样的事情...跳过开始块(因为它只更新up_check_time)...但是如果其中一个站点超时,它实际上正确地更新了所有内容(check_msg,代码等)...令人困惑,是吗?

require 'net/http'
require 'uri'

def ping
    @sites = NewsSource.all

    @sites.each do |site|
        if site.uri and !site.uri.empty?
            uri = URI.parse(site.uri)
            response = nil
            path = uri.path.blank? ? '/' : uri.path
            path = uri.query.blank? ? path : "#{path}?#{uri.query}"

            begin
                Net::HTTP.start(uri.host, uri.port) {|http|
                http.open_timeout = 30
                http.read_timeout = 30
                response = http.head(path)
                }

                if response.code.eql?('200') or response.code.eql?('301') or response.code.eql?('302')
                site.up = true
                else
                site.up = false
                end

                site.up_check_msg = response.message
                site.up_check_code = response.code
            rescue Errno::EBADF
            rescue Timeout::Error
                site.up = false
                site.up_check_msg = 'timeout'
                site.up_check_code = '408'
            end
            site.up_check_time = 0.seconds.ago
            site.save
        end
    end
end

4 个答案:

答案 0 :(得分:3)

rescue目前有一个空的Errno::EBADF块,因此如果出现该异常,则您不会将site.up设置为false

此外,还有其他一些小改进:

您可以使用以下if site.uri and !site.uri.empty?代替:

next if site.uri.nil? or site.uri.empty?

跳过each循环的迭代,并避免将代码缩进一个额外的级别。

if response.code.eql?('200') or response.code.eql?('301') or response.code.eql?('302')
  site.up = true
else
  site.up = false
end

可以写得更简洁:

site.up = ['200', '301', '302'].include? response.code

如果您使用其中一些提示整理代码,那么它可能有助于缩小问题范围。

答案 1 :(得分:1)

这是我的一个程序的片段,也许有帮助:

urls.each_with_index do |url, idx|
  print "Processing URL #%04d: " % (idx+1)
  uri = URI.parse(url)
  response = nil

  begin
    Net::HTTP.start(uri.host, uri.port) do |http|
      response = http.head(uri.path.size > 0 ? uri.path : "/")
    end
  rescue => e
    puts "#{e.message} - #{url}"
    next
  end

  # handle redirects
  if response.is_a?(Net::HTTPRedirection)
    new_uri = URI.parse(response['location'])
    puts "URI redirects to #{new_uri}"
    next
  end

  puts case response.code
    when '200' then ...
    when '404' then ...
    else ...
  end
end

答案 2 :(得分:0)

我唯一能想到的是你在开始块中遇到了一些其他异常。由于您只是明确地拯救Errno :: EBADF,Timeout :: Error,因此看起来您的begin和rescue被跳过了。您可以通过摆脱Errno :: EBADF,Timeout :: Error并进行简单救援来验证这一点,然后将以下内容放入救援区中

logger.info(">>Exception was: "+$!)

然后查看日志以查看您获得的例外情况。

答案 3 :(得分:0)

如果您正在监控服务器,为什么不使用Nagios?它是免费的,还有一些Ruby支持,HereHere

编辑:

Ruby GEM:http://hobodave.com/2010/01/10/simple-nagios-probes-in-ruby/