Rails Rails 中的线程如何写 Logger 日志

chucai · 2012年05月15日 · 最后由 fsword 回复于 2013年07月09日 · 5448 次阅读

问题如下: 在我的 action 中,我会启用一个线程调用一个 system 命令,我想知道程序是否已经运行了该命令,所以,我在 system 命令后面,加入了日志记录。但是在 log 文件中并没有该项记录。 代码

def show
   ... ...
   Thread.new {
      sleep 10
      system(cmd)
      logger.info("命令已经执行")
   }
   ... ...
end

======补充说明 因为 cmd 命令会执行很长的时间,准确的说,是一个 ffmpeg 的命令,用来解析视频的。 sleep 10 的意思是确定视频文件存在,才让 cmd 处理 最后的 logger 没有记录到文件中

system('ls -lash > tmp/ls.log 2>&1')

这东西用 shell out 或进程通讯多好哇 线程不太好控制,特别是在 Rails 里的,受服务器模型影响

我试过行的。你是日志文件记录的级别高于 INFO 吧

#3 楼 @cantoraz 不会吧。Thread 外面的日志是可以记录的,当然我的代码还有一个问题没有说明。就是,在执行命令前,我会 sleep 一段时间。

Thread.new {
   sleep 10
   system(cmd)
   logger.info("命令执行了")
 }

不知道你为啥一定要用线程。

system('sleep 10 && cmd > tmp/shell.log 2>&1 &')
匿名 #6 2012年05月15日

#4 楼 @chucai 同学,父进程执行完毕退出了,你子线程没法 hold 的住哦,这里是非堵塞的

@sharp 你的解释很清晰~谢谢,也许是你说的原因。cmd 命令会执行很长的时间 @hooopo 因为 cmd 命令会执行很长的时间,根本不会断啊

#7 楼 @chucai @hooopo 给你的指令里 + 了&会通过 linux 后台进程运行呀~

解析视频这样的大任务建议用任务队列异步来做,比如 resque

#9 楼 @Rei 不用队列的原因在于要求实时性

#10 楼 @chucai 如果你的 controller 等待这个线程完成,那么用户页面就会卡住,如果不等待,那么就是异步任务了。

#11 楼 @Rei 恩。其实是不等待,所以单开一个线程做。想法是这样的,在 action 中开一个线程,等到满足条件,然后调用 ffmpeg 处理视频,最后线程退出,但是不知道为什么,有时候程序不会调用 ffmpeg 命令。所以,想日志记录看看。

试试 IO.popen(cmd) 呢

匿名 #14 2012年05月15日

#10 楼 @chucai 实时性和你用不用队列没有关系,只能说异步队列最大化的利用了系统资源,可以达到软实时。

你这里指的是同步响应

你没有 join 这个行程。主线程已经运行完了,子线程还没运行到 log

@EricZhu @sharp 我测试了一下,应该跟主线程运行完了没有什么关系。因为是 rails 程序,主线程不是一直存在着么(具体我也不清楚...)?看代码吧

def index
   Thread.new {
     logger.info("线程执行开始---------------")
     sleep 20
     system("ls")

     logger.info("线程执行结束---------------")
   }
   render :text => "hello,boy"
end

我 sleep 20,ls 命令都能得到结果

匿名 #17 2012年05月15日

对不起,我把你的例子也做了试验,只能看到 线程执行开始---------------

关注下,看来 rails 下线程还是不好使啊。

这个帖子里的回答真是五花八门啊

需要 登录 后方可回复, 如果你还没有账号请 注册新账号