如何流式传输(大)日志文件?

时间:2012-12-14 00:26:37

标签: ruby sinatra real-time-updates near-real-time

当自动化测试正在运行时,我无法连接到测试计算机并检查日志文件以检查测试进度,因为我会中断测试。我可以映射硬盘并以这种方式检查文件,但我想在我的sinatra应用程序中添加新功能。

应用程序运行测试并显示测试结果,因此我想通过sintra添加日志文件的实时流。日志文件甚至可能大2MB,所以我想每次更新日志文件时发送整个文件都不是一个好主意,尽管服务器客户端通信只能在99%的LAN上完成。我还希望从Web浏览器顶部的日志文件中获取最新的最后一行。

有人可以建议怎么做吗?

我可以想到定期进行的ajax调用会将sinatra作为最后一行接收到的一些行传递给sinatra。如果有的话,sinatra会返回任何更新。

更新

  • Windows 7 64位
  • ruby​​ 1.9.3p194(2012-04-20)[i386-mingw32]
  • sinatra(1.3.3)
  • sinatra-contrib(1.3.1)
  • sinatra-reloader(1.0)

2 个答案:

答案 0 :(得分:3)

您没有说明您的测试系统使用的操作系统类型,但如果是Linux或Mac OS,您就可以使用了。如果没有,它是Windows,我真的建议安装一个telnetd或ssh服务器,以及一个尾部类型的应用程序。

SSH和/或Telnet更轻量级,因为它们基本上只是发送文本,因此它们会影响您的测试系统,而不是尝试通过HTTP流式传输文件,尤其是使用您提到的解决方案。只需打开一个会话,tail -f该文件,然后开始测试。


要使用Sinatra实现解决方案,我将从一小段代码开始,如:

#!/bin/env ruby

filepath = ARGV.shift
start_line, num_lines = ARGV.map(&:to_i)

File.foreach(filepath) do |li|
  case 
  when $. < start_line
    next
  when (start_line .. (start_line + num_lines)) === $.
    puts li 
  when $. > (start_line + num_lines)
    break 
  end
end

将其作为display_file_block.rb保存到磁盘,并使用以下参数调用它:

path/to/file start_line lines_to_display

其中:

  • path/to/file很明显。
  • start_line是要显示的文件中的起始行。
  • lines_to_display是要显示的行数。

使用那些可以打开要显示的文件,从偏移量开始发送一些行。

在Sinatra中,为GET设置请求处理程序:

get '/tail' do
  path = params['path']
  start = params['start']
  count = params['count']
  `/path/to/display_file_block.rb #{ path } #{ start } #{ count }`
end

您可能希望将响应content-type设置为'text/plain'。 Sinatra网站可以告诉你如何做到这一点。

答案 1 :(得分:1)

以下是使用“推送”的示例,即WebSockets:

Minimum Websocket Nodejs Tail Example

在我看来,AJAX轮询是这种问题的管道式磁带解决方案。 WebSockets是可行的方法,并且正确完成对系统性能的影响非常小。

通过Google搜索“websockets sinatra”,您可以搜索Sinatra的类似解决方案,例如第一次点击:

https://github.com/simulacre/sinatra-websocket