書接上回:《ELK中Logstash的基本配置和用法》
引入logstash
Nginx日志格式修改
默認(rèn)情況下,Nginx的日志記錄的是下面的格式:
127.0.0.1 - - [21/Aug/2023:10:55:30 +0800] "POST /url/index HTTP/1.1" 200 39801 "http://test.cc/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
在 nginx.conf
中也可以看到相關(guān)配置信息:
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
現(xiàn)在為了方便收集日志,我們把這里的格式改為 json格式,在 nginx.conf
中加入下面的內(nèi)容:
log_format json '{"@timestamp": "$time_iso8601", '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"body_bytes_sent": "$body_bytes_sent", '
'"request_time": "$request_time", '
'"status": "$status", '
'"request_uri": "$request_uri", '
'"request_method": "$request_method", '
'"http_referrer": "$http_referer", '
'"http_x_forwarded_for": "$http_x_forwarded_for", '
'"http_user_agent": "$http_user_agent"}';
access_log logs/access.log json;
以上配置是手動組裝了一個json格式的配置信息。相關(guān)字段說明如下:
- $time_iso8601:格式化時間格式
- $remote_addr #記錄訪問網(wǎng)站的客戶端ip地址
- $remote_port # 客戶端的port
- $remote_user # 如果nginx有配置認(rèn)證,該變量代表客戶端認(rèn)證的用戶名
- $time_local #記錄訪問時間與時區(qū)
- $request #用戶的http請求起始行信息,包括方法名、請求地址、http版本
- $status #http狀態(tài)碼,記錄請求返回的狀態(tài)碼,例如:200、301、404等
- $body_bytes_sent #服務(wù)器發(fā)送給客戶端的響應(yīng)body字節(jié)數(shù)
- $http_referer #記錄此次請求是從哪個連接訪問過來的,可以根據(jù)該參數(shù)進(jìn)行防盜鏈設(shè)置。
- $http_user_agent #記錄客戶端訪問信息,例如:瀏覽器、手機(jī)客戶端等
- $http_x_forwarded_for #當(dāng)前端有代理服務(wù)器時,設(shè)置web節(jié)點記錄客戶端地址的配置,此參數(shù)生效的前提是代理服務(wù)器也要進(jìn)行相關(guān)的x_forwarded_for設(shè)置
- $request_body # post上傳的數(shù)據(jù)
- $request_time # 整個請求的總時間
- $upstream_response_time # 請求過程中,和php-fpm的交互時間
- $args # 請求中的參數(shù),如www.123.com/1.php?a=1&b=2的 $args就是a=1&b=2
- $content_length # HTTP請求信息里的”Content-Length”
- $conten_type # HTTP請求信息里的”Content-Type”
- $document_root # nginx虛擬主機(jī)配置文件中的root參數(shù)對應(yīng)的值
- $document_uri 或 $uri # 當(dāng)前請求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的
- $document_uri就是1.php,不包含后面的參數(shù)
- $request_uri # 請求的鏈接,包括和args
- $host # 主機(jī)頭,也就是域名
- $http_cookie # 客戶端的cookie信息
- $request_body_file # 做反向代理時發(fā)給后端服務(wù)器的本地資源的名稱
- $request_method # 請求資源的方式,GET/PUT/DELETE等
- $request_filename # 當(dāng)前請求的資源文件的路徑名稱,相當(dāng)于是document_uri的組合
- $scheme # 請求的協(xié)議,如ftp,http,https
- $server_protocol # 客戶端請求資源使用的協(xié)議的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等
- $server_addr # 服務(wù)器IP地址
- $server_name # 服務(wù)器的主機(jī)名
- $server_port # 服務(wù)器的端口號
記得把 相關(guān)log 的后面的main改成json,還有需要修改的虛擬主機(jī)的log。
修改后記錄的log格式如下:
{"@timestamp": "2023-08-21T11:24:00+08:00", "remote_addr": "127.0.0.1", "remote_user": "-", "body_bytes_sent": "11277", "request_time": "5.926", "status": "200", "request_uri": "/url/index", "request_method": "POST", "http_referrer": "http://test.cc/", "http_x_forwarded_for": "-", "http_user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"}
配置logstash收集nginx日志
寫入文件 logstash/config/logstash-to-es.conf
:
input {
file {
path => ["/home/rx/mywebsite.log"]
type => "mywebsite"
tags => ["mywebsite","prod"]
start_position => "beginning"
}
}
filter {
json {
source => "message"
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
index => "mywebsite-prod-log-%{+YYYY.MM.dd}"
user => "elastic"
password => "mypassword"
}
}
然后啟動logstash即可開始收集:
./bin/logstash -r -f ./config/logstash-to-es.conf
引入Redis
如果服務(wù)器比較多,寫入的日志落在不同的機(jī)器上,那么可以使用redis或者kafka作為中間件,收集多臺機(jī)器的日志進(jìn)行匯總處理。處理順序:logstash收集日志 -> redis/kafka -> logstash過濾日志 -> ES ->kibana
。流程圖如下:
由于我在測試的過程中沒有設(shè)置redis的密碼,導(dǎo)致運(yùn)行l(wèi)ogstash失敗
因此這里給redis設(shè)置一個密碼:
redis-cli
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass 123456
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123456"
收集日志寫入redis
添加配置文件vim logstash-7.1.0/config/my_config/logstash-to-redis.conf
,內(nèi)容如下:
input {
file {
path => ["/var/log/syslog"]
type => "system"
tags => ["syslog","test"]
start_position => "beginning"
}
file {
path => ["/var/log/auth.log"]
type => "system"
tags => ["auth","test"]
start_position => "beginning"
}
}
filter {
}
output {
redis {
host => ["127.0.0.1:6379"]
password => "123456"
db => "5"
data_type => "list"
key => "logstash"
}
}
上面redis部分的配置,host是個數(shù)組,可以配置多個redis服務(wù);db表示redis的第幾個數(shù)據(jù)庫;data_type這里用list類型模擬消息隊列;key表示將來存儲的redis數(shù)據(jù)的key的名稱。
然后啟動logstash,指定上面的配置信息:./bin/logstash -f ./config/my_config/logstash-to-redis.conf
然后打開redis客戶端看看是否有數(shù)據(jù):
可以看到redis中的消息隊列已經(jīng)存儲了很多數(shù)據(jù),接下來消費它。
從redis中讀取日志
在logstash的配置文件中添加配置文件 vim logstash-7.1.0/config/my_config/logstash-from-redis.conf
,內(nèi)容如下:
input {
redis {
host => "127.0.0.1"
port => 6379
password => "123456"
db => "5"
data_type => "list"
key => "logstash"
}
}
filter {
}
output {
if [type] == "system" {
if [tags][0] == "syslog" {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
index => "logstash-system-syslog-%{+YYYY.MM.dd}"
}
stdout { codec=> rubydebug }
}
else if [tags][0] == "auth" {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
index => "logstash-system-auth-%{+YYYY.MM.dd}"
}
stdout { codec=> rubydebug }
}
}
}
然后啟動logstash,指定上面的配置信息:./bin/logstash -f ./config/my_config/logstash-from-redis.conf
啟動后就開始消費redis里面的數(shù)據(jù)并寫入ES中。
logstash解析自定義日志格式
如果收集的日志不是json格式的,比如默認(rèn)的nginx日志是以空格分隔的:
針對這樣的日志格式,怎么配置logstash來解析呢?
下面記錄一下配置信息備用。
# vim logstash-7.17.12/config/logstash.conf
input {
redis {
host => "192.168.0.1"
port => 6379
password => "123456"
db => "0"
data_type => "list"
key => "filebeat"
}
}
filter {
if [app] == "www" {
if [type] == "nginx-access" {
grok {
match => {
"message" => "%{IPV4:remote_addr} - (%{USERNAME:remote_user}|-) \[%{HTTPDATE:time_local}\] \"%{WORD:request_method} %{URIPATHPARAM:request_uri} HTTP/%{NUMBER:http_protocol}\" %{NUMBER:http_status} %{NUMBER:body_bytes_sent} \"%{GREEDYDATA:http_referer}\" \"%{GREEDYDATA:http_user_agent}\" \"(%{IPV4:http_x_forwarded_for}|-)\""
}
overwrite => ["message"]
}
geoip {
source => "remote_addr"
target => "geoip"
database => "/opt/GeoLite2-City.mmdb"
add_field => ["[geoip][coordinates]", "%{[geoip][longitude]}"]
add_field => ["[geoip][coordinates]", "%{[geoip][latitude]}"]
}
date {
locale => "en"
match => ["time_local", "dd/MMM/yyyy:HH:mm:ss Z"]
}
mutate {
convert => ["[geoip][coordinates]", "float"]
}
}
}
}
output {
elasticsearch {
hosts => ["http://192.168.0.212:9200","http://192.168.0.213:9200","http://192.168.0.214:9200"]
index => "logstash-%{type}-%{+YYYY.MM.dd}"
}
stdout{codec => rubydebug }
}
引入Filebeat
Filebeat簡介
- Filebeat 是使用 Golang 實現(xiàn)的輕量型日志采集器,也是 Elasticsearch stack 里面的一員。Filebeat是用于轉(zhuǎn)發(fā)和集中日志數(shù)據(jù)的輕量級傳送工具。Filebeat監(jiān)視您指定的日志文件或位置,收集日志事件,并將它們轉(zhuǎn)發(fā)到Elasticsearch或 Logstash進(jìn)行索引。
- Logstash功能雖然強(qiáng)大,但是它依賴java、在數(shù)據(jù)量大的時候,Logstash進(jìn)程會消耗過多的系統(tǒng)資源,這將嚴(yán)重影響業(yè)務(wù)系統(tǒng)的性能,而filebeat就是一個完美的替代者,filebeat是Beat成員之一,基于Go語言,沒有任何依賴,配置文件簡單,格式明了,同時,filebeat比logstash更加輕量級,所以占用系統(tǒng)資源極少,非常適合安裝在生產(chǎn)機(jī)器上。
- Filebeat的工作方式如下:啟動Filebeat時,它將啟動一個或多個輸入,這些輸入將在為日志數(shù)據(jù)指定的位置中查找。對于Filebeat所找到的每個日志,F(xiàn)ilebeat都會啟動收集器。每個收集器都讀取單個日志以獲取新內(nèi)容,并將新日志數(shù)據(jù)發(fā)送到libbeat,libbeat將聚集事件,并將聚集的數(shù)據(jù)發(fā)送到為Filebeat配置的輸出。
- logstash如果收集大量日志的時候,會占用很大的內(nèi)存,使用Filebeat可以緩解這種情況。
Filebeat支持輸出到多種存儲介質(zhì):
引入Filebeat后的流程圖如下:
Filebeat安裝和配置
在 這里 下載(我這里下載的5.6.9版本的,不同版本的配置文件不同),然后解壓,可以根據(jù)需要修改配置文件filebeat.yml
。更多內(nèi)容參考:這里。
啟動filebeat并且輸出內(nèi)容nohup ./filebeat -e -c filebeat.yml &
啟動后,在當(dāng)前目錄下會生成一個nohup.out文件,可以查看filebeat啟動日志和運(yùn)行狀態(tài)。以操作系統(tǒng)中/var/log/secure文件的日志格式為例,消費輸出日志內(nèi)容示例如下:
{"@timestamp":"2023-08-30T11:27:48.755Z",
"@metadata":{"beat":"filebeat","type":"doc","version":"6.3.2","topic":"osmessages"},
"beat":{"name":"filebeatserver","hostname":"filebeatserver","version":"6.3.2"},
"host":{"name":"filebeatserver"},
"source":"/var/log/secure",
"offset":11326,
"message":"Jan 31 17:41:56 localhost sshd[13053]: Failed password for root from 172.16.213.37 port 49560 ssh2",
"prospector":{"type":"log"},
"input":{"type":"log"},
"fields":{"log_topic":"osmessages"}
}
輸出信息格式解讀
從這個輸出可以看到,輸出日志被修改成了JSON格式,日志總共分為10個字段,分別是"@timestamp"、"@metadata"、"beat"、"host"、"source"、"offset"、"message"、"prospector"、"input"和"fields"
字段,每個字段含義如下:
- @timestamp:時間字段,表示讀取到該行內(nèi)容的時間。
- @metadata:元數(shù)據(jù)字段,此字段只有是跟Logstash進(jìn)行交互使用。
- beat:beat屬性信息,包含beat所在的主機(jī)名、beat版本等信息。
- host: 主機(jī)名字段,輸出主機(jī)名,如果沒主機(jī)名,輸出主機(jī)對應(yīng)的IP。
- source: 表示監(jiān)控的日志文件的全路徑。
- offset: 表示該行日志的偏移量。
- message: 表示真正的日志內(nèi)容。
- prospector:filebeat對應(yīng)的消息類型。
- input:日志輸入的類型,可以有多種輸入類型,例如Log、Stdin、redis、Docker、TCP/UDP等
- fields:topic對應(yīng)的消息字段或自定義增加的字段。
通過filebeat接收到的內(nèi)容,默認(rèn)增加了不少字段,但是有些字段對數(shù)據(jù)分析來說沒有太大用處,所以有時候需要刪除這些沒用的字段,在filebeat配置文件中添加如下配置,即可刪除不需要的字段:
processors:
- drop_fields:
fields: ["beat", "input", "source", "offset"]
這個設(shè)置表示刪除"beat"、"input"、"source"、"offset"
四個字段,其中, @timestamp
和@metadata
字段是不能刪除的。做完這個設(shè)置后,再次查看輸出日志,已經(jīng)不再輸出這四個字段信息了。
從nginx日志文件中讀取內(nèi)容
修改 filebeat 的配置文件,從nginx日志文件中讀取內(nèi)容,然后輸出到redis:vim filebeat-5.6.9/filebeat.yml
,內(nèi)容如下:
filebeat.inputs:
- type: log
paths:
- /usr/local/nginx/logs/access.log
# tags: ["access"]
fields:
app: www
type: nginx-access
fields_under_root: true
- type: log
paths:
- /usr/local/nginx/logs/error.log
# ags: ["error"]
fields:
app: www
type: nginx-error
fields_under_root: true
output.redis:
hosts: ["192.168.0.1"]
port: 6379
password: "123456"
key: "filebeat"
db: 5
datatype: list
啟動filebeat:nohup ./filebeat -e -c filebeat.yml -d "publish" &
然后查看redis里面已經(jīng)有了nginx的日志數(shù)據(jù)。文章來源:http://www.zghlxwxcb.cn/news/detail-670791.html
然后再消費者機(jī)器上配置logstash消費redis中的數(shù)據(jù),vim logstash-7.17.12/config/logstash-from-redis.conf
,配置內(nèi)容如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-670791.html
input {
redis {
host => "192.168.0.1"
port => 6379
password => "123456"
db => "5"
data_type => "list"
key => "filebeat"
}
}
filter {
json {
source => "message"
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
index => "mywebsite-prod-log-%{+YYYY.MM.dd}"
user => "elastic"
password => "mypassword"
}
}
到了這里,關(guān)于使用ELK(ES+Logstash+Filebeat+Kibana)收集nginx的日志的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!