簡體   English   中英

使用 awk 和 sed 進行日志解析

[英]Log Parsing using awk and sed

我有

2019-11-14T09:42:14.150Z  INFO ActivityEventRecovery-1 ActivityCacheManager - - [nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"] Handling activity 0082bc26-70a6-433e-a470-
2019-11-14T09:43:08.097Z  INFO L2HostConfigTaskExecutor2 TransportNodeAsyncServiceImpl - FABRIC [nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"] Calling uplinkTeamingChangeListener.onTransportNodeUpdated on TN 72f73c66-da37-11e9-8d68-005056bce6a5 revision 5
2019-11-14T09:43:08.104Z  INFO L2HostConfigTaskExecutor2 Publisher - ROUTING [nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"] Refresh mac address of Logical router port connected with VLAN LS for logical router LogicalRouter/f672164b-40cf-461f-9c8d-66fe1e7f8c19
2019-11-14T09:43:08.105Z  INFO L2HostConfigTaskExecutor2 GlobalActivityRepository - - [nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"] Submitted activity 73e7a942-73d2-4967-85fa-7d9d6cc6042b in QUEUED state with dependency null exclusivity true and requestId null and time taken by dao.create is 1 ms

我想將這些日志解析為 json object。 到目前為止,我正在使用 python 正則表達式並將其放入字典中。

    currentDict = {
                               "@timestamp" : regexp.group(1),
                               "Severity" : regexp.group(2),
                               "Thread" : regexp.group(3),
                               "Class" : regexp.group(4),
                               "Message-id" : regexp.group(5),
                               "Component" : regexp.group(6),
                               "Message" : regexp.group(7),
                               "id's" : re.findall(x[1], regexp.group(7))
                        }

但這種方式非常慢,即 200mb 文件需要 5-10 分鍾。

我使用的 Python 正則表達式 - (\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ)\s+(INFO|WARN|DEBUG|ERROR|FATAL|TRACE)\s+(.*?)\s+(.*?)\s+\-\s+(.*?)\s+(?:(\[?.*?\])?)\s(.*)

預期 output -

{"@timestamp" : "2019-11-14T09:42:14.150Z", "Sevirity" : "INFO", "Thread" : "ActivityEventRecovery-1", "Class" : "ActivityCacheManager - -", "Component" : "[nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"]", "Message" : "Handling activity 0082bc26-70a6-433e-a470-"}
{"@timestamp" : "2019-11-14T09:43:08.097Z", "Sevirity" : "INFO", "Thread" : "L2HostConfigTaskExecutor2", "Class" : "TransportNodeAsyncServiceImpl - FABRIC", "Component" : "[nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"]", "Message" : "Calling uplinkTeamingChangeListener.onTransportNodeUpdated on TN 72f73c66-da37-11e9-8d68-005056bce6a5 revision 5}"}
{"@timestamp" : "2019-11-14T09:43:08.104Z", "Sevirity" : "INFO", Thread : "L2HostConfigTaskExecutor2", "Class" : "Publisher - ROUTING", "Component" : "[nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"]", Message : "Refresh mac address of Logical router port connected with VLAN LS for logical router LogicalRouter/f672164b-40cf-461f-9c8d-66fe1e7f8c19}"}
{"@timestamp" : "2019-11-14T09:43:08.105Z", "Sevirity" : "INFO", "Thread" :  "L2HostConfigTaskExecutor2", "Class" :   "GlobalActivityRepository", "Component" : "[nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"]", "Messages" : "Submitted activity 73e7a942-73d2-4967-85fa-7d9d6cc6042b in QUEUED state with dependency null exclusivity true and requestId null and time taken by dao.create is 1 ms"}}

在互聯網上,我發現使用 awk 和 sed 可以更快地完成。 我對此了解不多。 如何使用awksed進行解析。

請幫忙!

# For timestamp
cut -d " " -f 1 in > temp
sed -i -e 's/^/{"@timestamp" : "/' temp
awk 'NF{print $0 "\", "}' temp > a

# For Severity ...

# For Thread ...

# For Class
cut -d " " -f 5,6,7 in > temp
sed -i -e 's/^/"Class" : "/' temp
awk 'NF{print $0 "\", "}' temp > d

# For Component
grep -o -P '(?<=\[).*(?=\])' in > temp
sed -i -e 's/^/"Component" : \["/' temp
awk 'NF{print $0 "\"], "}' temp > e

# For Message ...

# Merge all files line by line
paste -d " " a b c d e f

我將簡短地解釋這個腳本的一些內容,cut 用於將單詞放在兩個空格之間。 Sed 將文本添加到每行的開頭。 Awk 正在將文本添加到每行的末尾。

我離開了嚴重性、線程和消息部分,因為它們與其他部分相同。 該腳本相當簡單,但如果不知道如何使用工具本身,您將無法理解它,因為您說您不了解它們。

這個 sed 腳本應該做得非常快:

sed -E 's/^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+\s-\s[^ ]+)\s+(\[.*\])\s+(.*)$/{"@timestamp" : "\1", "Severity" : "\2", "Thread" : "\3", "Class" : "\4", "Component" : "\5", "Message" "\6"}/' inputdata.dat

解釋:

  • sed 's/^<regular-expression>$/<output-string>/'操作/替換每個匹配正則表達式^<input-line>$ 特此^表示開始$行尾
  • -E :表示使用擴展正則表達式 擴展的正則表達式現在包含在 POSIX 中。 在 grep 的手冊頁中,您可以找到:

    基本與擴展正則表達式:

    基本的正則表達式中,元字符?、+、{、|、(和)失去了它們的特殊意義; 而是使用反斜杠版本 \?、\+、\{、\|、\( 和 \)。

  • (...)...(...)...(...)...(...) ...) 中的內容是 - 在此腳本中 - 與第一個、第二個、第三個匹配的描述。 ..第六個數據字段。 通常,它是將整個正則表達式細分為不同單元的工具,您可以通過\1\2 ... 在 output 字符串中引用這些單元。 這樣做,您可以將文本操作限制在某些上下文中。 在這種情況下,數據字段本身保持不變,只有上下文會改變。

  • [^ ]+ :在[...]中描述了一個class 字符[A-Za-z0-9]表示恰好是一個字母或數字字符[0-9]+表示至少一位數字[ ]表示一個空白[^0-9 ]表示正好一個字符 - 除了數字之外的任何其他內容,但是空白,所以這里[^ ]+表示至少一個字符 - 除了空白之外的任何其他內容-> 第一個內容的正確正則表達式模式三個數據字段
  • ([^ ]+\s-\s[^ ]+) :第四個數據字段“Class”是一個復合數據字段,兩個組件和一個分隔符' - ' (1st - 2nd),在 char 類 ( [..] ) 使用\s而不是' '
  • (\[.*\]) :第五個數據字段“組件”也是一個復合數據字段,但包含在方括號[]中。 為了匹配括號字符本身(不是通過將這些字符括在括號中的字符 class),您必須使用括號字符[]前面加上反斜杠\ . 是通配符,因此 \[. .* \[.*\]中的 .* 表示括號之間的所有內容
  • \s+ :至少一個空格或制表符(在數據字段之間)
  • 所以第六個數據字段 - 靈活長度的消息 - 可以匹配為(.*)這意味着rest 之后]和緊隨其后的空格直到行尾
  • \1... \6 (在右側):output 中對正則表達式中相應表達式組(在本例中為數據字段)的引用。
  • inputdata.dat :將其替換為您的數據文件的名稱

為了獲得可運行的 shell 腳本,將其保存為文件:

#! /bin/sh
sed -E 's/^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+\s-\s[^ ]+)\s+(\[.*\])\s+(.*)$/{"@timestamp" : "\1", "Severity" : "\2", "Thread" : "\3", "Class" : "\4", "Component" : "\5", "Message" "\6"}/' "$1" >"$2"

之后運行命令chmod +x <your-scriptname>使腳本可執行。 然后它可以作為./<your-scriptname> <input-file> <wanted-output-file-name>運行。

注意力:

  • 不要對輸入和 output 文件使用相同的文件名
  • 如果文件名 output 的文件已經存在,它將被覆蓋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM