ELK + RabbitMQ & file + Spring boot

满江红·怒发冲冠

  怒发冲冠,凭阑处、潇潇雨歇。
  抬望眼,仰天长啸,壮怀激烈。
  三十功名尘与土,八千里路云和月。莫等闲,白了少年头,空悲切。
  靖康耻,犹未雪;臣子恨,何时灭?
  驾长车,踏破贺兰山缺。
  壮志饥餐胡虏肉,笑谈渴饮匈奴血。
  待从头,收拾旧山河,朝天阙。
复制代码

背景

最近项目需要,使用 docker 部署了 ELK,因为我们日志产生在客户端,考虑安全问题,在后端提供了两个接口,一个实时的日志信息推送,还有一个提供日志文件上传,以此作为 logstash 的输入

原本以为很简单的问题,由于本人是前端临时过来打工的,对 docker 、java、linux、ELK 各种不熟悉,折腾了好久,现记录下,文中有不对的地方,请不吝赐教

业务流程

客户端产生日志,有两种情况推送给后端服务器

  • 在线状态,直接通过接口推送
  • 离线状态,会将日志本地持久化,等待下次联网,通过上传文件的方式推送给后端

服务器端提供以下两个接口

  • 实时日志推送接口:1. 身份认证;2. 数据处理;3. 推送给消息队列
  • 上传日志文件接口:1. 接收文件;2. 保存文件

ELK 负责数据采集,数据来源

  • RabbitMQ 队列中的数据
  • 上传的日志文件

以上是大概的流程

ELK 安装

安装主要是参考这片文章 使用 Docker 搭建 ELK 环境 ,具体安装按照这个来,很方便。

配置问题

我大部分的时间都是在这里浪费的,尤其是 logstash 的 input 配置

这里说一下项目里的配置文件

docker-compose.yml 是 ELK 三件套的配置文件,后续因为我的后端也是容器化部署的,上传的日志文件需要能让 logstash 拿到,所以我添加了一个 volume

  - type: bind
    source: ./logstash/logs   ### 这个是相对于该配置文件的相对地址,后续我会把这个目录和后端服务上传文件的文件夹对应起来
    target: /usr/share/logstash/logs ### 这个是 logstash 容器里的地址
复制代码

然后是 logstash pipeline 的配置

### 文件的 input, path 对应的是 logstash 容器里的绝对路径,这里要将这个地址和宿主机做映射,也就是后端上传文件映射的那个地址
​
input {
  file {
    mode => "read"
    start_position => "beginning"
    path => ["/usr/share/logstash/logs/logs/**"]
    codec => json
  }
}
​
### rabbitmq 的 input
input {
  rabbitmq {
    host => "172.20.10.2"
    port => 5672
    user => "admin"
    password => "admin"
    queue => "log.handler"
    exchange => "scheduler-logs-exchange"
    exchange_type => "direct"
    key => "log.handler"
    heartbeat => 30
    durable => true
    codec => json
  }
}
​
​
## Add your filters / logstash plugins configuration here
​
output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    user => "your name"
    password => "your password"
    index => "your index"
  }
}
​
复制代码

说几个遇到的问题:

  1. rabbitmq 的生产者是后端 java 代码,Java 在推送信息给 rabbitmq 之前,我在代码里面初始化了 exchange 和 queue ,导致 logstash 运行报错,这里正确的做法是,java 代码不用在初始化了,交给 logstash ,它会自动来创建的。这过程中还因为我修改了 rabbitmq 的 exchange_type,导致类似的问题发生。
  1. 最早的时候 pipeline 我配置了两个文件,我的想法是一个给 rabbitmq 使用,一个给文件使用;配置也生效了,可是每次我向 rabbitmq 推送一条数据,logstash 都会产生两笔数据,最后找到原因是两个配置文件,有两个 output,它的机制应该是只要有 input 满足了,output 会执行两次,so 我将配置又整合在一起了;此外还遇到一个奇怪的问题,rabbitmq 和 file 的 input 的位置问题,我测试发现,file 必须在 rabbitmq 上面,不然 file 就会无效,不知道啥原因。
  2. 部署问题,我在本地搭建的环境执行没有问题,可是到服务器上,文件的读取总是报错,错误提示是 file 里面某个输入字段不合法;后来和本地比对,我发现,logstash 正确读取 日志文件之后,会将文件自动删除(因为我配置的 start_position => "beginning"),但是服务器上没有,后来我发现是 logstash 容器里面对操作文件的权限不对,没有删除权限。我只能去容器里面把权限给改了。
  3. 配置文件修改后,记得重启服务,重启服务,重启服务。。。

最后,虽然现在看上去能够正确运行了,但我感觉有几个问题,我的方式应该是不对的

  • logstash 里面修改文件的权限的
  • java 服务上传文件目录和 logstash 读取日志目录链接方式

希望大家给出一些帮助,谢谢

猜你喜欢

转载自juejin.im/post/7039505681652645924
今日推荐