我必须在我的远程 linux 机器上跟踪日志文件,并将其作为输出连续打印到浏览器上。我已经设法使用 JSch 来跟踪它,并且我正在将输出打印为 System out。我现在为此使用 servlet(尽管客户端迫切要求仅使用 jsp)。问题是,一旦我尝试在浏览器上打印尾流,浏览器就会进入冻结状态,就好像它在不断地加载某些东西(它是!)。当浏览器冻结时,sysout 日志完美地在控制台上打印尾流。这是我的小服务程序
package sshUploader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Run several ssh commands in a single JSch session
*/
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.io.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Hashtable;
/**
* Servlet implementation class TailLogServlet
*/
@WebServlet(description = "This servlet tails the remote logs", urlPatterns = { "/TailLogServlet" })
public class TailLogServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TailLogServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
try{
System.out.println("**************************ADI NEW*****************");
JSch jsch = new JSch();
String user = <user>; //CHANGE ME
String host = <host>; //CHANGE ME
String passwd = <pwd>; //CHANGE ME
int port = 22;
Session session = jsch.getSession(user, host, port);
session.setPassword(passwd);
Hashtable<String, String> hashtable = new Hashtable<String, String>();
hashtable.put("StrictHostKeyChecking", "no");
session.setConfig(hashtable);
session.connect();
Channel channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
InputStream input = channel.getInputStream();
ps.println("tail -f /home/LogFile.log");
ps.close();
// response.setIntHeader("Refresh", 1);
response.setContentType("text/html");
/*Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
if(calendar.get(Calendar.AM_PM) == 0)
am_pm = "AM";
else
am_pm = "PM";
String CT = hour+":"+ minute +":"+ second +" "+ am_pm;*/
PrintWriter out = new PrintWriter (response.getOutputStream());//.getWriter();
out.println("<html><head><title>GuestBookServlet</title></head>");
out.println("<body>********************");
int SIZE = 1024;
byte[] tmp = new byte[SIZE];
while (true)
{
while (input.available() > 0)
{
int i = input.read(tmp, 0, SIZE);
if(i < 0)
break;
System.out.print(new String(tmp, 0, i)); // use document.write(new String(tmp, 0, i));
// System.out.println("******Adi i :"+i);
//out.println("Out by Adi i :"+i);
out.println(new String(tmp, 0, i));
}
if(!channel.isConnected())
{
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try
{
Thread.sleep(300);
}
catch (Exception ee)
{
}
}
out.println("</body></html>");
out.close();
channel.disconnect();
session.disconnect();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
这只会卡在流的打印上。如果我尝试通过不断更新来打印当前时间,我可以。它完美地反映在浏览器中。我有什么出路吗?
编辑: 好的,我已经缩小到
根本原因
. 这是
无限while循环
我在这里申请。此循环不断检查远程输入流中是否有任何内容。因此,sysouts 正在正确打印,但 out.write 没有。如果我删除无限 while 循环,则会打印一行,因为这是远程输入流中唯一的内容。关于如何在无限循环内获得浏览器输出的任何想法?