logstash主用于日志實時數據收集、解析,并將數據轉發的工具,內置的功能也相當強大。但,同時意味著,他可能接收到各種情況的數據。
此處,我們主要講解我實際使用中,碰到的一個小問題,換行(\n)。
logstash的換行處理,可以有多種方式,比如如imultiline,可以將多行合并之類的,這種適合input 直接讀取文件。
但有時,你接收到的消息內容,即某個字段的內容,本身已經是換行的內容,經過input的轉換后,加上了轉義符,換行變成\\n。
這里舉例我實際碰到的環境:kafka+logstash+elasticsearch
kafka采集到的數據,已經是一條完整的數據,如:
2023/08/10 09:15:26 main.go:20 E! 測試多行日志記錄
第二行日志,需要合并
第三行也要合并
logstash.conf配置如下:
input {kafka {bootstrap_servers => "kafka.test.com"topics => ["test"]}
}filter {json {source => "message" #原mesage字段為json格式的字符串,轉換成json數據}grok{match => ["message", "%{DATE:date} %{TIME:time} %{DATA:logclass}: %{DATA:loglevel}! %{GREEDYDATA:msg}"] }mutate {add_field => {"logdate" => "%{date} %{time}"} # 新增字段,多字段字符串組合成新字段logdateremove_field => ["date","time"]}
}output {elasticsearch {hosts => ["http://elasticsearch:9200"]index => "testlog"}
}
此時kibana上查看到的數據是在原本換行的地方變成\n。因為kafka在接到到換行的數據時會轉成\n或\n\t。而logstash在接收到kafka的數據時,會當成字符串,自動加上轉義符,要正常顯示換行,需要把\\n 替換成\n。
?網上找了一堆相關資料,說的的方法是沒錯,但就是沒有效果,如
filter {mutate {gsub => ["message","\\n",""] # 顯式的采用此種方法替換
}
因為logstash會把“\\n”當成是有轉義符處理,即\n,也即實際的換行。所以“\\n”其實替換的是實際的換行,實際已經可以換行的數據,替換成空字符。
如果要es中顯示的\n,變成實際換行顯示,需要以下配置:
filter {mutate {gsub => ["message","\\\\n","\n"] # 字符替換 ,將\\n 替換成 \n; "\\\\n"需要增加轉義符。}
最終es顯示效果如下: