簡體   English   中英

如何從遠程日志文件中將文本流式傳輸到html - ruby​​ on rails

[英]how to stream text into html from remote log file - ruby on rails

我在rails應用程序上有這個ruby,當按下按鈕時,它通過ssh在遠程linux主機上執行任何命令。然后返回帶有Jquery的輸出並將其顯示在我的html頁面中。

但是,如果我想啟動一個Weblogic服務器,我無法告訴用戶服務器啟動和運行的時間,因為它寫入了一個日志文件而我的Jquery只在Jquery完成時返回。

我的問題是:有沒有辦法在我的html頁面中輸出一個命令的輸出,如:tail -f somefile.log,直到寫入一個特定的單詞(例如:“server:running”)

要么

有沒有辦法在執行startWeblogic.sh之后,我的jquery讀取日志文件並等待“server:running”然后返回成功消息。

我希望這是我能做的! 謝謝你們的答案。

這是我目前的配置:

$(document).ready(function () {
    $("button").click(function (event) {
    $.post("/ssh/execute", {
    hostname: $('#serverlist').val(),
    username: $('#login').val(),
    password: $('#password').val(),
    command: $('#CommandSelect').val(),

    }).done(function (data){
        $("#textarea").text(data.retour);
    }).fail(function (data){
        $("#textarea").text("Wrong password or the server exploded");
    });
});

});

這是我的控制器:

class SshController < ApplicationController
    def execute

        require 'rubygems'
        require 'net/ssh'

        hostname = params[:hostname]
        username = params[:username]
        password = params[:password]
        if params[:command] == "ls"
            cmd =  "sudo su - -c 'ls -lart '"
        else
        cmd =params[:command]
        end


        Net::SSH.start(hostname, username, :password => password) do |ssh|
            render :json => {:retour => ssh.exec!(cmd)}
        end

    end
end

要構建@emaillenin的答案,你當然可以使用帶有--follow選項的tail來隨着它的增長使用文件。 更好的是,您可以通過-F跟蹤文件 ,這在文件名隨時間變化時MyLog.log (例如: MyLog.log在一天結束時移動到MyLog1.log )。 有關tail更多信息可在相應的man(1)頁面中找到,或者您可以參考此通用Tail手冊頁

`tail -F /var/log/MyApplication.log`

將它與Rails 4的ActionController::Live直播HTTPOpen3#popen3方法相結合,你可以在后台進程中連續運行tail,直到用戶關閉它們的窗口!

注意:您需要使用能夠很好地處理並發性的服務器,例如Puma。 每個打開連接1個工作程序是規則。

require 'open3'

class StaticPagesController < ApplicationController
  include ActionController::Live

  private

  def follow_log
    begin
      stdin, stdout, stderr, wait_thread = Open3.popen3("tail -F -n 0 #{Rails.root.join('log', 'development.log')}")

      stdout.each_line do |line|
        yield line
      end

    rescue IOError

    ensure
      stdin.close
      stdout.close
      stderr.close
      Process.kill('HUP', wait_thread[:pid])
      logger.info("Killing Tail pid: #{wait_thread[:pid]}")
    end
  end
end

在這里,我們在子進程中執行tail命令,並確保它使用-n 0選項從文件的底部開始。 這意味着它總是在等待初始行,並且不會打印用戶可能已經在另一個會話中看到的前一行。

每當一個新行被添加的時候,我們就會yield ,為塊,這樣我們就可以寫出來的流。

我們還ensure在塊結束時,我們關閉所有打開的IO流,並向進程發送HUP kill命令。

現在,我們可以建立我們的行動:

  def home
    begin
      follow_log do |line| 
        response.stream.write line
      end

    rescue IOError

    ensure
      logger.info("Killing stream")
      response.stream.close
    end
  end

一旦response.stream.write嘗試寫入不再存在的流(即:用戶關閉其瀏覽器),將IOError 這有一個缺點:該方法將保持tail運行,直到下一行寫入文件。 根據您的日志,這可能需要很長時間。

要從Rails實時流式傳輸到網頁,您需要使用ActionController :: Live

一個簡單的例子:

class MyController < ActionController::Base
  include ActionController::Live

  def stream
    response.headers['Content-Type'] = 'text/event-stream'
    100.times {
      response.stream.write "hello world\n"
      sleep 1
    }
  ensure
    response.stream.close
  end
end

對於客戶端流,請使用EventSource並查看示例

要使SSH命令與流式傳輸一起使用,您可以多次輪詢服務器,間隔為2秒,並對輸出進行流式處理。

為什么不嘗試使用ps檢查服務是否已啟動?

你可以運行ps -elf | grep java 例如,每30秒在服務器上ps -elf | grep java ,然后你可以看到你正在尋找的特定實例是否正在運行。

我認為這比在流媒體中不斷讀取日志文件要有效得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM