1. 前言在日常运维工作中，对于系统和业务日志的处理尤为重要。尤其是分布式架构，每个服务都会有很多节点，如果要手工一个一个的去取日志，运维怕是要累死。 简单介绍：ELK 是 elasticsearch + logstash + kibana 三款开源软件的简称。elasticsearch：是个开源的分布式搜索引擎，特点是：分布式、配置简单、自动发现、索引自动分片、索引副本机制、restful风格接口，多数据源，自动搜索负载等logstash：可以对日志进行收集、滤过、并将其存储在 elasticsearch中kibana：可以为 elasticsearch提供友好的用户交互界面，用户可以通过 kibana来分析、搜索甚至绘图来分析数据。这里介绍下目前使用比较多的架构：ELK + filebeatFilebeat 是一个轻量级开源日志文件数据收集器，可以将它安装到需要收集的节点上，它会将日志输送到 logstash 或 elasticsearch有了 ELK 就可以将分布到多台的日志统一规划起来。网络上有很多关于 ELK 的部署方案，参考了很多发现要不就是老版本的，要不就是不太完善，因此自己做下记录。注意：在安装 ELK 的时候，这三个软件的版本必须保持支持，否则出现各种bug2. ELK搭建过程实验拓扑图：实验环境主机服务介绍：本次实验是收集 nginx 日志，并存储在 elasticsearch中。将 elasticsearch 和 kibana 安装在同一主机上可以避免不必要的网络IO操作，直接本机交互。2.1 Elasticsearch 的安装过程（1）初始化工作selinux、firewall 关闭时间同步主机名修改修改打开文件最大数时间同步：[root@192.168.118.14 ~]``#ntpdate tiger.sina.com.cn修改主机名：[root@192.168.118.14 ~]``#hostnamectl set-hostname node1``修改完主机名别忘记在 ``/etc/hosts` `中申明``192.168.118.14 node1修改文件打开最大数：[root@192.168.118.14 ~]``#vim /etc/security/limits.conf``* soft nproc 655350``* hard nproc 655350``* soft nofile 655350``* hard nofile 655350` `[root@192.168.118.14 ~]``#ulimit -SHn 655350（2）配置 java 环境[root@192.168.118.14 ``/usr/local/src``]``#tar xf jdk-8u77-linux-x64.tar.gz -C /usr/local/` `在 ``/etc/profile` `文件中追加``JAVA_HOME=``/usr/local/jdk1``.8.0_77``JAVA_BIN=$JAVA_HOME``/bin``PATH=$PATH:$JAVA_BIN``CLASSPATH=$JAVA_HOME``/lib/dt``.jar:$JAVA_HOME``/lib/tools``.jar``export` `JAVA_HOME JAVA_BIN PATH CLASSPATH` `[root@192.168.118.14 ``/usr/local/src``]``#source /etc/profile``[root@192.168.118.14 ``/usr/local/src``]``#ln -vs /usr/local/jdk1.8.0_77/bin/java /usr/bin/``[root@192.168.118.14 ``/usr/local/src``]``#java -version``java version ``"1.8.0_77"``Java(TM) SE Runtime Environment (build 1.8.0_77-b03)``Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)（3）安装 elasticsearch下载地址：https://www.elastic.co/cn/downloads/past-releases#elasticsearch这里下载的是 6.8 的 rpm 包直接安装：[root@192.168.118.14 ~``/ELK``]``#yum localinstall elasticsearch-6.8.2.rpm``修改配置文件如下：``[root@192.168.118.14 ~``/ELK``]``#egrep ^[a-z] /etc/elasticsearch/elasticsearch.yml``cluster.name: super-cluster``node.name: node1``path.data: ``/var/lib/elasticsearch``path.logs: ``/var/log/elasticsearch``bootstrap.memory_lock: ``true``network.host: 0.0.0.0``http.port: 9200``discovery.zen.``ping``.unicast.hosts: [``"192.168.118.14"``]``http.cors.enabled: ``true``http.cors.allow-origin: ``"*"启动[root@192.168.118.14 ~``/ELK``]``#systemctl enable elasticsearch ; systemctl start elasticsearch首次启动可能会启动失败，查看日志：[root@192.168.118.14 ~``/ELK``]``#tail /var/log/elasticsearch/super-cluster.log``…``[1]: memory locking requested ``for` `elasticsearch process but memory is not locked``…如上报错，需要修改启动脚本：[root@192.168.118.14 ~``/ELK``]``#vim /lib/systemd/system/elasticsearch.service``在 [Service] 配置段添加：``…``LimitMEMLOCK=infinity``…` `[root@192.168.118.14 ~``/ELK``]``#systemctl daemon-reload``[root@192.168.118.14 ~``/ELK``]``#systemctl start elasticsearch查看端口，如果 9200 和 9300 监听，则说明 elasticsearch启动成功。验证：[root@192.168.118.14 ~``/ELK``]``#curl http://localhost:9200/``{`` ``"name"` `: ``"node1"``,`` ``"cluster_name"` `: ``"super-cluster"``,`` ``"cluster_uuid"` `: ``"1FD-KmYMTVCzWVPI9vn8zw"``,`` ``"version"` `: {`` ``"number"` `: ``"6.8.2"``,`` ``"build_flavor"` `: ``"default"``,`` ``"build_type"` `: ``"rpm"``,`` ``"build_hash"` `: ``"b506955"``,`` ``"build_date"` `: ``"2019-07-24T15:24:41.545295Z"``,`` ``"build_snapshot"` `: ``false``,`` ``"lucene_version"` `: ``"7.7.0"``,`` ``"minimum_wire_compatibility_version"` `: ``"5.6.0"``,`` ``"minimum_index_compatibility_version"` `: ``"5.0.0"`` ``},`` ``"tagline"` `: ``"You Know, for Search"``}到此，elasticsearch安装成功。这里多安装一个elasticsearch-head 用来调试和查看数据是非常方便的。程序下载地址：https://github.com/mobz/elasticsearch-head首先安装依赖包yum ``install` `git nodejs openssl-devel ``screen` `-y` `克隆 elasticsearch-``head``项目``[root@192.168.118.14 ~]``# git clone https://github.com/mobz/elasticsearch-head.git``[root@192.168.118.14 ~]``# cd elasticsearch-head/` `此时忽略phantomjs-prebuilt@2.1.16，执行命令如下``[root@node1 elasticsearch-``head``]``# npm install phantomjs-prebuilt --ignore-scripts` `[root@node1 elasticsearch-``head``]``# npm install``…这里是一个非常缓慢的过程。启动 elasticsearch-head 服务[root@192.168.118.14 ~]``#cd elasticsearch-head/``[root@192.168.118.14 ~``/elasticsearch-head``]``#screen``[root@node1 elasticsearch-``head``]``# npm run start``Ctrl+a Ctrl+d 将进程放置到后台，这里不懂的查下 ``screen` `命令，很好使。查看端口 只要 9100 被监听，说明启动成功。浏览器访问：妥了，安装成功。通过 elasticsearch-head 可以查看 elasticsearch 中的所有数据。目前就一个 node1 索引。如果要深入学习 elasticsearch 推荐一本书《elasticsearch-the-definitive-guide-cn》 网上有 PDF 可以下载。接下来，安装 kibana 。Kibana 和 elasticsearch安装到同一台主机的Kibana 下载地址：https://www.elastic.co/cn/downloads/past-releases#kibana直接rpm包安装[root@192.168.118.14 ~``/ELK``]``#yum localinstall kibana-6.8.2-x86_64.rpm -y修改配置文件：这里注意，如果将 kibana 端口修改为 80 ，这里是需要修改kibana启动用户为 root 因为普通用户是不能启动 1024 以下端口的。修改启动配置文件：[root@192.168.118.14 ~]``#vim /etc/systemd/system/kibana.service``User=root``Group=root` `再次启动服务``[root@192.168.118.14 ~]``#systemctl daemon-reload``[root@192.168.118.14 ~]``#systemctl restart kibana查看 80 端口如果被监听就说明启动成功。2.2 logstash 安装过程根据规划，logstash 应该被安装到一台独立的主机上，logstash安装非常简单。Logstash 下载地址：https://www.elastic.co/cn/downloads/past-releases#logstash和上面一样，初始化工作不要忘记，这里就不再描述了。安装 jdk 也和上面一样的，jdk验证：[root@192.168.118.15 ``/usr/local/src``]``#java -version``java version ``"1.8.0_77"``Java(TM) SE Runtime Environment (build 1.8.0_77-b03)``Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)安装 logstash[root@192.168.118.15 ~]``#yum localinstall logstash-6.8.2.rpm -y` `将 logstash 命令添加到 PATH 环境变量中``[root@192.168.118.15 ``/etc/logstash``]``#vim /etc/profile.d/logstash.sh``export` `PATH=``/usr/share/logstash/bin``:$PATHOk, 到这里已经安装完成，是不是很简单。验证：[root@192.168.118.15 ~]``#logstash -e 'input { stdin {} } output { stdout{} }'``只要出现 Successfully started Logstash API endpoint {:port=>9600} 就表示启动成功。``你好，中国``{`` ``"@version"` `=> ``"1"``,`` ``"message"` `=> ``"你好，中国"``,`` ``"host"` `=> ``"logstash-node1"``,`` ``"@timestamp"` `=> 2019-09-14T04:14:35.035Z测试通过，logstash验证成功。2.3 Filebeat 和 nginx 安装Filebeat 下载地址：https://www.elastic.co/cn/downloads/past-releases#filebeat首先安装 nginx 直接yum安装[root@192.168.118.16 ~]``#yum install nginx -y``启动nginx``[root@192.168.118.16 ~]``#nginx安装 filebeat[root@192.168.118.16 ~]``#yum localinstall filebeat-6.8.2-x86_64.rpm -y``开启nginx模块``[root@192.168.118.16 ~]``#cd /etc/filebeat/``[root@192.168.118.16 ``/etc/filebeat``]``#filebeat modules enable nginx``Enabled nginx修改 filebeat主配置文件：[root@192.168.118.16 ~]``#vim /etc/filebeat/filebeat.yml``注释掉输出到 elasticsearch``#output.elasticsearch:`` ``# Array of hosts to connect to.`` ``#hosts: ["localhost:9200"]` `开启输出到 logstash``output.logstash:`` ``# The Logstash hosts`` ``hosts: [``"192.168.118.16:5044"``]注意这里的 hosts 要写 logstash 主机的 IP修改 nginx 模块配置文件：[root@192.168.118.16 ~]``#vim /etc/filebeat/modules.d/nginx.yml启动 filebeat 服务[root@192.168.118.16 ~]``#systemctl start filebeat``Filebeat 服务是没有监听端口的，只要状态是 running 就表示启动成功，可以查看 filebeat 日志``/var/log/filebeat/filebeat到此，ELK + filebeat 已经部署完毕，接下来就可以安装需求来进行调整和收集数据，而这一块的工作都集中在 logstash，因此 ELK 编写 logstash 才是难点。Logstash 配置语法，强力建议查看官方文档，非常全面了。2.4 编写 logstash 配置文件这里采用循序渐进的方式展开，可以先写一个简单的测试。编写一个将数据输出到屏幕的配置文件：[root@192.168.118.15 ``/etc/logstash/conf``.d]``#vim test.confLogstash 可以根据配置文件来启动，启动方式如下：[root@192.168.118.15 ``/etc/logstash/conf``.d]``#logstash -f test.conf``出现 Successfully started Logstash API endpoint 就表示启动成功。启动成功后，我们尝试访问 nginx 生成日志数据。日志文件已经传输过来了，接下来就是把这些数据写入到 elasticsearch 中。继续修改配置文件：通过配置文件启动 logstash[root@192.168.118.15 ``/etc/logstash/conf``.d]``#logstash -f test.conf尝试访问 nginx 查看 elasticsearch-head中是否有新的索引被创建出来。如上图，一个新的索引被创建出来，可以通过 elasticsearch-head 查看该索引中的数据。目前已经将日志数据写入到 elasticsearch中了， 然后通过 kibana 展示出来，浏览器访问上面装好的 kibana设置完成，直接点击 Discover多访问几次nginx，查看日志是否展示出来。ok，到此， ELK + filebeat 获取 nginx 日志就完成了。虽然将日志展示出来了， 但是这样杂乱无章的日志数据看着还是很难受的，这就需要进一步的规整。下一篇再写如果更详细的通过 logstash获取nginx日志数据，然后通过kibana展示更规整的数据及绘图。
1. 前言先上一张整体的效果图：上面这张图就是通过 ELK 分析 nginx 日志所得到的数据，通过 kibana 的功能展示出来的效果图。是不是这样对日志做了解析，想要知道的数据一目了然。接下来就是实现过程实录。2. 实现过程通过上一篇：ELK 部署文档 已经对 ELK + filebeat 获取 nginx 做了详细的配置介绍，这里重点就不在安装 ELK 上面了。 下面这边的内容，主要是针对 logstash 配置文件的编写和 kibana web界面的配置。主机信息在申明下，和上一篇一样：2.1 nginx 日志格式编写在编写logstash 文件之前，得有一个标准输入输出格式，这个格式通用的就是 json 格式。首先，考虑如何才能获取 json 格式的日志，当然可以直接通过修改 nginx 日志的格式来实现，因此开始修改 nginx 日志格式。如果获取的日志无法修改json 格式，则可以通过正则表达式来匹配。在nginx 配置文件中添加如下日志格式：http { … log_format main_json '{"domain":"$server_name",' '"http_x_forwarded_for":"$http_x_forwarded_for",' '"time_local":"$time_iso8601",' '"request":"$request",' '"request_body":"$request_body",' '"status":$status,' '"body_bytes_sent":"$body_bytes_sent",' '"http_referer":"$http_referer",' '"upstream_response_time":"$upstream_response_time",' '"request_time":"$request_time",' '"http_user_agent":"$http_user_agent",' '"upstream_addr":"$upstream_addr",' '"upstream_status":"$upstream_status"}'; …. }定义的这个nginx 日志格式叫 main_json 后面的配置文件，都可以引用这个日志格式。除了nginx 日志参数以外，还可以通过配置文件来自行添加自定义参数，比如 获取用户的真实ip于是编写一个自定义变量的配置文件：[root@192.168.118.16 ~]`` vim /etc/nginx/location.conf` ` set $real_ip $remote_addr;``if` `( $http_x_forwarded_for ~ ``"^(\d+\.\d+\.\d+\.\d+)"` `) {`` ``set` `$real_ip $1;``}这个配置文件只是为了获取用户的真实IP，变量名为： real_ip 需要在nginx.conf 中引用，在刚才的配置文件中也加入该变量，完整日志格式如下：log_format main_json '{"domain":"$server_name",' '"real_ip":"$real_ip",' '"http_x_forwarded_for":"$http_x_forwarded_for",' '"time_local":"$time_iso8601",' '"request":"$request",' '"request_body":"$request_body",' '"status":$status,' '"body_bytes_sent":"$body_bytes_sent",' '"http_referer":"$http_referer",' '"upstream_response_time":"$upstream_response_time",' '"request_time":"$request_time",' '"http_user_agent":"$http_user_agent",' '"upstream_addr":"$upstream_addr",' '"upstream_status":"$upstream_status"}';注释掉该行： access_log /var/log/nginx/access.log main;接下来，编写一个nginx 配置文件 端口为 9527 作为测试使用[root@192.168.118.16 ~]`` vim /etc/nginx/conf.d/server_9527.conf``server {`` ``listen 9527;`` ``server_name localhost;`` ``include location.conf;`` ``location / {`` ``root ``/www/9527/``;`` ``index index.html;`` ``access_log ``/www/log/access``.log main_json;`` ``error_log ``/www/log/error``.log;`` ``}`` ``location ``/shop` `{`` ``root ``/www/9527``;`` ``access_log ``/www/log/shop_access``.log main_json;`` ``error_log ``/www/log/shop_error``.log;`` ``}``}` `[root@192.168.118.16 ~]`` mkdir -p /www/{9527,log}``[root@192.168.118.16 ~]`` cd /www/9527/``[root@192.168.118.16 ``/www/9527``]`` vim index.html``hello, 9527``[root@192.168.118.16 ``/www/9527``]`` mkdir -pv /www/9527/shop``[root@192.168.118.16 ``/www/9527``]`` vim /www/9527/shop/index.html``出售9527` `[root@192.168.118.16 ``/www/9527``]`` nginx -t``[root@192.168.118.16 ``/www/9527``]`` nginx -s reloadNginx 配置完成，重新加载，访问测试：[root@192.168.118.16 ~]`` curl http://192.168.118.16:9527/index.html``hello, 9527``[root@192.168.118.16 ~]`` curl http://192.168.118.16:9527/shop/index.html``出售9527页面访问正常，查看日志：[root@192.168.118.16 ~]`` ll -tsh /www/log/``total 8.0K``4.0K -rw-r--r-- 1 root root 346 Sep 14 14:35 shop_access.log``4.0K -rw-r--r--. 1 root root 341 Sep 14 14:35 access.log`` ``0 -rw-r--r--. 1 root root 0 Sep 14 14:35 error.log`` ``0 -rw-r--r-- 1 root root 0 Sep 14 14:34 shop_error.log日志文件已生成，查看日志格式：[root@192.168.118.16 ~]`` cat /www/log/access.log``{``"domain"``:``"localhost"``,``"real_ip"``:``""``,``"http_x_forwarded_for"``:``"-"``,``"time_local"``:``"2019-09-14T14:35:11+08:00"``,``"request"``:``"GET /index.html HTTP/1.1"``,``"request_body"``:``"-"``,``"status"``:200,``"body_bytes_sent"``:``"12"``,``"http_referer"``:``"-"``,``"upstream_response_time"``:``"-"``,``"request_time"``:``"0.000"``,``"http_user_agent"``:``"curl/7.29.0"``,``"upstream_addr"``:``"-"``,``"upstream_status"``:``"-"``}定义的 json 格式已经被引用到，nginx日志格式配置完成，接下来就是 通过filebeat 将nginx 日志传递给 logstash2.2 filebeat 传输 nginx 日志这里在上一篇的基础上做修改，直接修改 filebeat 配置文件：[root@192.168.118.16 ~]`` vim /etc/filebeat/modules.d/nginx.yml重启 filebeat 服务[root@192.168.118.16 ~]`` systemctl restart filebeat2.3 logstash 配置文件编写通过上面的步骤，filebeat 已经将 nginx 日志传输过来了，接下来就看 logstash 要怎么接收日志数据了，还是通过循序渐进的方式来编写。首先将日志数据打印到屏幕，保证数据的正确性。从 nginx.conf 启动 logstash。通过浏览器访问 nginx 9527端口产生日志数据。这里启动 logstash 可以添加 修改自动重载的模式，这样当修改了 nginx.conf 时，不必频繁的去关闭重启。[root@192.168.118.15 ``/etc/logstash/conf``.d]`` logstash -f nginx.conf --config.reload.automatic通过抓取一段 json 数据，分析下：logstash 输出内容这里面数据很多，但是这里的有些数据不是必要的，应该保留需要的数据，而剔除没必要的数据，使 json 看起来更加简洁。首先来查看这段 json ，发现真正的 nginx 日志数据都存在 message 里面，其他的都是一些主机服务相关的信息，但是 message 看起来乱糟糟的，简直没法看。既然采用的 json 格式，那就能够格式化。修改配置文件如下：logstash 输出内容将这两次获取的数据进行一个对比，下面这个数据 message 被删除了，但是 message 中的每个字段都独立出来了。这样的好处： （1）日志信息更加清晰，能够准确的定位到某一个字段； （2）为后面存储到 elasticsearch 中，进行查询或者筛选做好了准备。上面这个操作就等于是将原来的 message 分列存放了。上面这个json 发现有两个时间： @timestamp - 格林尼治时间 - logstash 获取日志时间 Time_local - 东八区时间 - nginx日志记录时间这两个时间的 分钟和秒钟并不一致，而后面过滤日志采用的是 @timestamp 时间，也就是 logstash 时间，这就会造成 nginx 日志时间不准确的现象，因此需要将两个时间修改为一致。logstash 输出内容现在，对比两个时间的分钟 和秒钟，完全一致了。接下来，删除一些不必要的字段，并重命名一些字段名，修改配置文件如下：logstash 输出内容经过重命名和删除没有的字段，json 也变的精简了很多，这样存储 elasticsearch 消耗的存储空间也响应的变小了。接下来就可以将数据写入到 elasticsearch 中了。在这之前，做的都是 access.log，压根就没考虑到 error.log 的格式，因为 nginx 中 error.log 日志格式无法自定义。尝试访问一个错误uri 来查看下获取到的数据：logstash 输出内容error.log 过来的数据就变成上面这个样子了。这又是个问题，做 ELK 一是为了分析数据，二是为了尽快排错，如果 ELK 连这个都做不到，那就有点鸡肋了。上面的这个格式看起来又是很乱了，nginx 错误日志都在 message 中，虽然nginx 错误日志无法定义格式，但是 logstash 可以通过正则表达式来将它转换为 json 格式。但在这之前，应该考虑，access.log 和 error.log 是两种不同的格式，不能用同一种方式去匹配。那怎么判断数据是来自 access.log 还是 error.log 呢？这里语法肯定是想到了：If … {``Access.log``} elseif … {``Error.log``}对，语法没错，但是用什么条件呢？查看上面的日志，不难发现每次都有这样的字段：Access.log 日志数据：`` ``"fileset"` `=> {`` ``"module"` `=> ``"nginx"``,`` ``"name"` `=> ``"access"` `error.log 日志数据：`` ``"fileset"` `=> {`` ``"module"` `=> ``"nginx"``,`` ``"name"` `=> ``"error"这样，就有判断的依据了，根据logstash配置语法开始写：到目前为止，logstash 的 nginx 日志收集过滤配置文件如下：配置文件名：nginx.confnginx.conf测试 access.log 日志格式数据：logstash 输出内容测试 error.log 日志格式数据：logstash 输出内容这下没问题了， 两种格式的数据都获取到了。接下来就将数据写入到 elasticsearch中。到目前为止，logstash 配置文件 nginx.conf 如下：nginx.conf这个配置也算是本次 nginx 最终版配置了。使用浏览器多次访问nginx 9527 端口，然后切换到 elasticsearch-head 查看索引是否创建成功。ok，已经看到今天的索引创建成功，查看数据。数据也是没有问题的，切换到 kibana 添加索引。ok，目前已经将数据存储到 elasticsearch 并通过 kibana 展示出来了，但是想要更清晰的分析查看数据还需要在 kibana 上下一番功夫。2.4 kibana 展示 首先是 Discover 这里，每次进来，都需要一目了然的查看日志，做以下配置：上面两个设置以后，每次登录进来只需要点击 打开 查看相关模板就能看到清晰的日志数据。接下来，就是绘制最上面那副图啦。在绘制之前必须要有数据支撑，因为这个是测试环境没有真是的用户访问。因此需要造一批假数据访问。方法就是 直接去 access.log 里复制一条数据，修改 real_ip 为 公网ip假数据添加成功后，来进行图表的配置，点击 可视化第一个：访问省会城市 TOP 5 （饼图）选择饼图，然后选择 logstash-nginx-* 索引完成后点击保存。第二个：访问分布地图（坐标地图）完成后点击保存。第三个：域名TOP5 （数据表）完成后点击保存。第四个：后端服务TOP5（数据表）完成后点击保存。第五个：uri top 5（数据表）完成后点击保存。第六个：realipTOP5 （水平条形图）完成后点击保存。第七个：http状态TOP5 （饼图）完成后点击保存。好了， 在 可视化 一栏中，创建了 7 个数据表图，点开 仪表板，将这些图表展示出来就行了。然后将图表摆放好，大功告成。
ELK收集日志作者：Andu 2019/6/30精华文章 第1章 ELK介绍没有日志收集平台的时候如何分析日志？什么是ELK/EFLK? ELK的数据流转流程?官方演示地址：https://demo.elastic.co/第2章 日志收集分类代理层：nginx,haproxyweb层：nginx,tomcat数据库层：mysql,redis,mongo,elasticsearch操作系统层：source,message第3章 安装部署ELK3.1 官方地址https://www.elastic.co/guide/index.html3.2 安装配置java[root@Andu ~]# yum install java-1.8.0-openjdk.x86_64 -yA1\(#_msocom_1) [root@Andu ~]# java -version openjdk version "1.8.0_212" OpenJDK Runtime Environment (build 1.8.0_212-b04) OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode) 3.3 更新时间yum install ntpdate -y ntpdate time1.aliyun.comA2\(#_msocom_2) 3.4 安装配置elasticsearch[root@Andu ~]# mkdir /data/soft/ -p [root@Andu ~]# cd /data/soft/ [root@Andu soft]# rz [root@Andu soft]# ll 总用量 506120 -rw-r--r-- 1 root root 114059630 2月 25 11:09 elasticsearch-6.6.0.rpm -rw-r--r-- 1 root root 36581177 4月 27 12:29 elasticsearch-head.tar.gz -rw-r--r-- 1 root root 11790119 2月 25 11:08 filebeat-6.6.0-x86_64.rpm -rw-r--r-- 1 root root 185123116 2月 25 11:11 kibana-6.6.0-x86_64.rpm -rw-r--r-- 1 root root 170703770 2月 25 11:38 logstash-6.6.0.rpm [root@Andu soft]# rpm -ivh elasticsearch-6.6.0.rpm 警告：elasticsearch-6.6.0.rpm: 头V4 RSA/SHA512 Signature, 密钥 ID d88e42b4: NOKEY 准备中... ################################# [100%] Creating elasticsearch group... OK Creating elasticsearch user... OK 正在升级/安装... 1:elasticsearch-0:6.6.0-1 ################################# [100%] \### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using systemd sudo systemctl daemon-reload sudo systemctl enable elasticsearch.service \### You can start elasticsearch service by executing sudo systemctl start elasticsearch.serviceCreated elasticsearch keystore in /etc/elasticsearch 3.4.1 相关配置目录及配置文件[root@Andu ~]# rpm -qc elasticsearch /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/jvm.options /etc/elasticsearch/log4j2.properties /etc/elasticsearch/role_mapping.yml /etc/elasticsearch/roles.yml /etc/elasticsearch/users /etc/elasticsearch/users_roles /etc/init.d/elasticsearch /etc/sysconfig/elasticsearch /usr/lib/sysctl.d/elasticsearch.conf /usr/lib/systemd/system/elasticsearch.service 3.4.2 ES配置文件解读[root@Andu soft]# vim /etc/elasticsearch/elasticsearch.yml [root@Andu soft]# grep ^[a-z] /etc/elasticsearch/elasticsearch.yml node.name: node-1 path.data: /var/lib/elasticsearchA3\(#_msocom_3) path.logs: /var/log/elasticsearchA4\(#_msocom_4) bootstrap.memory_lock: trueA5\(#_msocom_5) network.host: 192.168.10.66,127.0.0.1A6\(#_msocom_6) http.port: 9200A7\(#_msocom_7) [root@Andu soft]# systemctl daemon-reload [root@Andu soft]# systemctl enable elasticsearch.service Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.service to /usr/lib/systemd/system/elasticsearch.service. [root@Andu soft]# systemctl start elasticsearch.service 3.4.3 启动失败报错此时启动会发现失败，原因是内存锁定失败[2019-05-12T14:39:58,764][ERROR][o.e.b.Bootstrap ] [node-1] node validation exception [1] bootstrap checks failed [1]: memory locking requested for elasticsearch process but memory is not locked 3.4.4 锁定内存失败解决方案官方解决方案https://www.elastic.co/guide/en/elasticsearch/reference/6.4/setup-configuration-memory.html https://www.elastic.co/guide/en/elasticsearch/reference/6.4/setting-system-settings.html#sysconfig \### 修改启动配置文件 vim /usr/lib/systemd/system/elasticsearch.service \### 增加如下参数 [Service] LimitMEMLOCK=infinity \### 重新启动 systemctl daemon-reload systemctl restart elasticsearch 3.4.5 检查启动是否成功 [root@Andu ~]# netstat -lntup|grep 9200 tcp6 0 0 192.168.10.66:9200 :::* LISTEN 15824/java tcp6 0 0 127.0.0.1:9200 :::* LISTEN 15824/java [root@Andu ~]# curl localhost:9200 { "name" : "node-1", "cluster_name" : "elasticsearch", "cluster_uuid" : "As5ZlEQ2Syq0ktLL0hg5XA", "version" : { "number" : "6.6.0", "build_flavor" : "default", "build_type" : "rpm", "build_hash" : "a9861f4", "build_date" : "2019-01-24T11:27:09.439740Z", "build_snapshot" : false, "lucene_version" : "7.6.0", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" } 3.5 服务模式安装配置es-head插件3.5.1 插件官方地址https://github.com/mobz/elasticsearch-head3.5.2 使用docker部署elasticsearch-headdocker pull alivv/elasticsearch-head docker run --name es-head -p 9100:9100 -dit alivv/elasticsearch-head 3.5.3 使用nodejs编译安装官网地址https://nodejs.org/en/download/package-manager/https://nodejs.org/dist/latest-v10.x/http://npm.taobao.org下载安装yum install nodejs npm openssl screen -y node -v npm -v npm install -g cnpm --registry=https://registry.npm.taobao.org cd /opt/ git clone git://github.com/mobz/elasticsearch-head.git cd elasticsearch-head/ cnpm install screen -S es-head cnpm run start Ctrl+A+D 3.5.4 修改ES配置文件支持跨域官方说明：https://www.elastic.co/guide/en/elasticsearch/reference/6.6/modules-http.html配置参数：http.cors.enabled: true http.cors.allow-origin: "*" 3.5.5 网页访问IP地址:9200/9100 3.6 谷歌浏览器插件形式安装es-head 使用服务模式安装es-head插件过程比较繁琐，网络不好的时候还会经常卡住，幸运的是es-head插件官方还提供了另外一种更简便的方式，就是google chrome的插件 优势 1.免安装，直接下载插件安装在浏览器即可2.只要浏览器和服务器可以通信就能使用 3.7 安装配置kibana3.7.1 安装配置kibana[root@Andu soft]# rpm -ivh kibana-6.6.0-x86_64.rpm [root@Andu soft]# grep "^[a-z]" /etc/kibana/kibana.yml server.port: 5601 server.host: "192.168.10.66" elasticsearch.hosts: ["http://localhost:9200"] kibana.index: ".kibana [root@Andu soft]# systemctl start kibana [root@Andu soft]# systemctl status kibana [root@Andu soft]# netstat -lntup|grep 5601 tcp 0 0 192.168.10.66:5601 0.0.0.0:* LISTEN 16442/node 3.8 安装filebeat和logstashrpm -ivh filebeat-6.6.0-x86_64.rpm rpm -ivh logstash-6.6.0.rpm 3.9 docker安装elkversion: '3' services: elasticsearch: image: elasticsearch:v1 container_name: elasticsearch environment: \- cluster.name=docker-cluster \- bootstrap.memory_lock=true \- "ES_JAVA_OPTS=-Xms8g -Xmx8g" \- "discovery.zen.ping.unicast.hosts=elasticsearch" ulimits: memlock: ​ soft: -1 ​ hard: -1 volumes: \- /data/docker_es_data:/usr/share/elasticsearch/data ports: \- 19200:9200 networks: \- esnet elasticsearch-head: image: elasticsearch-head:v1 container_name: elasticsearch-head ports: \- 19100:9100 networks: \- esnet kibana: image: kibana:v1 container_name: kibana environment: \- ELASTICSEARCH_URL="http://elasticsearch:9200" \- kibana.index=".kibana" ports: \- 15601:5601 networks: \- esnet logstash: image: logstash:v1 container_name: logstash environment: \- ELASTICSEARCH_URL="http://elasticsearch:9200" ports: \- 16379:6379 networks: \- esnet networks: esnet: 第4章 使用filebeat配置日志收集4.1 收集nginx日志4.1.1 安装nginx和ab工具[root@Andu ~]# yum install nginx httpd-tools -y 4.1.2 启动测试[root@Andu ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [root@Andu ~]# systemctl start nginx [root@Andu ~]# netstat -lntup|grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1888/nginx: master tcp6 0 0 :::80 :::* LISTEN 1888/nginx: master [root@Andu ~]# ab -c 10 -n 100 192.168.10.66/ [root@Andu ~]# ab -c 10 -n 100 192.168.10.66/test.html 4.1.3 查看日志[root@Andu ~]# tail -f /var/log/nginx/access.log 192.168.10.66 - - [13/May/2019:00:24:02 +0800] "GET /test.html HTTP/1.0" 404 3650 "-" "ApacheBench/2.3" "-" 192.168.10.66 - - [13/May/2019:00:24:02 +0800] "GET /test.html HTTP/1.0" 404 3650 "-" "ApacheBench/2.3" "-" ....................................... 4.1.4 配置filebeat收集普通日志相关网址https://www.elastic.co/guide/en/beats/filebeat/7.x/filebeat-input-log.htmlhttps://www.elastic.co/guide/en/beats/filebeat/7.x/configuration-template.htmlhttps://www.elastic.co/guide/en/beats/filebeat/7.x/configuration-template.html正确配置filebeat.inputs: \- type: log enabled: true paths: \- /var/log/nginx/access.log json.keys_under_root: true json.overwrite_keys: true setup.kibana: host: "192.168.10.66:5601" output.elasticsearch: hosts: ["192.168.10.66:9200"] index: "nginx-%{[beat.version]}-%{+yyyy.MM}" setup.template.name: "nginx" setup.template.pattern: "nginx-*" setup.template.enabled: false setup.template.overwrite: true 4.1.5 kibana配置management-->index patterns-->nginx-->@timestamp 4.1.6 修改nginx日志为json格式 log_format main '{ "time_local": "$time_local", ' ​ '"remote_addr": "$remote_addr", ' ​ '"referer": "$http_referer", ' ​ '"request": "$request", ' ​ '"status": $status, ' ​ '"bytes": $body_bytes_sent, ' ​ '"agent": "$http_user_agent", ' ​ '"x_forwarded": "$http_x_forwarded_for", ' ​ '"up_addr": "$upstream_addr",' ​ '"up_host": "$upstream_http_host",' ​ '"upstream_time": "$upstream_response_time",' ​ '"request_time": "$request_time"' ' }'; 4.1.7 查看日志是否为json格式[root@Andu ~]# tail -f /var/log/nginx/access.log { "time_local": "13/May/2019:00:30:51 +0800", "remote_addr": "192.168.10.66", "referer": "-", "request": "GET /test.html HTTP/1.0", "status": 404, "bytes": 3650, "agent": "ApacheBench/2.3", "x_forwarded": "-", "up_addr": "-","up_host": "-","upstream_time": "-","request_time": "0.000" } { "time_local": "13/May/2019:00:30:51 +0800", "remote_addr": "192.168.10.66", "referer": "-", "request": "GET /test.html HTTP/1.0", "status": 404, "bytes": 3650, "agent": "ApacheBench/2.3", "x_forwarded": "-", "up_addr": "-","up_host": "-","upstream_time": "-","request_time": "0.000" } 4.1.8 收集多个日志并分类创建索引 filebeat配置 [root@Andu filebeat]# cat filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/log/nginx/access.log json.keys_under_root: true json.overwrite_keys: true tags: ["access"] \- type: log enabled: true paths: \- /var/log/nginx/error.log tags: ["error"] setup.template.settings: index.number_of_shards: 3 setup.kibana: host: "192.168.10.66:5601" output.elasticsearch: hosts: ["localhost:9200"] indices: \- index: "nginx_access-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ tags: "access" \- index: "nginx_error-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ tags: "error" setup.template.name: "nginx" setup.template.pattern: "nginx_*" setup.template.enabled: false setup.template.overwrite: true 4.2 收集tomcat日志4.2.1 安装tomcatyum install tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp tomcat-javadoc -y 4.2.2 启动检查[root@Andu ~]# systemctl start tomcat [root@Andu ~]# systemctl status tomcat [root@Andu ~]# lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 18915 tomcat 49u IPv6 61950 0t0 TCP *:webcache (LISTEN) 4.2.3 访问测试4.2.4 修改日志为json格式[root@Andu ~]# vim /etc/tomcat/server.xml [root@Andu ~]# cat -n /etc/tomcat/server.xml \---------------- 137 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 138 prefix="localhost_access_log." suffix=".txt" 139 pattern="{"clientip":"%h","ClientUser":"%l","authenticated":"%u","AccessTime":"%t","method":"%r","status":"%s","SendBytes":"%b","Query?string":"%q","partner":"%{Referer}i","AgentVersion":"%{User-Agent}i"}"/> \---------------- 4.2.5 重启确认日志是否为json格式[root@Andu ~]# systemctl restart tomcat [root@Andu ~]# tail -f /var/log/tomcat/localhost_access_log.2019-05-13.txt {"clientip":"192.168.47.1","ClientUser":"-","authenticated":"-","AccessTime":"[13/May/2019:13:18:03 +0800]","method":"GET /docs/images/tomcat.gif HTTP/1.1","status":"200","SendBytes":"2066","Query?string":"","partner":"http://192.168.10.66:8080/docs/realm-howto.html","AgentVersion":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"} 在线解析测试正确4.2.6 filebeat配置[root@Andu ~]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/log/tomcat/localhost_access_log* json.keys_under_root: true json.overwrite_keys: true tags: ["tomcat"]A16\(#_msocom_16) setup.kibana: host: "192.168.10.66:5601" output.elasticsearch: hosts: ["localhost:9200"] index: "tomcat-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ tags: "tomcat" setup.template.name: "tomcat" setup.template.pattern: "tomcatn-*" setup.template.enabled: false setup.template.overwrite: trueA17\(#_msocom_17) 亲测可用配置为如下 filebeat.inputs: \#################tomcat############# \- type: log enabled: true paths: \- /var/log/tomcat/localhost_access_log.*.txt json.keys_under_root: true json.overwrite_keys: true \#################output############# setup.kibana: host: "192.168.10.66:5601" output.elasticsearch: hosts: ["192.168.10.66:9200"] indices: \- index: "tomcat-access-%{[beat.version]}-%{+yyyy.MM}" setup.template.name: "tomcat" setup.template.pattern: "tomcat-*" setup.template.enabled: false setup.template.overwrite: true 4.2.7 配置tomcat收集多个域名的日志配置多个host标签4.3 收集java日志4.3.1 官方地址https://www.elastic.co/guide/en/beats/filebeat/6.6/multiline-examples.html因为java日志的输出信息非常多，需要将多行拼成一个事件，所以需要多行匹配模式因为elasticsearch本身就是java开发的，所以我们可以直接收集ES的日志4.3.2 filebeat配置[root@Andu ~]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/log/elasticsearch/elasticsearch.log multiline.pattern: '^\[' multiline.negate: true multiline.match: after setup.kibana: host: "192.168.10.66:5601" output.elasticsearch: hosts: ["localhost:9200"] index: "es-%{[beat.version]}-%{+yyyy.MM.dd}" setup.template.name: "es" setup.template.pattern: "es-*" setup.template.enabled: false setup.template.overwrite: true 4.4 收集docker日志4.4.1 安装dockerrm -fr /etc/yum.repos.d/local.repo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo yum install docker-ce -y systemctl start docker vi /etc/docker/daemon.json { "registry-mirrors": ["https://registry.docker-cn.com"] } systemctl restart docker 4.4.2 运行nginx镜像docker pull nginx docker run --name nginx -p 80:80 -d nginx docker ps docker logs -f nginx 4.4.3 配置filebeat收集单个docker日志官方介绍：https://www.elastic.co/guide/en/beats/filebeat/6.7/filebeat-input-docker.html首先查看docker容器的IDdocker inspect nginx-test|grep -w "Id" 配置文件filebeat.inputs: \- type: docker containers.ids: \- '2338d5038f7a2eac96d84d6cf424fb1829bd754ec5e0df944bdd29ba6d61a54e' tags: ["docker-nginx"] output.elasticsearch: hosts: ["localhost:9200"] index: "docker-nginx-%{[beat.version]}-%{+yyyy.MM.dd}" setup.template.name: "docker" setup.template.pattern: "docker-*" setup.template.enabled: false setup.template.overwrite: true 4.4.4 使用通配符收集所有容器的日志新版本的filebeat增加了收集多个容器的日志的选项https://www.elastic.co/guide/en/beats/filebeat/7.2/filebeat-input-container.html4.4.5 配置filebeat通过标签收集多个容器日志假如我们有多个docker镜像或者重新提交了新镜像，那么直接指定ID的就不是太方便了。我们从当前的容器提交一个新的镜像并且运行起来docker commit nginx nginx:v2 docker images docker run --name nginx -p 8080:80 -d nginx:v2 此时我们的容器目录下就有了两个不同的容器目录[root@elk-176 containers]# ls /var/lib/docker/containers/ 2338d5038f7a2eac96d84d6cf424fb1829bd754ec5e0df944bdd29ba6d61a54e 3bb5250e7e50a4ed8d1fae7a43d3bf4294864ac4e0af125ae5231cd9bd76b914 如果直接配置filebeat存到es里本台机器所有的容器日志都会混在一起没有办法区分多容器日志收集处理：其实收集的日志本质来说还是文件，而这个日志是以容器-json.log命名存放在默认目录下的json格式的文件：[root@elk-176 ~]# head -1 /var/lib/docker/containers/2338d5038f7a2eac96d84d6cf424fb1829bd754ec5e0df944bdd29ba6d61a54e/2338d5038f7a2eac96d84d6cf424fb1829bd754ec5e0df944bdd29ba6d61a54e-json.log {"log":"192.168.47.1 - - [23/May/2019:19:12:04 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36\" \"-\"\n","stream":"stdout","time":"2019-05-23T19:12:04.939212514Z"} 但是每个容器的ID都不一样，为了区分不同服务运行的不同容器，可以使用docker-compose通过给容器添加labels标签来作为区分然后filbeat把容器日志当作普通的json格式来解析并传输到es操作步骤：1.安装docker-composeyum install -y python2-pip 2.这里使用pip安装，默认源为国外，可以使用国内加速，相关网站https://mirrors.tuna.tsinghua.edu.cn/help/pypi/pip加速操作命令pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 3.继续安装docker-composepip install docker-compose 4.检查docker-compose version 5.编写docker-compose.yml[root@elk-176 ~]# cat docker-compose.yml version: '3' services: nginx: image: nginx:v2 # 设置labels labels: service: nginx \# logging设置增加labels.service logging: options: ​ labels: "service" ports: \- "8080:80" db: image: nginx:latest \# 设置labels labels: service: db \# logging设置增加labels.service logging: options: ​ labels: "service" ports: \- "80:80" 6.清理镜像docker ps -a|awk 'NR>1{print "docker rm",$1}'|bash 7.运行docker-compose.ymldocker-compose up -d 8.检查日志是否增加了lable标签[root@elk-176 ~]# tail -1 /var/lib/docker/containers/b2c1f4f7f5a2967fe7d12c1db124ae41f009ec663c71608575a4773beb6ca5f8/b2c1f4f7f5a2967fe7d12c1db124ae41f009ec663c71608575a4773beb6ca5f8-json.log {"log":"192.168.47.1 - - [23/May/2019:13:22:32 +0000] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36\" \"-\"\n","stream":"stdout","attrs":{"service":"nginx"},"time":"2019-05-23T13:22:32.478708392Z"} 9.配置filebeat[root@elk-176 ~]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/lib/docker/containers/*/*-json.log json.keys_under_root: true json.overwrite_keys: true output.elasticsearch: hosts: ["192.168.10.66:9200"] indices: \- index: "docker-nginx-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ attrs.service: "nginx" \- index: "docker-db-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ attrs.service: "db" setup.template.name: "docker" setup.template.pattern: "docker-*" setup.template.enabled: false setup.template.overwrite: true 4.4.6 配置filebeat通过服务类型和日志类型多条件创建不同索引目前为止，已经可以按服务来收集日志了，但是错误日志和正确日志混在了一起，不好区分，所以可以进一步进行条件判断，根据服务和日志类型创建不同的索引filebeat配置文件[root@elk-176 ~]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/lib/docker/containers/*/*-json.log json.keys_under_root: true json.overwrite_keys: true output.elasticsearch: hosts: ["192.168.10.66:9200"] indices: \- index: "docker-nginx-access-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ attrs.service: "nginx" ​ stream: "stdout" \- index: "docker-nginx-error-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ attrs.service: "nginx" ​ stream: "stderr" \- index: "docker-db-access-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ attrs.service: "db" ​ stream: "stdout" \- index: "docker-db-error-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ attrs.service: "db" ​ stream: "stderr" setup.template.name: "docker" setup.template.pattern: "docker-*" setup.template.enabled: false setup.template.overwrite: true 4.4.7 验证提交新镜像运行后日志收集情况1.提交新镜像[root@elk-176 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f92f4d747584 nginx:latest "nginx -g 'daemon of…" 45 minutes ago Exited (0) 51 seconds ago root_db_1 b2c1f4f7f5a2 nginx:v2 "nginx -g 'daemon of…" 45 minutes ago Exited (0) 51 seconds ago root_nginx_1 [root@elk-176 ~]# docker commit root_nginx_1 nginx:v3 sha256:4457e2b7afc719ef185c75c02031b11c1407efe2e2e57b85f0c9347d04a9ff00 [root@elk-176 ~]# docker commit root_db_1 nginx:v4 sha256:a7e8d8b3290c817194956aa06fc486ef928853121d9c6224fd64fe759c967dda [root@elk-176 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx v4 a7e8d8b3290c 35 seconds ago 109MB nginx v3 4457e2b7afc7 45 seconds ago 109MB nginx v2 c181c6355cd9 2 hours ago 109MB nginx latest 53f3fd8007f7 2 weeks ago 109MB 2.修改并运行docker-compose[root@elk-176 ~]# cat docker-compose.yml version: '3' services: nginx: image: nginx:v3 \# 设置labels labels: service: nginx \# logging设置增加labels.service logging: options: ​ labels: "service" ports: \- "8080:80" db: image: nginx:v4 \# 设置labels labels: service: db \# logging设置增加labels.service logging: options: ​ labels: "service" ports: \- "80:80" [root@elk-176 ~]# docker-compose up -d Starting root_nginx_1 ... Starting root_nginx_1 ... done Starting root_db_1 ... done [root@elk-176 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 04308aa3928b nginx:v4 "nginx -g 'daemon of…" 30 seconds ago Up 1 second 0.0.0.0:80->80/tcp root_db_1 49d2e2210e6f nginx:v3 "nginx -g 'daemon of…" 30 seconds ago Up 1 second 0.0.0.0:8080->80/tcp root_nginx_1 3.访问并查看是否有新数据生成curl logcalhost/zhangya.html curl logcalhost:8080/zhangya.html 4.经过查看发现已经成功收集到了日志，这样我们就做到了不用修改filebeat配置文件也可以持续的收集新镜像的日志并按分类创建不同的索引4.4.8 修改docker容器内日志类型为json刚才收集的docker内的日志类型为普通格式，如果我们修改为json格式会如何呢？第5章 使用filledeat modules配置5.1 官方网址https://www.elastic.co/guide/en/beats/filebeat/6.6/configuration-filebeat-modules.html5.2 使用模版配置nginx正常日志社区论坛：https://discuss.elastic.co/t/filebeat-module-custom-index/1813505.2.1 filebeat配置文件[root@Andu ~]# cat /etc/filebeat/filebeat.yml filebeat.config.modules: path: ${path.config}/modules.d/*.yml reload.enabled: true setup.kibana: host: "192.168.10.66:5601" output.elasticsearch: hosts: ["localhost:9200"] indices: \- index: "nginx_access-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ fileset.name: "access" \- index: "nginx_error-%{[beat.version]}-%{+yyyy.MM.dd}" when.contains: ​ fileset.name: "error" setup.template.name: "nginx" setup.template.pattern: "nginx_*" setup.template.enabled: false setup.template.overwrite: true 5.2.2 filebeat modules配置使用nginx模版配置需要安装2个插件，默认从官网下载速度太慢，可以提前下载然后离线安装https://www.elastic.co/guide/en/elasticsearch/plugins/6.6/ingest-geoip.htmlhttps://www.elastic.co/guide/en/elasticsearch/plugins/6.6/plugin-management-custom-url.html在线安装：[root@Andu ~]# /usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-user-agent [root@Andu ~]# /usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-geoip 离线下载安装：[root@Andu ~]# wget https://artifacts.elastic.co/downloads/elasticsearch-plugins/ingest-user-agent/ingest-user-agent-6.6.0.zip [root@Andu ~]# wget https://artifacts.elastic.co/downloads/elasticsearch-plugins/ingest-geoip/ingest-geoip-6.6.0.zip [root@Andu ~]# /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///root/ingest-geoip-6.6.0.zip [root@Andu ~]# /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///root/ingest-user-agent-6.6.0.zip 激活nginx模块：[root@Andu ~]# filebeat modules enable nginx [root@Andu ~]# egrep -v "#|^$" /etc/filebeat/modules.d/nginx.yml \- module: nginx access: enabled: true var.paths: ["/var/log/nginx/access.log"] error: enabled: true var.paths: ["/var/log/nginx/error.log" 注意：6.7之后这两个插件默认集成到了elasticsearch，不需要单独安装了5.3 使用模块收集系统日志message和secure日志如果不需要转换，也可以直接按普通日志模式收集message和secure日志5.4 导入kibana视图默认如果使用filbeat模版导入视图会把所有的服务都导入进去,而我们实际上并不需要这么多视图，而且默认的视图模版只能匹配filebeat-*开头的索引，所以这里我们有2个需要需要解决：1.通过一定处理只导入我们需要的模版2.导入的视图模版索引名称可以自定义解决方法：1.备份一份filebeat的kibana视图，删除不需要的视图模版文件2.修改视图文件里默认的索引名称为我们需要的索引名称cp -a /usr/share/filebeat/kibana /root find . -type f ! -name "*nginx*"|xargs rm -rf sed -i 's#filebeat\-\*#nginx\-\*#g' Filebeat-nginx-overview.json 替换索引名称filebeat setup --dashboards -E setup.dashboards.directory=/root/kibana/ 5.5 使用模块收集mysql日志和慢日志5.6 使用模块收集mongo日志和redis日志第6章 使用缓存收集日志当日志的数量非常多的时候，可能需要引入缓存层作为临时存储数据的地方，防止因为ES处理不过来导致日志丢失的情况。filebeat支持将日志发送到redis或者kafka作为消息队列缓存。但是使用了缓存层，就不能使用模版来配置日志收集了。所以最好日志是json格式6.1 使用单台redis作为缓存这里需要说明，如果使用redis作为缓存可以将不同的日志类型单独写成一个键，这样好处是清晰，但是缺点是logstash写起来起来复杂也可以将所有的日志全部写入到一个键中，然后靠后端的logstash去过滤处理。6.1.1 安装启动测试redis[root@Andu ~]# yum install redis -y [root@Andu ~]# systemctl status redis [root@Andu ~]# redis-cli 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> GEt k1 "v1" 127.0.0.1:6379> 6.1.2 配置nginx的json日志将nginx的日志调整为json格式 log_format json '{ "time_local": "$time_local", ' ​ '"remote_addr": "$remote_addr", ' ​ '"referer": "$http_referer", ' ​ '"request": "$request", ' ​ '"status": $status, ' ​ '"bytes": $body_bytes_sent, ' ​ '"agent": "$http_user_agent", ' ​ '"x_forwarded": "$http_x_forwarded_for", ' ​ '"up_addr": "$upstream_addr",' ​ '"up_host": "$upstream_http_host",' ​ '"upstream_time": "$upstream_response_time",' ​ '"request_time": "$request_time"' ' }'; 6.1.3 配置filebeat写入到不同的key中[root@Andu ~]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/log/nginx/access.log json.keys_under_root: true json.overwrite_keys: true tags: ["access"] \- type: log enabled: true paths: \- /var/log/nginx/error.log tags: ["error"] setup.template.settings: index.number_of_shards: 3 setup.kibana: host: "192.168.10.66:5601" output.redis: hosts: ["localhost"] keys: \- key: "nginx_access" when.contains: ​ tags: "access" \- key: "nginx_error" when.contains: ​ tags: "error" 6.1.4 配置logstash读取不同的key[root@Andu ~]# cat /etc/logstash/conf.d/redis.conf input { redis { host => "127.0.0.1" port => "6379" db => "0" key => "nginx_access" data_type => "list" } redis { host => "127.0.0.1" port => "6379" db => "0" key => "nginx_error" data_type => "list" } } filter { mutate { convert => ["upstream_time", "float"] convert => ["request_time", "float"] } } output { stdout {} if "access" in [tags] { elasticsearch { ​ hosts => "http://localhost:9200" ​ manage_template => false ​ index => "nginx_access-%{+yyyy.MM.dd}" } } if "error" in [tags] { elasticsearch { ​ hosts => "http://localhost:9200" ​ manage_template => false ​ index => "nginx_error-%{+yyyy.MM.dd}" } } } 6.1.5 filebeat收集日志写入到一个key中[root@Andu ~]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/log/nginx/access.log json.keys_under_root: true json.overwrite_keys: true tags: ["access"] \- type: log enabled: true paths: \- /var/log/nginx/error.log tags: ["error"] setup.template.settings: index.number_of_shards: 3 setup.kibana: host: "192.168.10.66:5601" output.redis: hosts: ["localhost"] key: "filebeat" 6.1.6 logstash根据tag区分一个key里的不同日志[root@Andu ~]# cat /etc/logstash/conf.d/redis.confinput { redis { host => "127.0.0.1" port => "6379" db => "0" key => "filebeat" data_type => "list" } } filter { mutate { convert => ["upstream_time", "float"] convert => ["request_time", "float"] } } output { if "access" in [tags] { elasticsearch { ​ hosts => "http://localhost:9200" ​ manage_template => false ​ index => "nginx_access-%{+yyyy.MM.dd}" } } if "error" in [tags] { elasticsearch { ​ hosts => "http://localhost:9200" ​ manage_template => false ​ index => "nginx_error-%{+yyyy.MM.dd}" } } } 6.2 使用nginx+keepalived代理多台redis6.2.1 解决方案介绍上面我们实验了单台redis作为收集日志的缓存层，但是单台redis存在一个问题，就是单点故障虽然可以做持久化处理，但是加入服务器坏掉或者修复时间未知的情况下还是有可能会丢数据。redis集群方案有哨兵和集群，但可惜的是filebeat和logstash都不支持这两种方案。不过利用我们目前所学的知识完全可以解决这个问题，虽然不是彻底解决，但是已经很好了方案如下：1.使用nginx+keepalived反向代理负载均衡到后面的多台redis2.考虑到redis故障切换中数据一致性的问题，所以最好我们只使用2台redis,并且只工作一台，另外一台作为backup，只有第一台坏掉后，第二台才会工作。3.filebeat的oputut的redis地址为keepalived的虚拟IP4.logstash可以启动多个节点来加速读取redis的数据5.后端可以采用多台es集群来做支撑6.2.2 nginx配置文件注意：添加stream模块，要在nginx.conf里最后添加，而不是在conf.d里面添加子配置[root@lb02 ~]# cat /etc/nginx/nginx.conf .......................... stream { upstream redis { server 10.0.0.51:6381 max_fails=2 fail_timeout=10s; server 10.0.0.51:6382 max_fails=2 fail_timeout=10s backup; } server { ​ listen 6379; ​ proxy_connect_timeout 1s; ​ proxy_timeout 3s; ​ proxy_pass redis; } } 6.2.3 redis配置[root@db01 /opt/redis_6381/conf]# cat /opt/redis_6381/conf/redis_6381.conf bind 10.0.0.51 port 6381 daemonize yes pidfile /opt/redis_6381/pid/redis_6381.pid logfile /opt/redis_6381/logs/redis_6381.log databases 16 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename redis_6381.rdb dir /data/redis_6381 6.2.4 模拟故障测试6.2.5 logstash配置6.2.6 使用supervisor批量管理多个logstash进程6.3 使用kafka作为缓存6.3.1 介绍6.3.2 zookeeper安装配置6.3.3 kafka安装配置6.3.4 kafka集群收发消息测试6.3.5 filebeat配置[root@kafka-175 conf.d]# cat /etc/filebeat/filebeat.yml filebeat.inputs: \- type: log enabled: true paths: \- /var/log/nginx/access.log json.keys_under_root: true json.overwrite_keys: true tags: ["access"] \- type: log enabled: true paths: \- /var/log/nginx/error.log tags: ["error"] setup.template.settings: index.number_of_shards: 3 setup.kibana: host: "192.168.10.66:5601" output.kafka: hosts: ["192.168.10.66:9092","192.168.47.176:9092","192.168.47.177:9092"] topic: elklog 6.3.6 logstash配置[root@kafka-175 conf.d]# cat /etc/logstash/conf.d/kafka.conf input{ kafka{ bootstrap_servers=>"192.168.10.66:9092" topics=>["elklog"] group_id=>"logstash" codec => "json" } } filter { mutate { convert => ["upstream_time", "float"] convert => ["request_time", "float"] } } output { if "access" in [tags] { elasticsearch { ​ hosts => "http://localhost:9200" ​ manage_template => false ​ index => "nginx_access-%{+yyyy.MM.dd}" } } if "error" in [tags] { elasticsearch { ​ hosts => "http://localhost:9200" ​ manage_template => false ​ index => "nginx_error-%{+yyyy.MM.dd}" } } } 第7章 配置logstash同步mysql数据略第8章 kibana画图展示略第9章 grafana画图展示除了kibana外，grafana也支持从es调取数据并展示https://grafana.com/docs/features/datasources/elasticsearch/#using-elasticsearch-in-grafana第10章 如何在公司推广ELK项目如何在公司推广ELK的项目1.优先表达出对其他人带来的便利和好处- 领导- 开发- 测试- DBA-- 以后你自己相查什么数据都可以直接查-- 以前插个日志运维得查10分钟，现在你只要点几下鼠标就ok了-- 我专门为你们部门定制了一个图形面板，你看看效果，有啥不满意的尽管说，我优先给你们部门解决2.对于运维来说，json日志更友好- 告诉领导，json格式更友好，做出测试环境，并给领导演示json格式优点- 提前统计好到底需要收集哪些日志- 要求能转成json的就转成json- 自己改不了的，给领导说，让开发改成json格式- 那行，领导你看，如果不改成json，就只能是这个效果了，后续的新需求，可能就满足不了了- 并不是说所有日志，必须是json3.推广演示- 提前都准备好文档和ppt还有测试环境- 一定要对比传统分析日志和ELK之后带来的巨大改变第11章 面试问题[A1]ELK每个组件都需要JAVA环境[A2]搭建群集一定要同步时间[A3]数据库存储目录[A4]日志文件存储位置[A5]锁定内存[A6]监听地址，最好添加上本机地址[A7]监听端口[A8]配置filebeat支持json格式传输到Es[A9]修改索引名称，推荐以月份结尾，因为Kibana支持月份[A10]关闭默认模板索引[A11]引用设置索引[A13]定义JSON键值对，使得ES读数据更加明显索引更加奥里给[A14]定义错误日志存放目录，tags指定下方可指定条件，可以是键值里得任何一种。[A15]当tags是error的时候收集日志简直不要奥里给[A16]如果只监听一个服务不用添加条件：定义条件[A17]不用纠结每添加一种服务就要该名称 只要之前改过，就可以不用修改就可以使用