Jon*_*han 0 ruby logging multithreading daemon ruby-on-rails
我写了一个管理脚本,尾随一个heroku日志,每n秒,它总结平均值,并通知我,如果我跨越一定的门槛(是的,我知道并喜欢新的遗物 - 但我想做自定义的东西).
这是整个脚本.
我从未成为IO和线程的主人,我想知道我是否犯了一个愚蠢的错误.我有几个守护程序线程while(true){}可能是罪魁祸首.例如:
# read new lines
f = File.open(file, "r")
f.seek(0, IO::SEEK_END)
while true do
select([f])
line = f.gets
parse_heroku_line(line)
end
Run Code Online (Sandbox Code Playgroud)
我使用一个守护进程来监视日志的新行,另一个用于定期汇总.
有人看到一种方法可以降低处理器密集度吗?
这可能很热,因为从临时文件中读取时你从未真正阻止过.IO::select是POSIX select(2)上的薄层.看起来你试图阻止,直到文件准备好读取,但select(2)认为EOF准备就绪("文件描述符也准备好在文件结尾"),所以你总是立即返回从select然后调用gets在EOF返回nil.
您可以通过避免其写入临时文件的线程,而不是使用获得更真实的EOF阅读和漂亮的阻塞行为IO::popen到餐桌的%x[heroku logs --ps router --tail --app pipewave-cedar]日志零售商,连接到Ruby的IO对象,您可以遍历gets时,退出gets回报率nil(表示日志tailer完成).gets当没有什么东西可以阅读时,来自tailer的管道会阻塞,你的脚本只会像你的行解析和报告一样热.
编辑:我没有设置实际尝试您的代码,但您应该能够使用此代码替换日志分页器线程和临时文件读取循环,以获得上述行为:
IO.popen( %w{ heroku logs --ps router --tail --app my-heroku-app } ) do |logf|
while line = logf.gets
parse_heroku_line(line) if line =~ /^/
end
end
Run Code Online (Sandbox Code Playgroud)
我也注意到你的报告线程没有做任何事情来同步访问@total_lines,@total_errors等等.所以,你有一些小的竞争条件,你可以得到不一致的值从实例瓦尔该parse_heroku_line方法的更新.
| 归档时间: |
|
| 查看次数: |
532 次 |
| 最近记录: |