编辑:我误读了您的问题,因为您要求更简单的解决方案,但我试图为复杂的方法提供解决方案。无论如何,我希望它会有用。
实际答案:
我为我的项目完成了以下活动
- 在远程 unix 服务器上使用 shell 脚本清除日志
- 执行前端活动
- 在预定义时间(例如 60 秒)后捕获日志
- Sftp 返回客户端计算机
首先你需要一个 SFTP 客户端和 SSH 客户端来与 unix 服务器交互
这里 Node 是一个包含 Unix 环境细节的对象。所以相应地改变。
为此使用 JSch 库
public static String runCommand(String Command, Node node )
{
String output = null;
if (node.getConnType().equals("SSH")){
int exitStatus = 0;
try{
JSch jsch=new JSch();
JSch.setConfig("StrictHostKeyChecking", "no");
Session session=jsch.getSession(node.getUserName(), node.getHost(), 22);
session.setPassword(node.getPassword());
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password");
session.connect();
String command=Command;
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
output = new String(tmp, 0, i);
}
if(channel.isClosed()){
if(in.available()>0) continue;
exitStatus= channel.getExitStatus();
//System.out.println("exit-status: "+exitStatus);
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
channel.disconnect();
session.disconnect();
}
catch(Exception e){
e.printStackTrace();
}
if (exitStatus == 0)
{
if(output != null)
return output.replaceAll("[\\n\\r]", "");
}
}
return null;
}
SFTP 客户端
public boolean transferFileSFTP(Node node,String srcDir,String targetDir,String srcFileName,String targetFileName, String direction)
{
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession(node.getUserName(), node.getHost(), 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setConfig("PreferredAuthentications",
"publickey,keyboard-interactive,password");
session.setPassword(node.getPassword());
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
System.out.println("src:" + srcDir+srcFileName );
System.out.println("target:" + targetDir+targetFileName );
sftpChannel.get(targetDir+targetFileName, srcDir+srcFileName);
sftpChannel.exit();
session.disconnect();
return true;
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
return false;
}
现在,
等到所需时间并使其基于线程以同时从涉及的不同应用程序收集日志,
使用 ExecutorService 和 Future 实用程序
因此创建了一个 LogCollector 类来发起请求,另一个是 ThreadClass(logical),它将在日志文件上执行活动。
LogCollector.java
public class LogCollector {
private static ExecutorService pool = Executors.newFixedThreadPool(100);
private static List<Future<String>> list = new ArrayList<Future<String>>();
public static void add(Node node, String srcDir, String targetDir, String srcFileName, String targetFileName, long wait )
{
list.add(pool.submit(new LogCollectorThread(System.currentTimeMillis()/1000,wait, srcDir, targetDir, srcFileName, targetFileName, node )));
}
public static void getResult()
{
try{
for (Future<String> future : list) {
String out =future.get();
//DO whatever you want to do with a response string return from your thread class
}
pool.shutdown();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
LogCollectorThread.java
public class LogCollectorThread implements Callable<String>{
long startTime;
long wait;
String srcFileName;
String targetFileName;
String srcDir;
String targetDir;
Node node;
public LogCollectorThread(long startTime, long wait,String srcDir, String targetDir,String srcFileName, String targetFileName,
Node node) {
super();
this.startTime = startTime;
this.wait = wait;
this.srcFileName = srcFileName;
this.targetFileName = targetFileName;
this.srcDir = srcDir;
this.targetDir = targetDir;
this.node = node;
}
/***
* Returns a String with Parameters separated by ',' and status at the end
* status values:
* 0 - successfully retrieved log file
* 1 - failure while retrieving log file
*/
@Override
public String call() throws Exception {
while((System.currentTimeMillis()/1000 - startTime)<=wait)
{
Thread.sleep(1000);
}
MyFTPClient sftp= new MyFTPClient();
boolean result =sftp.transferFileSFTP(this.node, this.srcDir, this.targetDir, this.srcFileName, this.targetFileName, "From");
System.out.println(this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName);
if(result == true)
return this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName +"," + "0" ;
else
return this.node.getHost() + ","+ this.srcDir + ","+this.targetDir +","+ this.srcFileName +","+ this.targetFileName +"," + "1" ;
}
}
如何使用 LogCollector 类:
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
Helper.runCommand("cd /opt/redknee/app/crm/current/log/; echo > AppCrm.log", testEnv.getBSS());
LogCollector.add(testEnv.getBSS(), "collectedLogs\\", "/opt/redknee/app/crm/current/log/", timeStamp + "_" + testEnv.getBSS().getHost() + "_BSS_AppCrm.log" , "AppCrm.log", 60);
//So your thread is working now, so now perform your Front End Activity
//After 60 seconds, log file will be SFTPed to client host
//You can perform you activity before adding logCollectorThread or just before that
LogCollector.getResult();
这里我给出了太多的代码,
但是逐行描述每一步太难了。
我想证明的主要事情是使用 java 大部分事情都是可能的。
由您决定它的重要性以及是否值得做。
现在满足您搜索特定字符串的确切要求。
正如您在 logCollectorThread 中看到的,
目前我什么也没做,只是等到 60 秒完成。
所以在这里你可以使用 runCommand 从日志中 grep 所需的字符串
你可以使用像
这样的命令
grep -i "Action Completed" | grep -v 'grep' | wc -l
如果它返回 1,你找到了你的字符串
同样,您可以检查失败消息。
并从您的线程返回所需的字符串,并将其作为 threadCollector.getResult() 方法的结果。
一旦文件通过 FTP 传输到您的客户端,使用 Java 将其解析为特定字符串将非常容易。 StackOverflow 将在这方面为您提供帮助:)
声明者:不要期望代码能够完全正常工作。
它会起作用,但你必须付出你的努力。插入缺失的部分需要您的 Java 知识