为什么在Raspberry Pi上运行的Ruby脚本会死掉?

时间:2014-04-04 10:03:23

标签: ruby linux raspberry-pi

我使用Raspberry Pi(256MB版本)来监控室外温度并检测棚屋内的移动。要完成这项工作有三件事要做:

  1. 一个ruby脚本,每分钟运行一次并记录每分钟的温度。根据当前时间的不同,它还会将温度上传到3种不同的网络服务(每小时5,10,15分钟等)并推文(小时)
  2. 一个长时间运行的Ruby脚本,它在重启时运行并监视由运动检测软件创建的文件,然后将它们上传到Dropbox
  3. Motion - 动作检测软件
  4. 脚本在root用户crontab中启动,如下所示:

    * * * * * /usr/local/rvm/rubies/ruby-2.0.0-p353/bin/ruby /usr/share/shed_watcher/lib/shed_watcher.rb >> /tmp/cron_shed_watcher.log 2>&1
    @reboot /usr/local/rvm/rubies/ruby-2.0.0-p353/bin/ruby /usr/share/shed_watcher/lib/file_monitor.rb >> /tmp/file_monitor.log 2>&1
    

    我最近注意到,在检测到运动的几秒钟内,Pi变得无响应,重启后cron_shed_watcher.log日志文件包含以下条目:

        2014-04-03T19:55:17:342 - RAM USAGE: 28460K: stored temperatures are ["8.625\n", "8.625\n", "8.625\n", "8.625\n", "8.625\n"]
    
    2014-04-03T19:55:17:332 - RAM USAGE: 28460K: temperature is 8.625
    
    2014-04-03T19:55:17:376 - RAM USAGE: 28460K: average temperature is: 8.625
    
    
    
    2014-04-03T20:00:28:812 - RAM USAGE: 28456K: temperature is 8.562
    
    2014-04-03T20:00:28:843 - RAM USAGE: 28460K: average temperature is: 8.587
    
    2014-04-03T20:00:28:822 - RAM USAGE: 28460K: stored temperatures are ["8.562\n", "8.625\n", "8.625\n", "8.562\n", "8.562\n"]
    
    
    
    2014-04-03T20:05:17:312 - RAM USAGE: 28460K: temperature is 8.5
    
    2014-04-03T20:05:17:322 - RAM USAGE: 28460K: stored temperatures are ["8.562\n", "8.562\n", "8.562\n", "8.5\n", "8.5\n"]
    
    2014-04-03T20:05:17:346 - RAM USAGE: 28460K: average temperature is: 8.537
    
    
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    Killed
    

    要从Killed阶段发生的任何事情中恢复,我需要重新启动。我不清楚Killed日志条目的来源。我怀疑存在内存不足问题,因此日志条目中的RAM信息,但这似乎保持稳定。我还怀疑文件监视器Ruby脚本更可能是任何内存问题的罪魁祸首,因此我将每个脚本写入不同的日志文件。但是,Killed日志条目显示在温度脚本(cron_shed_watcher.log)中,而不是文件监视器日志文件中。

    这是shed_watcher.rb Ruby脚本(编辑以删除不必要的细节):

            now = DateTime.now
            shed_temp = Temperature.new
            temp = shed_temp.celcius
    
                #tweet & email###
                if now.min == 0
                    Tweeter.tweet TimeUtils.get_now_as_string(TimeUtils.get_local_time(now)), ave_temp.round(1)
    
                    if now.hour == 6
                        GMailer.email_graph :daily, now
                        if now.sunday?
                            GMailer.email_graph :weekly, now
                        end
                        if now.day == 1
                            GMailer.email_graph :monthly, now
                        end
                        if now.month == 1 && now.day == 1
                            GMailer.email_graph :yearly, now
                        end
                    end
                end
    
                #Xively###
    #create json for Xively web service 
    
                #Met Office############## --- 
    #create url for Met Officeweb service 
    
                #open sen.se###
    #create json for Open Sense web service
    
                #post to web###
                begin
                    Exception => e
                    Logger.log "RestClient raised exception:"
                    Logger.log e.message
                end
            end
    

    以下是温度等级,它从硬件中获取温度:

    class Temperature
        attr_reader :celcius, :fahrenheit
        def initialize
            @celcius = -999
            @fahrenheit = -999
    
            `modprobe w1-gpio`
            `modprobe w1-therm`
    
            base_dir = '/sys/bus/w1/devices/'
            device_folder = Dir.glob(base_dir + '28*')[0]
            @device_file = device_folder + '/w1_slave'
    
            read_temp
        end
    end
    
    def read_temp_raw
        File.open(@device_file, 'r') do |f|
            lines = f.readlines()
        end
    end
    
    def read_temp
        lines = read_temp_raw()
        temp_c = 0
        temp_f = 0
        while !lines[0].strip().end_with? 'YES'
            sleep(0.2)
            lines = read_temp_raw
        end
        equals_pos = lines[1].rindex('=')
        if equals_pos != -1
            line=lines[1].strip
            line=line[line.index('=') + 1, line.length - line.index('=') + 1]
            temp_c = line.to_f / 1000.0
            temp_f = temp_c * 9.0 / 5.0 + 32.0
            @celcius = temp_c
            @fahrenheit = temp_f
        end
    end
    

    如您所见,此类进行了一些Linux系统调用:modprobe w1-gpiomodprobe w1-therm

    file_monitor.rb脚本(在重启时运行)如下所示:

    class FileWatcher
    
        def initialize
            client = DropboxClient.new(ACCESS_TOKEN)
            begin
                FSSM.monitor('/tmp/motion/', '**/*', :directories => true) do
                    update do |base, relative|
                    end
                    delete do |base, relative|
                    end
                    create do |base, relative|
                        Logger.log "Create called with #{relative}"
                        now = DateTime.now
    
                        Logger.log "Uploading #{File.absolute_path(relative, base)} to dropbox then deleting"
                        begin
                            client.put_file(relative, File.new(File.absolute_path(relative, base)))
                            File.delete(File.absolute_path(relative, base))
                        rescue Exception => e
                            Logger.log "Dropbox upload raised exception:"
                            Logger.log e.message
                            File.open('files_to_process.txt', 'a') do | file |
                                file.puts File.absolute_path(relative, base)
                            end
                        end
                    end
                end
            rescue Exception => e
                Logger.log "FileWatcher raised exception:"
                Logger.log e.message
            end
        end
    end
    
    fw = FileWatcher.new
    

    如果检测到动作,则会在/tmp/motion/中创建每秒约一个jpg文件。

    如何查找这些日志条目和设备死亡的原因?

0 个答案:

没有答案