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

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

问题如下: 在我的 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 &')
匿名 #7 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) 呢

匿名 #15 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 命令都能得到结果

匿名 #18 2012年05月15日

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

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

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

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