2015-10-05 29 views
0

我需要从驻留在一对多日志文件服务器上的日志文件收集信息子集。我有以下的Java代码,不会初始数据收集/过滤:需要过滤,解析和排序多个日志文件

public String getLogServerInfo(String userName, String password, String hostNames, String id) throws Exception{ 
    int timeout = 5; 
    String results = ""; 
    String[] hostNameArray = hostNames.split("\\s*,\\s*"); 

    for (String hostName : hostNameArray) { 
     SSHClient ssh = new SSHClient(); 
     ssh.addHostKeyVerifier(new PromiscuousVerifier()); 

     try { 
      Utils.writeStdOut("Parsing server: " + hostName); 
      ssh.connect(hostName); 
      ssh.authPassword(userName, password); 
      Session s = ssh.startSession(); 

      try { 
       String sh1 = "cat /logs/en/event/event*.log | grep \"" + id + "\" | grep TYPE=ERROR"; 
       Command cmd = s.exec(sh1); 
       results += IOUtils.readFully(cmd.getInputStream()).toString(); 

       cmd.join(timeout, TimeUnit.SECONDS); 
       Utils.writeStdOut("\n** exit status: " + cmd.getExitStatus()); 
      } finally { 
       s.close(); 
      } 
     } finally { 
      ssh.disconnect(); 
      ssh.close(); 
     } 
    } 

    return results; 
} 

results字符串变量看起来是这样的:

TYPE = ERROR,TIMESTAMP = 10/03/2015年07: 14:31 253 AM,HOST = server1,APPLICATION = app1,FUNCTION = function1,STATUS = null,GUID = null等等。 TYPE = ERROR,TIMESTAMP = 10/03/2015 07:14:59 123 AM, HOST = server1,APPLICATION = app1,FUNCTION = function1,STATUS = null,GUID = null等。 TYPE = ERROR,TIMESTAMP = 10/03/2015 07:14:28 956 AM,HOST = server2,APPLICATION = app1,FUNCTION = function2,STATUS = n ULL,GUID = null等等等等

我需要完成以下任务:

  1. 什么我需要做的是能够通过TIMESTAMP结果进行排序?它现在是未排序的,因为我列举了一个到多个文件,并将结果追加到字符串的末尾。
  2. 我只想要返回一列“列”的子集,如TYPE,TIMESTAMP,FUNCTION。我以为我可以REGEX它在grep,但也许阵列会更好?

结果只是打印到控制台/报告中,因为只打印失败的测试结果,并且仅用于故障排除目的。

回答

0

经过这一些工作之后,我发现其中一个键/值对允许在逗号中输入逗号,因此cut将不起作用。这里是成品:

我grep命令保持相同,从所有的服务器收集数据:

String sh1 = "cat /logs/en/event/event*.log | grep \"" + id + "\" | grep TYPE=ERROR"; 
Command cmd = s.exec(sh1); 
results += IOUtils.readFully(cmd.getInputStream()).toString(); 

把字符串转换成一个数组,所以我可以由线处理它们行:

String lines[] = results.split("\r?\n"); 

然后,我使用正则表达式来获取我需要的数据,为数组中的每一行重复以下操作,并根据需要重复使用所需的列数。这有点破解,我可能通过简单地替换有问题的键/值对中的逗号,然后使用SPLIT()和逗号作为分隔符,然后循环我想要的字段来做得更好。

lines2[i] = ""; 
Pattern p = Pattern.compile("TYPE=(.*?), APPLICATION=.*"); 
Matcher m = p.matcher(lines[i]); 

if (m.find()) { 
    lines2[i] += ("TYPE=" + m.group(1)); 
} 

最后,这将由时间戳进行排序,因为它是第二列:

Arrays.sort(lines2); 
1

我把你提供的输出列表放在一个名为test.txt的文件中,确保每一个“TYPE = ERROR etc. etc”都在一个新行中(我猜这在你的系统中是一样的输出,但不清楚)。

然后我用cat test.txt | cut -d',' -f1,2,5 | sort -k2做你想做的。

  • cut -d',' -f1,2,5基本上以逗号分割,并且只报告令牌编号1,2,5(TYPE,TIMESTAMP,FUNCTION)。

    TYPE =错误,TIMESTAMP:如果您想了解更多,您可以根据什么记号你按照第2列要

  • sort -k2排序(TIMESTAMP)

我得到的输出是添加更多号码= 10/03/2015 7点14分28秒956 AM,FUNCTION =函数2

TYPE = ERROR,TIMESTAMP = 10/03/2015 7时14分31秒253 AM,FUNCTION =功能1

TYPE = ERROR ,TIMESTAMP = 10/03/2015 07:14:59 123 AM,FUNCTION = fu nction1

那么你应该尝试做的,是|cut -d',' -f1,2,5 | sort -k2

我希望这有助于进一步管你的命令。

+0

,谢谢,我想切的解决办法工作,从而解决了#2。我是否需要将数据放入不同的对象才能排序?你上面看到的是阅读完所有文件后的结果。您所拥有的排序在每个文件中完成,因此最终结果仍未排序。 – Greg

+0

如果文件不是太大,你可以先将它们结合在一起(合并它们),然后应用这个解决方案。 – Edd

+0

或者,在过滤出不喜欢的列之后(如上所示),可以将每行存储到您定义的数据结构中,将它们全部添加到ArrayList中并使用Collections.sort(yourList,new Comparator ()),在比较器中需要为时间戳定义一个比较运算符。它很混乱,但它会起作用。 – Edd