之前编写过低版本的ELK日志收集,最近换公司,部署了一套单节点7.13版本ELK,7.13版本较之前6.x版本还是有很大区别的。
一、环境
ELK部署在同一台Centos7.9服务器上
Filebeat用于收集nginx日志
java日志使用的是阿里云NAS共享存储,所以直接将日志目录挂载到了ELK服务器上
JDK 1.8
二、下载安装
1、下载
# elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.2-linux-x86_64.tar.gz
# logstash
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.13.2-linux-x86_64.tar.gz
# kibana
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.13.1-linux-x86_64.tar.gz
# filebeat
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.2-linux-x86_64.tar.gz
2、安装
创建elasticsearch和kibana的启动用户(这两个服务不能用root启动)
# useradd es
ELK服务器上不需要安装filebeat,所以将下载下来的三个安装包全部解压到/usr/local目录下
其中elasticsearch和kibana两个解压后的目录需要授权es用户
# chown -R es:es elasticsearch kibana
安装jdk1.8
持久化目录更改:
/data/elasticsearch_data/data # elasticsearch数据目录
/data/elasticsearch_data/log # elasticsearch日志目录
/data/nohup_logs # logstash和kibana的nohup启动日志存放位置
/data/logstash_work # logstash多配置文件启动,第二个需要指定一个工作目录
配置修改:
# elasticsearch
# egrep -v '^$|^#' /usr/local/elasticsearch-7.13.2
需要修改以下配置,其实除了目录以外不需要修改,但是如果要修改 network.host 允许其他服务器访问的话,就需要修改其他配置了,所以我这里做了修改。
node.name: node-1
path.data: /data/elasticsearch_data/data
path.logs: /data/elasticsearch_data/log
network.host: 0.0.0.0
cluster.initial_master_nodes: ["node-1"]
http.cors.enabled: true
http.cors.allow-origin: "*"
3、启动
# elasticsearch
# su - es
# cd /usr/local/elasticsearch-7.13.2
# ./bin/elasticsearch -d
# kibana
# cd /usr/local/kibana-7.13.1-linux-x86_64/
# 指定nohup日志输出位置为上面创建的目录
# nohup ./bin/kibana > /data/nohup_logs/kibana.log &
logstash 和 filebeat 配置完成后再进行启动
三、日志收集分析
java日志收集
直接通过logstash收集本地挂载的日志
# cat /usr/local/logstash-7.13.2/config/java_log.conf 这是我根据自己环境创建的java日志收集配置文件
input {
file {
path => "/pod-log/axt_resources/main.log" # java日志源
type => "axt_resources_log"
start_position => "beginning"
}
}
input {
file {
path => "/pod-log/axt_crm/main.log"
type => "axt_crm_log"
start_position => "beginning"
}
}
# 过滤切割
filter {
grok {
match => {
"message" => '%{DATESTAMP:time} \[%{WORD:threadName}\] %{WORD:logLevel} %{GREEDYDATA:syslog_message}'
}
}
date {
match => ["time", "YYYY/MM/dd-HH:mm:ss"]
locale => en
}
}
# 输出到es
output {
stdout {
codec => rubydebug
}
if [type] == 'axt_resources_log' {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "axt_resources_log-%{+YYYY.MM.dd}" # 定义索引名称
template_overwrite => true
}
}
if [type] == 'axt_crm_log' {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "axt_crm_log-%{+YYYY.MM.dd}"
template_overwrite => true
}
}
}
root用户启动logstash
# cd /usr/local/logstash-7.13.2
# 指定配置文件名称及nohup日志输出位置
# nohup bin/logstash -f config/java_log.conf > /data/nohup_logs/logstash.log &
kibana配置查看
7.13的kibana和6.x的有些区别,熟悉一下就好
打开进入之后按图中所示点击进入
创建索引
输入刚刚logstash配置文件中输出时的索引名称加 ‘*’ 号匹配
然后点击下一步
选择时间字段创建完成
查看日志
选择刚刚创建的索引可以看到日志已经收集出来,剩下的搜索和旧版本没什么两样
nginx日志收集
因为我的nginx日志没有存放到共享目录中,所以需要在nginx服务器上安装filebeat,通过filebeat
解压filebeat二进制包到/usr/local下
创建配置文件目录
cd /usr/local/filebeat-7.13.2-linux-x86_64
mkdir conf
编写filebeat配置文件
我这里有三台nginx日志服务器
$ cat /usr/local/filebeat-7.13.2-linux-x86_64/conf/nginx-logstash.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /data/nginx/logs/js.access.log
- /data/nginx/logs/js.error.log
- /data/nginx/logs/jy.access.log
- /data/nginx/logs/jy.error.log
- /data/nginx/logs/www.access.log
- /data/nginx/logs/www.error.log
tail_files: true
input_type: log
fields.service: web1-nginx
tags: ["web1-nginx"]
output.logstash:
hosts: ["172.16.105.148:5044"]
index: "nginx-web1-log-%{+yyyy.MM.dd}"
setup.template.name: "nginx"
setup.template.pattern: "nginx-*"
setup.template.enabled: false
setup.template.overwrite: true
$ cat conf/nginx-logstash.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /data/nginx/logs/qcba.access.log
- /data/nginx/logs/qcba.error.log
tail_files: true
input_type: log
fields.service: qcba-nginx
tags: ["qcba-nginx"]
output.logstash:
hosts: ["172.16.105.148:5044"]
$ cat /usr/local/filebeat-7.13.2-linux-x86_64/conf/nginx-logstash.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /data/nginx/logs/*.ai*.log
tail_files: true
input_type: log
fields.service: www-ai-nginx
tags: ["www-ai-nginx"]
output.logstash:
hosts: ["172.16.105.148:5044"]
paths 可以正则匹配如:- /data/nginx/logs/*.ai*.log
fields.service 定义一个名称,当该日志输出到logstash时,logstash可根据名称进行nginx日志的来源区分。
现不要启动filebeat,需要启动logstash服务
先看一下我这边需要收集的三个nginx日志格式
三台nginx服务器都处于阿里云SLB下,所以需要 http_x_forwarded_for ,http_x_forwarded_for 才是真实用户ip
第一个
log_format main
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
第二个 www-ai-nginx
log_format main
'$remote_addr - $remote_user [$time_local] $host "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for $hostname';
第三个 qcba--nginx
log_format main
'$remote_addr - $remote_user [$time_local] $host "$request" $request_body '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for $hostname';
三个日志多多少少有点区别,针对不同的日志在logstash的grok中需要匹配不同的过滤
编辑 logstash 配置文件
[root@ELK config]# cat nginx_log.conf
input {
beats {
port => "5044" # 定义接收日志的端口号
}
}
filter {
mutate {
rename => { "[host][name]" => "host" }
}
if [fields][service] == "web1-nginx" {
grok {
match => {
"message" => '%{IP:remote_addr} - (%{WORD:remote_user}|-) \[%{HTTPDATE:time_local}\] "%{WORD:method} %{NOTSPACE:request} HTTP/%{NUMBER}" %{NUMBER:status} %{NUMBER:body_bytes_sent} %{QS} %{QS:http_user_agent} %{IP:http_x_forwarded_for}'
}
remove_field => "message" # 删除message信息,使用上面的匹配
}
}
if [fields][service] == "www-ai-nginx" {
grok {
match => {
"message" => '%{IP:remote_addr} - (%{WORD:remote_user}|-) \[%{HTTPDATE:time_local}\] %{URIHOST:host_url} "%{WORD:method} %{NOTSPACE:request} HTTP/%{NUMBER}" %{NUMBER:status} %{NUMBER:body_bytes_sent} %{QS} %{QS:http_user_agent} %{DATA:http_x_forwarded_for} %{WORD:host_name}'
}
remove_field => "message"
}
}
if [fields][service] == "qcba-nginx" {
grok {
match => {
"message" => '%{IP:remote_addr} - (%{WORD:remote_user}|-) \[%{HTTPDATE:time_local}\] %{URIHOST:host_url} "%{WORD:method} %{NOTSPACE:request} HTTP/%{NUMBER}" - %{NUMBER:status} %{NUMBER:body_bytes_sent} %{QS} %{QS:http_user_agent} %{DATA:http_x_forwarded_for} %{WORD:host_name}'
}
remove_field => "message"
}
if [method] == "HEAD" { # 日志中如果包含阿里云健康检查,可以根据匹配后删除包含HEAD字段的日志
drop{}
}
}
# 根据ip分析地理位置
geoip {
source => "http_x_forwarded_for"
target => ["geoip"]
add_field => ["[geoip][coordinates]", "%{[geoip][longitude]}"]
add_field => ["[geoip][coordinates]", "%{[geoip][latitude]}"]
}
}
output {
stdout {
codec => rubydebug
}
if [fields][service] == "www-ai-nginx" {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "nginx_wwwai_log-%{+YYYY.MM.dd}"
template_overwrite => true
}
}
if [fields][service] == "qcba-nginx" {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "nginx_qcba_log-%{+YYYY.MM.dd}"
template_overwrite => true
}
}
if [fields][service] == "web1-nginx" {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "logstash-nginx_log-%{+YYYY.MM.dd}"
template_overwrite => true
}
}
}
启动logstash和各个nginx服务器上的filebeat
# logstash
cd /usr/local/logstash-7.13.2/
nohup bin/logstash -f config/nginx_log.conf --path.data=/data/logstash_work/ > /data/nohup_logs/logstash-nginx.log &
--path.data 指定工作目录,上面有讲过启动第二个logstash时必须指定一个工作目录
# filebeat
cd /usr/local/filebeat-7.13.2-linux-x86_64
./filebeat -e -c conf/nginx-logstash.yml -d publish &
kibana查看
先根据上面java的示例添加索引 'logstash-nginx_log-*'及另外两个索引
配置图形
演示一个:
点击右上角编辑,会出现创建可视化
地图演示
还是点击编辑,再点击下面图标
添加图层
选择nginx的索引就会自动出现下面的地理位置索引
完成了,地图可调很多样式,我没细研究,喜欢的可以琢磨一下。