大数据日志监控filebeat+kafka+elk+docker部署

1 篇文章 0 订阅
1 篇文章 0 订阅

部署架构

在这里插入图片描述

日志格式说明

系统日志
{"file":"entry.go:224","level":"info","msg":"set sensive words: [呵呵呵呵 测试一下 你好]","time":"2020-04-24T11:20:32+08:00"}
访问日志,包含登录日志(请求类型值为2则为登录日志,登录日志才有额外信息)
# IP - 用户名 [时间] "方法 路径 协议" 响应状态码 内容大小 "refere" "User-Agent" 请求次数 "路由名称" "后端服务地址" 花费时间ms "后端服务名称" "参数" 请求类型 |||请求内容||| |||响应内容||| |||额外信息|||  

#例子
127.0.0.1 - admin [07/May/2020:08:52:52 +0000] "GET /login HTTP/1.1" 200 711 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.14 Safari/537.36 Edg/83.0.478.13" 18 "old@internal" "-" 57ms "-" "username=admin&password=123456" 2 |||-||| |||"{\"meta\":{\"success\":true,\"statusCode\":200,\"message\":\"\"},\"data\":{\"userId\":\"admin\",\"userName\":\"超级管理员\",\"userNickname\":\"联奕大学管理员\",\"email\":\"123456@qq.com\",\"orgId\":\"1\",\"departmentId\":\"000000\",\"departmentName\":\"院领导\",\"userType\":\"teacher\",\"sex\":\"1\",\"skin\":\"blue\",\"startTimestamp\":\"2020-05-07T16:52:52.9985147+08:00\",\"lastAccessTime\":\"2020-05-07T16:52:52.9985147+08:00\",\"authorization\":{},\"menus\":{},\"apps\":{\"ly-gtc\":\"ly-gtc\"},\"accessToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODg4NDg3NzIsImlhdCI6MTU4ODg0MTU3MiwidXNlcm5hbWUiOiJhZG1pbiIsImFjY2Vzc1Rva2VuIjoiIn0.z1ZAQpcivtLD81vKy1Nvi_7NRw25wMLDPhv-2glMb5k\",\"refreshToken\":\"dca4655e-3ec2-4c91-9864-f440748ff934\",\"expiresIn\":7200}}\n"||| |||{"username":"超级管理员","usertype":"teacher","login_access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODg4NDg3NzIsImlhdCI6MTU4ODg0MTU3MiwidXNlcm5hbWUiOiJhZG1pbiIsImFjY2Vzc1Rva2VuIjoiIn0.z1ZAQpcivtLD81vKy1Nvi_7NRw25wMLDPhv-2glMb5k"}|||

安全日志
{"clientAddr":"127.0.0.1:24377","clientHost":"127.0.0.1","clientPort":"24377","clientUsername":"-","downstreamContentSize":17,"downstreamStatus":429,"duration":4982900,"originContentSize":17,"originDuration":4982900,"originStatus":429,"overhead":0,"requestAddr":"127.0.0.1:81","requestContentSize":0,"requestCount":16,"requestHost":"127.0.0.1","requestMethod":"GET","requestPath":"/hello/a","requestPort":"81","requestProtocol":"HTTP/1.1","requestScheme":"http","retryAttempts":0,"routerName":"hello@mongodb","startLocal":"2020-05-06T15:03:04.403529+08:00","startUTC":"2020-05-06T07:03:04.403529Z","entryPointName":"web","level":"info","msg":"","request_Body":"\"\"","request_Params":"","request_User_Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.14 Safari/537.36 Edg/83.0.478.13","response_Body":"\"Too Many Requests\"","safety_Info":"127.0.0.1 访问/hello/a 限制为每秒2","safety_Type":"ratelimit","time":"2020-05-06T15:03:11+08:00"}

docker日志

安全日志:logType=1

登录日志:logType=2

操作日志:logType=3

普通日志:除了上面三种情况都是

类型 时间 日志等级 用户名 请求地址和端口 请求参数 请求方法 请求次数 响应状态码 响应信息

#示例
{"logType":1,"time":"2020-05-14T15:03:04.403529+08:00","level":"info","username":"-","requestAddr":"127.0.0.1:81","requestParam":"id=9","requestMethod":"GET","requestCount":16,"status":200,"msg":"Too Many Requests"}
{"logType":2,"time":"2020-05-14T15:03:04.403529+08:00","level":"warn","username":"-","requestAddr":"127.0.0.2:81","requestParam":"id=9","requestMethod":"GET","requestCount":16,"status":200,"msg":"Too Many Requests"}
{"logType":3,"time":"2020-05-14T15:03:04.403529+08:00","level":"error","username":"-","requestAddr":"127.0.0.3:81","requestParam":"id=9","requestMethod":"GET","requestCount":16,"status":200,"msg":"Too Many Requests"}
{"logType":4,"time": "2020-05-14T15:03:04.403529+08:00" "level":"error","username":"-","requestAddr":"127.0.0.3:81","requestParam":"id=9","requestMethod":"GET","requestCount":16,"status":200,"msg":"Too Many Requests"

环境准备

系统环境

Centos7.0及以上

基础软件环境

安装Docker 19及以上版本

软件环境

docker pull filebeat:7.6.1

docker pull wurstmeister/zookeeper:latest
docker pull wurstmeister/kafka:latest

docker pull logstash:7.6.1

docker pull elasticsearch:7.6.1

#可选安装,目的用来查看日志
docker pull kibana:7.6.1

部署过程

Filebeat

opt/elk/config/目录下新建filebeat.yml

filebeat.yml
# 日志输入配置
#=========================== Filebeat inputs =============================

filebeat.inputs:

- type: log
  # Change to true to enable this input configuration.
  enabled: true
  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    #- /var/log/*.log
    - /home/logs/nginx/*.log
  fields:
    log_topic: nginx_log
    #- c:\programdata\elasticsearch\logs\*

- type: log
  enabled: true
  paths:
    - /opt/elk/logs/*.log
  fields:
    log_topic: traefik_log

- type: log
  enabled: true
  paths:
    - /opt/elk/securityLogs/*.log
  fields:
    log_topic: security_log

#日志输出配置(采用kafka缓冲日志数据)
output.kafka:
  enabled: true
  hosts: ["192.168.30.23:9092"]
  topic: 'filebeat'
input输入配置说明
  • type 监控类型

  • enabled 是否开启,默认为false,需要设置为true

  • paths 指定要监控的日志,可以指定具体得文件或者目录

  • fields 向输出的每一条日志添加额外的信息

output输出配置说明
  • enabled 是否开启
  • hosts kafka的ip和port
  • topic 推送到kafka新建的topic
启动

重点:需要监控的日志目录也需要挂载进容器,这样filebeat才能读取到

docker run -d --name=filebeat \
--user=root \
-v /opt/elk/config/filebeat.yml:/usr/share/filebeat/filebeat.yml \
-v /home/logs/nginx/:/home/logs/nginx/ \
-v /opt/elk/logs/:/opt/elk/logs/ \
-v /opt/elk/securityLogs/:/opt/elk/securityLogs/ \
elastic/filebeat:7.6.1 

Kafka(先启动zookeeper)

启动
#zookeeper port:2181
docker run -d --name zookeeper -p 2181:2181 --log-opt max-size=100m wurstmeister/zookeeper:latest

#kafka	port:9092
docker run -d --name kafka --publish 9092:9092 --log-opt max-size=100m \
--link zookeeper \
--env KAFKA_ZOOKEEPER_CONNECT=192.168.30.23:2181 \
--env KAFKA_ADVERTISED_HOST_NAME=192.168.30.23 \
--env KAFKA_ADVERTISED_PORT=9092 \
--volume /etc/localtime:/etc/localtime \
wurstmeister/kafka:latest
为了防止kafka日志文件过大,我们需要设置合适的日志保存策略

server.properties

测试kafak是否安装成功
#进入kafka容器
docker exec -it kafka /bin/bash

#之后进入bin目录
cd /opt/kafka_2.12-2.4.0/bin

#创建test这个topic
./kafka-topics.sh --create --zookeeper 192.168.30.23:2181 --replication-factor 1 --partitions 1 --topic test

#之后创建生产者,运行命令之后,随便输点啥
./kafka-console-producer.sh --broker-list 192.168.30.23:9092 --topic test

#重开一个窗口,新建消费者,运行命令之后,就可以看到生产者发过来的消息了
./kafka-console-consumer.sh --bootstrap-server 192.168.30.23:9092 --topic test --from-beginning

2、使用 kafka-run-class 指令,获取topic的最小offset和最大offset

#查看各个分区的最小offset(这个意思就是,这个offset之前的消息已经被清除了,现在consumer是从这个offset之后开始消费):
./kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092 --topic filebeat --time -2
#查看各个分区的最大offset(这个意思就是,producer下一次写入信息时的offset):
./kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092 --topic filebeat --time -1

3、获取最近N条数据,offset = MaxOffset - N

比如想要获取最近10条数据,根据第二个步骤获取到的MaxOffset为52884,则这条命令最后的--offset参数为52884 - 10 = 52874

./kafka-console-consumer.sh --bootstrap-server 192.168.35.14:9092 --topic filebeat \
	--property print.key=true --partition 0 --offset 52874

elasticsearch

配置
  • 需要设置系统内核参数,否则会因为内存不足无法启动

    sysctl -w vm.max_map_count=262144

    使之立即生效

    sysctl -p

创建/opt/elk/elasticsearch.yml配置文件,内容如下:

cluster.name: "elasticsearch"
network.host: 0.0.0.0
#快照仓库地址
path.repo: /opt/elk/es/snapshot
启动
docker run -d --name es -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" -e "cluster.name=elasticsearch" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-v /opt/elk/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /opt/elk/es/snapshot:/opt/elk/es/snapshot \
--log-opt max-size=100m -d elasticsearch:7.6.1

创建es快照仓库文件夹夹并改变权限:

mkdir -p /opt/elk/es/snapshot
chmod 777 snapshot
#进入容器
docker exec -it es /bin/bash

#安装中文分词插件
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.6.1/elasticsearch-analysis-ik-7.6.1.zip
#重启se
docker restart es
验证es是否安装成功(curl ip:9200)
[root@localhost ~]# curl localhost:9200
{
  "name" : "a33593fc9be0",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "LyoRC3pKRHmJnigMyr8eeQ",
  "version" : {
    "number" : "7.6.1",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "aa751e09be0a5072e8570670309b1f12348f023b",
    "build_date" : "2020-02-29T00:15:25.529771Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

logstash

在/opt/elk/logstash目录下新建logstash.conf文件

input {
  kafka {
    bootstrap_servers => "192.168.35.14:9092"
    topics => ["filebeat"]
    group_id => "test-consumer-group"
    codec => "json"
    consumer_threads => 1
    decorate_events => true
  }
}

filter {
  if [fields][log_topic] == "nginx_log"{
    json {
      source => "message"
      remove_field => ["message"]
    }

    date {
      match => ["time", "yyyy-MM-dd HH:mm:ss ZZ", "ISO8601"]
      target => "@timestamp"
    }
  }

  if [fields][log_topic] == "security_log"{
    json {
      source => "message"
      remove_field => ["message"]
    }

    date {
      match => ["time", "yyyy-MM-dd HH:mm:ss ZZ", "ISO8601"]
      target => "@timestamp"
    }
  }

  if [fields][log_topic] == "traefik_log"{  
    
    dissect{
      mapping => {
	"message" => '%{source_address} %{traefik_access_user_identifier} %{user_name} [%{timestamp}] "%{http_request_method} %{url_original} HTTP/%{http_version}" %{http_response_status_code} %{traefik_access_message}'
      }
    }

    grok {
	match => { "traefik_access_message" =>  '(?:%{NUMBER:http_response_body_bytes:long}|-)( (?:"%{DATA:http_request_referrer}"|-)?( (?:"%{DATA:user_agent_original}"|-)?)?( (?:%{NUMBER:traefik_access_request_count:long}|-)?)?( (?:"%{DATA:traefik_access_frontend_name}"|-)?)?( "%{DATA:traefik_access_backend_url}")?( %{NUMBER:temp_duration:long}ms)?)?( (?:"%{DATA:traefik_service_name}"|-)?)?( (?:"%{DATA:appid}"|-)?)?( (?:"%{DATA:traefik_service_paramter}"|-)?)?( %{NUMBER:request_type:long})?( (?:\|\|\|%{DATA:request_body}\|\|\||-)?)?( (?:\|\|\|%{DATA:response_body}\|\|\||-)?)?( (?:\|\|\|%{DATA:extra_info}\|\|\||-)?)?' }
	remove_field => [ "message", "traefik_access_message" ]
    }

    if [request_type] == "2" {
    	json {
      		source => "extra_info"
      		remove_field => ["extra_info"]
    	}	
    } 
    if [request_type] == "3" {
    	json {
      		source => "extra_info"
      		remove_field => ["extra_info"]
    	}	
    } 

    date {
	match => [ "timestamp" , "dd/MMM/yyyy:H:m:s Z" ]
	#remove_field => [ "traefik_access_time" ]
	target => "@timestamp"
    }

    mutate {
      convert => {
        "temp_duration" => "integer" 
        "traefik_access_request_count" => "integer"
        "http_response_status_code" => "integer"
      }
    }

    useragent {
      source=>"user_agent_original"
    }
    grok {
      match => { "source_address" =>  '^(%{IP:source_ip}|%{HOSTNAME:source_domain})$' }
    }

    geoip {
      source=>"source_ip"
      target=>"source_geo"
    }
 
  }
  
}


output {
  stdout{ codec=>rubydebug}
  
  if [fields][log_topic] == "traefik_log"{
	if [request_type] == "2" {
		elasticsearch {
         		hosts => ["192.168.35.14:9200"]
         		index => "login_log-%{+YYYY.MM.dd}"
      		}
	} else if [request_type] == "3" {
		elasticsearch {
         		hosts => ["192.168.35.14:9200"]
         		index => "logout_log-%{+YYYY.MM.dd}"
      		}
	} else {
		elasticsearch {
                        hosts => ["192.168.35.14:9200"]
                        index => "traefik_log-%{+YYYY.MM.dd}"
                }
	}
  }

  if [fields][log_topic] == "nginx_log"{
      	elasticsearch {
        	hosts => ["192.168.35.14:9200"]
         	index => "nginx_log-%{+YYYY.MM.dd}"
      	}
  }

  if [fields][log_topic] == "security_log"{
      	elasticsearch {
         	hosts => ["192.168.35.14:9200"]
         	index => "security_log-%{+YYYY.MM.dd}"
      	}
  }
}

日志说明

nginx_log:网关系统日志

syslog: 服务器系统日志

security_log 安全日志

k8s_container_log:容器日志(包括以下三种日志,根据日志中logType可分类)

  • 安全日志:logType=1
  • 登录日志:logType=2
  • 操作日志:logType=3
  • 容器日志:除了以上三种

traefik_log 访问日志(包括以下日志,根据request_type分类)

  • 登录日志:request_type=2
  • 登出日志:request_type=3
  • 访问日志:除了以上都是
解析语法说明:
#将message直接解析,应为message是json格式,解析起来跟简单
json {
	source => "message"
	#解析之后移除message字段
	remove_field => ["message"]
}

#logstash自动生成的timestamp,不是日志的生成时间,需要将日志里的时间提取出来,替换timestamp
date {
	match => ["time", "yyyy-MM-dd HH:mm:ss ZZ", "ISO8601"]
	target => "@timestamp"
}

#重命名、添加字段、移除字段
mutate {
        rename => {
			"timestamp"=>"time" 
		}
		add_field => {
			#这里message是个数组,我们把它转化成字段
			"msg" => "%{[message][0]}" 
		}
		remove_field => ["message"]
}

在/opt/elk/目录下新建logstash.yml,将修改es所在服务器的ip

http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://192.168.30.23:9200" ]
启动
docker run -d --name=logstash -p 5044:5044 -p 9600:9600 \
-v /opt/elk/logstash.yml:/usr/share/logstash/config/logstash.yml \
-v /opt/elk/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
-v /opt/elk/logstash-container.conf:/usr/share/logstash/pipeline/logstash-container.conf \
--log-opt max-size=100m \
logstash:7.6.1
查看logstash启动日志(日志数据推送过来的时候,可以看到具体日志数据)
docker logs -f logstash

kibana(可选启动,为了更直观的查看测试日志数据,建议启动)

启动
docker run -d -p 5601:5601 --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.30.23:9200 --log-opt max-size=100m kibana:7.6.1

效果

上传日志文件测试,在浏览器可以查看elasticsearch中各个索引库的数据,索引库的生成在logstash.conf配置文件output模块,输出到es,会生成对应的索引库

一:在浏览器中输入ip:port/index/_search

ip:es的ip

port:一般默认为9200

index:es的索引库

如图
在这里插入图片描述

二:使用kibana查看效果

输入ip:5601
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
ELK(Elasticsearch、Logstash、Kibana)是一个开源的日志管理和分析平台,能够帮助企业收集、存储、搜索、分析和可视化各种类型的日志数据。而Kafka是一个高吞吐量的分布式消息队列系统,可以用来收集和传输大规模的日志数据。Reyslog是一个开源的日志收集器,可以帮助企业从各种不同的数据源中收集日志数据。Filebeat是一个轻量级的日志收集工具,可以帮助企业从各种不同的文件中收集日志数据。 以下是ELK+kafka+reyslog+filebeat企业级部署的步骤: 1. 安装和配置Elasticsearch、Logstash和Kibana,并确保它们能够正常运行。可以使用docker-compose等工具来简化部署过程。 2. 安装和配置Kafka,并创建一个主题(topic)用于存储日志数据。 3. 安装和配置Reyslog,并将其配置为从各种不同的数据源中收集日志数据,并将其发送到Kafka主题(topic)中。 4. 安装和配置Filebeat,并将其配置为从各种不同的文件中收集日志数据,并将其发送到Kafka主题(topic)中。 5. 在Kibana中创建一个索引(index),并定义一个包含所有必需字段的映射(mapping)。然后,使用Logstash来将从Kafka主题(topic)中接收到的日志数据转换为适合索引(index)的格式,并将其存储在Elasticsearch中。 6. 在Kibana中创建一个仪表板(dashboard),并使用其可视化功能来呈现和分析日志数据。可以使用各种不同的可视化插件来创建自定义可视化效果。 7. 部署整个系统,并定期监控其性能和可用性,以确保其正常运行。 总之,ELK+kafka+reyslog+filebeat企业级部署需要进行一系列复杂的配置和设置,需要具备一定的技术知识和实践经验。建议企业可以考虑使用专业的日志管理和分析平台,如Splunk等,以简化部署和管理过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木一番

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值