基于Filebeat+Logstash+elasticsearch+kibana(8.4.1版本)搭建日志服务

1,077 阅读8分钟

一、背景及环境准备:

1、背景:

线上服务是SpringBoot服务,随着业务发展,产生的日志越来越多,排查越来越不方便。且如果跨服务调用,出现错误排查起来要花费大量时间,即使有trace_id也不是很方便。所以日志服务应运而生。

2、环境准备:

目前有项目服务器(project-server),就是跑着线上服务的服务器。日志服务器(log-server),用来搭建elk日志服务。在项目服务器上安装filebeat,用来采集日志数据,主要是两个日志文件:app-info.log和app-error.log文件。在日志服务器上安装logstash+elasticsearch+kibana,其中logstash负责过滤日志格式,elasticsearch负责存储和查找日志,kibana负责可视化操作日志。安装版本选择8.4.1版本。由于日志服务器上很干净,没有安装JDK,所以elasticsearch和logstash依赖的JDK直接使用它们自带的就可以。

3、整体架构图:

image.png

二、环境安装与配置:

1、下载安装包:

目前官网最新的稳定发布版本是8.4.1 elk.gif

2、上传安装包到服务器:

上传至/usr/local/elk并创建一个新用户senior,将安装包解压后重命名后将解压后的文件夹赋予senior用户,elk组件需以非root用户运行。如图:(由于本来就有一个非root的用户senior,且属于root组,所以不需要创建,也可以使用) image.png 解压重命名命令(以logstash为例):

tar -zxvf logstash-8.4.1-linux-x86_64.tar.gz ./
mv logstash-8.4.1-linux-x86_64 ./logstash-8.4.1

更改文件所有者命令:以logstash为例

sudo chown -R senior logstash-8.4.1

-R代表递归文件夹,表示该文件夹下内容都归指定用户所有。

3、调整配置:

需要先修改elasticsearch、再修改logstash、filebeat、kibana的配置,然后进行启动。为什么先搞elasticsearch,因为elasticsearch是核心,它正常启动,可以避免好多问题。

3.1、修改elasticsearch配置并启动:

进入elasticsearch安装目录,进入config文件夹下,编辑jvm.options和elasticsearch.yml两个文件,前者是因为elasticsearch依赖了JDK,所以需要配一些基本参数,看个人机器的配置进行调整,目前日志服务器作为测试版,它的配置是2核4G+40G磁盘。

3.1.1、修改虚拟内存:

具体就是不修改启动会报错虚拟内存不足的错,因为单个进程默认的虚拟内存就是65530KB,这对于es来说不够:

ERROR: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]**

修改:

sudo vim /etc/sysctl.conf

在配置文件末尾添加:

vm.max_map_count=262144

保存退出后刷新:

sudo sysctl -p

3.1.2、编辑jvm.options:

两个参数,将jvm需要的最大内存和最小内存设置为一样大小,可以让jvm一开始就申请足够的内存,防止因为内存不足而不停申请内存,影响速度。

-Xms1g
-Xmx1g

3.1.3、编辑elasticsearch.yml:

# 集群名称(单节点也要配)
cluster.name: sn-pub-elasticsearch
# 节点名称(单节点也要配)
node.name: sn-node-1
# 允许外部访问
network.host: 0.0.0.0
# es的端口
http.port: 9200
# 集群主节点
cluster.initial_master_nodes: ["sn-node-1"]
# 配置不开启安全认证,不开启账号密码登录
xpack.security.enabled: false

3.1.4、启动:

后台启动: 进入到elasticsearch的bin目录下

./elasticsearch -d

查看进程

ps -ef | grep elasticsearch

image.png 至此,一个es其实已经启动了。想要需要登录才能查看索引的es,那么接着配置。

编辑elasticsearch.yml添加用户认证,也就是账号密码登录

xpack.security.enabled: true
xpack.security.http.ssl:
  enabled: false
xpack.security.transport.ssl:
  enabled: true
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12

使用kill -9 pid杀死elasticsearch进程后再次后台启动,启动完成后,修改密码(不需要用户认证的可跳过),修改elastic用户和kibana的密码,默认elastic是管理员权限。 使用如下命令按提示操作即可(以elastic用户为例,对kibana用户操作也是一样的):

./elasticsearch-reset-password -u elastic -i

上面的是单个配置 下面是挨个为elasticsearch拥有的用户配置密码:

在elasticsearch的bin目录下执行

./elasticsearch-setup-passwords interactive

遇到如图提示:输入y image.png 然后按照提示输入自己想要的密码即可,密码会有二次确认。 image.png

3.2、修改logstash的配置并启动:

进入logstash的安装目录,进入config文件夹下,创建conf.d文件夹,进入conf.d文件夹,创建文件logstash.conf。

3.2.1、编辑logstash.conf文件

# 采集:
input {
  beats {
    host => "0.0.0.0"
    # logstash监听的端口,filebeat会将数据从此端口发送进来
    port => 5044
  }
}
# 过滤:
filter {
  # filebeat采集日志时会打标签,
  if "sn-nb-test-api-info" in [tags]{
  # 过滤日志信息,从日志中解析出需要的字段
    grok {
      match => {
        "message" => "\[%{TIMESTAMP_ISO8601:time}\]\[%{DATA:trace_id}\]\[%{DATA:thread_name}\]\[%{LOGLEVEL:level}\]\[%{JAVACLASS:class}\]\[%{INT:line_no}\]%{GREEDYDATA:msg}"
      }
    }
    # 处理日志生成的时间,日志产生的时间是北京时间,减去8小时,先处理成utc时间
    date {
      match => ["time","yyyy-MM-dd HH:mm:ss.SSS"]
      target => "@timestamp"
      timezone => "Etc/GMT-8"
    }
    # es会搜集许多组件的信息,这里将它们删除掉,否则到时候发送kibana太多多余的字段
    mutate {
      remove_field => ["@version","message","host","agent","ecs","cloud","input","log","event","time"]
    }
  }

  if "sn-nb-test-api-error" in [tags]{
    grok {
      match => {
        "message" => "\[%{TIMESTAMP_ISO8601:time}\]\[%{DATA:trace_id}\]\[%{DATA:thread_name}\]\[%{LOGLEVEL:level}\]\[%{JAVACLASS:class}\]\[%{INT:line_no}\]%{GREEDYDATA:msg}"
      }
    }
    date {
      match => ["time","yyyy-MM-dd HH:mm:ss.SSS"]
      target => "@timestamp"
      timezone => "Etc/GMT-8"
    }
    mutate {
      remove_field => ["@version","message","host","agent","ecs","cloud","input","log","event","time"]
    }
  }
}
# 输出:
output {
  if "sn-nb-test-api-info" in [tags]{
     elasticsearch {
       hosts => ["x.x.x.x:9200"]
       # elasticsearch按索引文档进行数据存储,所以这里将每天的日志建立索引存储
       index => "sn-nb-test-api-info-%{+yyyy-MM-dd}"
       user => "elastic"
       password => "******"
     }
  }
  if "sn-nb-test-api-error" in [tags]{
     elasticsearch {
       hosts => ["x.x.x.x:9200"]
       index => "sn-nb-test-api-error-%{+yyyy-MM-dd}"
       user => "elastic"
       password => "******"
     }
  }
}

将输出部分的x.x.x.x替换成elasticsearch所在服务器的ip即可,密码就是自己设置的密码。elasticsearch没有设置用户认证也就不用user和password了。 grok为什么要这么处理,这和filebeat采集到的日志格式有关,springboot服务产生的日志格式是这样的:

[2022-09-13 00:01:04.504][][Thread-41][INFO][com.senior.cloud.system.schedule.VehicleEatSchedule][41]每天1:01生成作业效率报表数据:timeStr:20220912

每一对[ ]之间都是固定的日志格式,是springboot服务里logback.xml里设置的。 后面安装了kibana,可以通过kibana里的dev Tools对日志进行grok调试,效果如图:

image.png

3.2.2、编辑config目录下jvm.options:

logstash运行也是依赖JVM,不多赘述,目前配置如下:

-Xms512m
-Xmx512m

3.2.3、编辑config目录下的logstash.yml:

在行末添加

path.config: /usr/local/elk/logstash-8.4.1/config/conf.d
path.logs: /usr/local/elk/logstash-8.4.1/logs

3.2.4、启动:

进入到logstash安装的bin目录下,执行(后台运行):

nohup ./logstash > ../logs/logstash.log &

3.3、修改kibana配置并启动:

使用命令cd /opt进入opt目录下,使用命令sudo mkdir kibana创建kibana目录,然后使用 sudo chown -R senior kibana/更改kibana目录所有者为senior

进入kibana安装目录,进入config目录下

3.3.1、编辑kibana.yml:

server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://x.x.x.x:9200"]
elasticsearch.username: "kibana"
elasticsearch.password: "*****"
i18n.locale: "zh-CN"
logging.appenders.default:
  type: file
  fileName: /opt/kibana/logs/kibana.log
  layout:
    type: json

其它配置注释掉,是关于安全认证的。同理x.x.x.x替换成elasticsearch所在的服务器ip,密码就是自己设置的那个。

3.3.2、启动:

nohup ./kibana &

由于kibana是node.js编写的,所以查看kibana进程号需要这样:

sudo netstat -tunlp|grep 5601

查看启动日志:

tail -f /opt/kibana/logs/kibana.log 

3.4、修改filebeat配置并启动:

filebeat安装在需要采集日志的服务器上,上传解压不再赘述,这个使用root账号测试也是可以启动的。

3.4.1、编辑filebeat.yml:

# ============================== Filebeat inputs ===============================

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

# filestream is an input for collecting log messages from files.
# 新版推荐使用filestream代理log
- type: filestream

  # Unique ID among all inputs, an ID is required.
  # id是必须的,名字随意
  id: sn-api-info-test
  # 这块采集的是info信息,所以tag标记就取名叫这个
  tags: ["sn-nb-test-api-info"]

  # Change to true to enable this input configuration.
  enabled: true
  #encoding
  encoding: utf-8

  # Paths that should be crawled and fetched. Glob based paths.
  # linux上服务产生的日志的绝对路径
  paths:
    - /home/senior/app/logs/app-info.log
    #- c:\programdata\elasticsearch\logs\*
  #multiline
  # 配置多行解析,为了将error日志里的堆栈信息放在一行显示,否则会很恶心
  # 表示将匹配到不以[开头的行追加到以[开头的行之后构成一行
  parsers:
  - multiline:
      type: pattern
      pattern: '^\['
      negate: true
      match: after
- type: filestream

  # Unique ID among all inputs, an ID is required.
  id: sn-api-error-test
  tags: ["sn-nb-test-api-error"]

  # Change to true to enable this input configuration.
  enabled: true
  #encoding
  encoding: utf-8

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /home/senior/app/logs/app-error.log
    #- c:\programdata\elasticsearch\logs\*
  #multiline
  parsers:
  - multiline:
      type: pattern
      pattern: '^\['
      negate: true
      match: after
# ============================== Filebeat modules ==============================

filebeat.config.modules:
  # Glob pattern for configuration loading
  path: ${path.config}/modules.d/*.yml

  # Set to true to enable config reloading
  reload.enabled: false

  # Period on which files under path should be checked for changes
  #reload.period: 10s

# ======================= Elasticsearch template setting =======================

setup.template.settings:
  index.number_of_shards: 1
  #index.codec: best_compression
  #_source.enabled: false

output.logstash:
  # The Logstash hosts
  hosts: ["x.x.x.x:5044"]
# ================================= Processors =================================
processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~

3.4.2、启动:

nohup ./filebeat -e -c filebeat.yml > filebeat.log &

3.4.3、访问界面:

x.x.x.x:5601。访问kibana,有密码需要使用elastic账号密码,然后对时间进行设置: image.png

4、最终效果:

4.1、需要登录,使用elastic账号密码

image.png 否则使用kibana账号会这样: image.png

4.2、登录成功,配置好discover中的data view就可以了

result.gif

4.3、优化kibana显示

如果不想每次都得在data view选择field作为右侧展示的列,可以做一个默认设置,在kibana设置里配置: image.png 以后打开默认就会变成这样: image.png