之前介紹過如何使用文件系統通過Logstash將數據推送至elasticsearch來實現日誌的線上分析。而這次介紹的是使用rabbit作爲數據源進行數據操作的方法
logstash只是作爲一個數據處理的通道,但很多時候面對數據我們不僅僅需要的是處理,還需要考慮數據的產生速度和數據的安全提出要求。而使用消息隊列能夠滿足對服務壓力和數據安全的需求。
ps. 在很多使用logstash的設計中使用kafka作爲消息隊列,不過個人的服務器中並未安裝kafka(就是懶),所以這篇介紹的是使用rabbit作爲消息隊列,後續個人雲服務器安裝kafka後再介紹其相關內容。
關於logstash數據源的相關介紹可以看之前的內容
Logstash——Logstash從MySQL中收集數據並輸出添加
Logstash——Logstash從Redis中收集數據並輸出
Logstash-Rabbit數據源配置
最開始先看下Rabbit作爲數據來源時支持的所有配置
input {
jdbc {
### 啓用消息確認。
ack => true
### 可選隊列參數作爲數組。
arguments =>
### 當最後一個使用者斷開連接時,是否應該在代理上刪除隊列?
automatic_recovery =>
### 當最後一個使用者斷開連接時,是否應該在代理上刪除隊列?
automatic_recovery =>
### 將此設置爲自動從斷開的連接中恢復。您幾乎可以肯定不想覆蓋它!
connect_retry_interval =>
### 重試連接之前等待的時間
connection_timeout =>
### 是否持久隊列
durable =>
### 綁定隊列的交換的名稱
exchange =>
### 要綁定的交換類型。
exchange_type =>
### 隊列是否排他?排他隊列只能由聲明瞭它們的連接使用,並且在關閉時將被刪除
exclusive =>
### 心跳超時
heartbeat =>
### Rabbitmq輸入/輸出RabbitMQ服務器地址主機的常用功能可以是單個主機
host =>
### 將隊列綁定到交換機時要使用的路由密鑰。
key =>
### 在中啓用消息標頭和屬性的存儲@metadata。這可能會影響性能
metadata_enabled =>
### 如果爲true,將被動聲明隊列
passive =>
### RabbitMQ密碼
password =>
### RabbitMQ端口進行連接
port =>
### 預取計數。如果使用該ack 選項啓用了確認
prefetch_count =>
### 需要訂閱的隊列
queue =>
### 是否啓動ssl
ssl =>
### 證書密碼
ssl_certificate_password =>
### 證書地址
ssl_certificate_path =>
### 證書版本
ssl_version =>
### 隊列無響應後進行重試的間隔
subscription_retry_interval_seconds =>
### 工作線程數
threads =>
### rabbit用戶
user =>
}
}
完成Logstash從Rabbit中收集數據
安裝Logstash
這裏可以看之前的文章安裝Logstash並完成一個簡單的日誌收集功能
Logstash配置
使用下面的配置可以很輕鬆的將隊列中的數據通過logstash傳遞到ES中
input {
rabbitmq {
host => "localhost"
port => 5672
user => "admin"
password => "admin"
queue => "logstash_one"
durable => true
codec => json
type => "one"
}
}
output {
elasticsearch {
hosts => "http://localhost:9200"
index => "redis_test_list_one"
user => exception_user # 此爲es的賬號,應用配置時刪除註釋
password => exception # 此爲es的密碼,應用配置時刪除註釋
}
stdout {}
}
同樣是數據編碼
在對數據不進行任何處理的時候可能會出現,下面這種數據
這個時候需要對發送的數據進行編碼處理,這裏可以看我之前介紹Rabbit的內容: RabbitMQ配置消息確認回調、消息轉換以及消息異常處理
元數據的獲取
官方提供了metadata_enabled => true
的配置,啓動此配置後可以從[@metadata][rabbitmq_properties]
中獲得一些關於隊列消息的數據。數據包含下面的內容
- app-id
- cluster-id
- consumer-tag
- content-encoding
- content-type
- correlation-id
- delivery-mode
- exchange
- expiration
- message-id
- priority
- redeliver
- reply-to
- routing-key
- timestamp
- type
- user-id
當然上面數據並不是絕對存在的,有些參數需要傳遞消息的時候設置過纔可能存在。
[@metadata][rabbitmq_properties]數據的獲取
這裏爲了獲取rabbit的元數據有一些需要注意的內容,當時也是困擾我很久。下面是我嘗試多次後最終用來演示rabbit元數據獲取的配置。
input {
rabbitmq {
host => "localhost"
port => 5672
user => "admin"
password => "admin"
queue => "logstash_one"
durable => true
codec => json
type => "one"
}
rabbitmq {
host => "localhost"
port => 5672
user => "admin"
password => "admin"
queue => "logstash_two"
durable => true
codec => json
type => "two"
metadata_enabled => true
add_field => {
metadataExchange => "%{[@metadata][rabbitmq_properties][exchange]}"
}
}
}
filter {
mutate {
add_field => {
exchange => "%{[@metadata][rabbitmq_properties][exchange]}"
}
}
if [type] == 'two' {
mutate {
add_field => {
age2 => "%{age}"
version2 => "%{@version}"
}
}
}
}
output {
stdout {
codec => rubydebug {
metadata => true
}
}
}
啓動logstash服務
使用上面的配置啓動logstash服務。
bin/logstash -f ./config/rabbitmq/config1.conf
此時控制檯輸出
這裏可以看到,關於元數據的使用有一些要注意的內容
頂級參數
對於頂級元素我們可以直接使用[參數名]
操作,比如下面這樣
if [type] == 'two' {
mutate {
add_field => {
age2 => "%{age}"
version2 => "%{@version}"
}
}
}
使用參數內容或者子參數內容的使用
對於需要賦值操作使用數據中內容的時候可以使用%{參數名}
或者 %{[參數名][參數名][參數名]}
進行操作,比如下面這種
filter {
mutate {
add_field => {
exchange => "%{[@metadata][rabbitmq_properties][exchange]}"
}
}
if [type] == 'two' {
mutate {
add_field => {
age2 => "%{age}"
version2 => "%{@version}"
}
}
}
}
使用Rabbit元數據[@metadata][rabbitmq_properties]
此處需要注意,對於rabbit中的元數據,之前我嘗試在input插件中獲取其數據,最終獲得的結果就和上面控制檯中輸出的那樣,其被當成了字符串直接輸出出來。
{
"@timestamp" => 2020-04-25T14:59:50.088Z,
"@version" => "1",
"exchange" => "%{[@metadata][rabbitmq_properties][exchange]}",
"type" => "one",
"message" => "hello world",
"tags" => [
[0] "_jsonparsefailure"
]
}
而在過濾器中獲取此數據爲正常
filter {
mutate {
add_field => {
exchange => "%{[@metadata][rabbitmq_properties][exchange]}"
}
}
if [type] == 'two' {
mutate {
add_field => {
age2 => "%{age}"
version2 => "%{@version}"
}
}
}
}
同時需要注意,在上面兩個input插件中有一個並未啓動metadata_enabled => true
的配置,而在filter
中嘗試獲取此數據在最後的輸出中也會被當成字符串輸出。所以在使用rabbit中的元數據時候,除了保證在合適的地方調用其語法還需要保證是否開啓了metadata_enabled
(同時也需要注意,官方提醒在開啓了此功能後會降低處理的性能)。
個人水平有限,上面的內容可能存在沒有描述清楚或者錯誤的地方,假如開發同學發現了,請及時告知,我會第一時間修改相關內容。假如我的這篇內容對你有任何幫助的話,麻煩給我點一個贊。你的點贊就是我前進的動力。