2015-10-05 67 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