我必须在我的远程linux机器上拖尾日志文件并在浏览器上连续打印输出。我已经设法使用JSch尾随它,我当前正在将输出打印为System out。我现在正在使用servlet(尽管客户端只是使用jsp)。问题是,当我尝试在浏览器上打印尾流时,浏览器会进入冻结状态,好像它正在不断加载某些东西(它是!!)。在浏览器冻结时,sysout日志可以在控制台上完美地打印尾流。这是我的servlet
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
}
}
这只会在打印流时遇到困难。如果我通过不断更新它来尝试打印当前时间,我能够。它在浏览器中完美体现。有什么出路吗?
修改 好的,我已经缩小到了
根本原因
。这是
无限循环
我在这里申请。此循环连续检查输入流中是否有来自远程的任何内容。因此,sysout正确打印,但out.write不正确。如果我删除无限循环,则会打印一行,因为它是远程输入流中唯一的thig。关于如何在浏览器内部无限循环获取输出的任何想法?
答案 0 :(得分:2)
好的,我终于在花了一些时间之后就做到了。在客户交付繁忙的时候在这里更新。以下是步骤
编写了一个名为TailLogServlet.java的servlet,它具有拖尾远程日志的代码。
准备了一个名为showTailLogs.jsp的jsp,它每2秒通过ajax调用一次这个servlet,并在浏览器上打印响应。此调用在jsp的 body onLoad 函数中完成
这是servlet和jsp:
的 showTailLogs.jsp 强>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/myStyle.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jquery.js"></script>
<title>Show Tail Logs</title>
<script>
var binDone = false;
var lastUpdate = "Starting logs";
function tail2() {
if (!binDone) {
$.post("/<<Context>>/TailLogServlet",
{
logUID:"<%= request.getParameter("logUID")%>",
logPwd:"<%= request.getParameter("logPwd")%>",
host:"<%= request.getParameter("host")%>",
logFileName:"<%= request.getParameter("logFileName")%>"
},
function(data,status){
$("#thePlace").append(data);
if (data.indexOf(lastUpdate)>-1) {
binDone = true;
}
});
}
}
</script>
</head>
<body onLoad='tail2(); setInterval("tail2()", 2000)'>
<div id="wrapper" class="radius">
<div id="imageContainer">
<img alt="my Image" class="myLogo" src="myLogo.jpg" />
<h1>Show Tail Logs</h1>
</div>
<div id="navContainer" style="color:white">
Logs Update automatically. Please don't press refresh button...
</div>
<div>
<div id="thePlace"></div>
</div>
</body>
</div>
</html>
的 TailLogServlet.java 强>
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 {
try
{
//System.out.println("*************GETTT TailLogServlet Hit. logFileName :"+request.getParameter("logFileName"));
PrintWriter pw=response.getWriter();
response.setContentType("text/html");
response.setHeader("Cache-Control", "no-cache");
JSch jsch = new JSch();
String user = request.getParameter("logUID"); //CHANGE ME
String host = request.getParameter("host");//CHANGE ME
String passwd = request.getParameter("logPwd"); //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 "+request.getParameter("logFileName"));
ps.close();
int SIZE = 1024;
byte[] tmp = new byte[SIZE];
long startTime = System.currentTimeMillis();
while ((System.currentTimeMillis()-startTime)< 3*1000){
while (input.available() > 0)
{
int i = input.read(tmp, 0, SIZE);
if(i < 0)
break;
System.out.println(new String(tmp, 0, i));
pw.println(new String(tmp, 0, i));
}
pw.flush();
}
}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
//System.out.println("*************POSTTTTT TailLogServlet Hit. logFileName :"+request.getParameter("logFileName"));
doGet(request, response);
}
}
代码可能有一些不需要的导入,因为我还没有完成清理。