ELK+FileBeat

日志服务(EFK)

基于Elasticssesarch,logstash,filebeat,Kibana

filebeat(日志数据采集器) -> logstash:5044(搜集日志) -> es:9200(存储日志) -> kibana:5601(查询和可视化)

1. ELK

在开源的日志管理方案中,最出名的莫过于 ELK 了。ELK 是三个软件的合称:Elasticsearch、Logstash、Kibana。

Elasticsearch
一个近乎实时查询的全文搜索引擎。Elasticsearch 的设计目标就是要能够处理和搜索巨量的日志数据。

Logstash
读取原始日志,并对其进行分析和过滤,然后将其转发给其他组件(比如 Elasticsearch)进行索引或存储。Logstash 支持丰富的 Input 和   
Output 类型,能够处理各种应用的日志。

Kibana
一个基于 JavaScript 的 Web 图形界面程序,专门用于可视化 Elasticsearch 的数据。Kibana 能够查询 Elasticsearch 并通过丰富的图表展 
示结果。用户可以创建 Dashboard 来监控系统的日志。
Logstash 负责从各个 Docker 容器中提取日志,Logstash将日志转发到 Elasticsearch 进行索引和保存,Kibana 分析和可视化数据。

docker中已经存在ELK的镜像,直接拉取即可.查询docker中ELK镜像: 
docker search elk
 //  拉取sebp/elk:700  
docker pull sebp/elk:700
 //  查看所有的镜像发现elk已存在  
docker images
容器启动后 ELK 各组件将分别监听如下端口:  
5601 – Kibana web 接口  
9200 – Elasticsearch JSON 接口  
5044 – Logstash 日志接收接口  

[注:](1)启动时出现错误:

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

因为vm.max_map_count至少需要262144,执行命令(这个为临时解决方法,重启虚拟机会失效)

sysctl -w vm.max_map_count=262144

永久解决办法为/etc/sysctl.conf文件最后添加一行:vm.max_map_count=262144重启虚拟机
(2)如果出现Starting Elasticsearch Server elk | …fail! 解决方法为将等待秒数为Elasticsearch开始Logstash和/或Kibana前将上升,运行命令

sudo docker run -e ES_CONNECT_RETRY = 300 -p 5602:5601 -p 9203:9200 -p 5044:5044 -it --name elk sebp/elk //当前默认端口被占用,映射其他宿主机端口,确保当前的端口没有被占用且外部可以访问

如果出现了上述中没有出现的错误,请参考 示例 中的建议
访问浏览器 http://host-ip:5601

运行时访问浏览器可能会出现Kibana server is not ready yet,很大部分原因是浏览器没有反应过来,重新刷新浏览器
当前 Kibana 没有可显示的数据,因为当前 Elasticsearch 还没有任何日志数据。
命令行:

docker search elk  //查询elk
docker pull sebp/elk:700  //拉取elk镜像
docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 --name elk sebp/elk:700 //运行elk容器

2.Filebeat

ELK 提供了一个配套小工具 Filebeat,它能将指定路径下的日志文件转发给 ELK。同时 Filebeat 很聪明,它会监控日志文件,当日志更新时,
Filebeat 会将新的内容发送给 ELK。启动Filebeat时,它会启动一个或多个查找器,查看你为日志文件指定的本地路径。
因为elk我们安装的是7.0.0的版本,所以filebeat最好版本保持一致,以避免出现有些不必要的错误。

1.docker环境安装

下载filebeat压缩包并且安装,在这里可以采取几种方式,我在这里使用的是rpm,具体方式可以去filebeat官网上查询 [官方文档] (https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-installation.html)我使用的是rpm方式
命令行:

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.0.0-x86_64.rpm  //拉取filebeat
rpm -vi filebeat-7.0.0-x86_64.rpm //安装filebeat

配置filebeat配置文件为 /etc/filebeat/filebeat.yml
进入filebeat文件夹,修改filebeat.yml文件,这里采用vi命令,进入配置文件后编辑,vi命令的用法可具体自我进行百度

enabled:false
path:
- 自己想收集日志的路径

使用方式:.netCore,framework同样适用,将项目部署到docker中,将项目生成的日志文件目录配置到filebeat.yml中即可

2.windows环境安装

在filebeat官方网站下载filebeat-7.0.0-windows-x86_64.zip,解压后,修改filebeat.yml配置文件,与docker中filebeat.yml配置一致,在当前目录打开cmd运行以下 命令启动filebeat

filebeat -e -c filebeat.yml 

[注]:当前配置为日志发送至logstash,但是启动filebeat后发现日志收集完成连接logstash输出管道已经建立成功但是在es中没有新的索引(直接发送至es可以查看到索引,排查出原因是因为没有读取到最新的配置文件(因为我修改了filebeat.yml),一直采用的是第一次的配置文件,所以有无索引或者索引有误应该是这个原因引起的(我将整个文件夹删除然后重新安装启动之后索引正常),解决方法为采用命令行停止此进程,重新启动filebeat

taskkill /f /t /im filebeat.exe

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OuYgMzH7-1597893761689)(uploads/58c0ddbd52fc0c51b566625b5308827c/image.png)]

使用方式:.netCore,framework项目同样适用,在windows安装filebeat后,将项目生成的日志文件目录配置到filebeat.yml中即可

3.filebeat发送日志方式

(1)filebeat直接将日志发送给 Elasticsearch 进行索引和保存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LbuTKoK7-1597893761692)(uploads/c90f246448d4e0740dbdc3f515261c0b/image.png)]
(2)filebeat发送给 Logstash
filebeat可以先发送给 Logstash 进行分析和过滤,然后由 Logstash 转发给 Elasticsearch。将filebeat.yml其他的output注释掉,将logstash释放进行配置

然后修改Logstash配置文件,执行以下命令,并且删除ssl

   docker exec -it elk bash //进入elk容器
   vi /etc/logstash/conf.d/02-beats-input.conf //进入logstash配置文件

修改配置完成后,重启filebeat,并且查看启动状态

    docker restart elk 
    systemctl restart filebeat.service
    systemctl status filebeat.service   

查看es索引,验证filebeat

curl 'localhost:9200/_cat_indices?v'

不难发现filebeat当前并未将日志文件发送成功,只存在两个系统级索引,再次排查filebeat状态时发现,在未修改filebeat.yml配置文件时,已经将filebeat启动,导致发送日志失败,将fiebeat重启(记得重启,记得重启,记得重启重要的事情说三遍,一定要重启!!!)并查看其状态,并查看es索引

发现索引已存在,现在去配置一个index pattern告诉 Kibana 查询和分析 Elasticsearch 中的哪些日志。访问kibana 指定 index pattern 为 filebeat-*,这与 Elasticsearch 中的 index前缀一致。
(3)同一服务器下不同目录下filebeat收集日志文件
修改filebeat.yml配置文件(为什么要使用一个配置文件监控多个文件? 因为filebeat 只能起一个进程。) 为了lostash能区分不同目录发过来的日志,我们在fileds下自定义log_source属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UCWq2EVj-1597893761718)(uploads/b5b2da53376fdb5a06d63426ce82474c/image.png)]

修改logstash发送至es的配置文件,先进入容器内查看logstash的配置文件

   docker exec -it elk bash  
   ll /etc/logstash/conf.d/

进入配置文件后发现配置文件中有一个输出文件 ,文件名为30-ouput.conf 修改此文件
重启elk与filebeat,查看filebeat状态
打开kibana或者使用命令行查看索引,发现索引已存在,输出索引为自定义[log_source]-*
[注意]:在此次采集日志文件过程中本应该输入2个不同的日志索引,根据我所设置的[fileds][log_source]应该应该输出两个不同的索引,但在es中只发现一个索引,我首先查看filebeat的状态,发现输入去确实为两个,但是日志文件却只有后读取的,经过排查之后发现是第一个日志路径下并无日志所以无法创建索引,在配置中一定要保证日志目录是准确的
(4)不同一服务器下filebeat收集日志文件
在另一台服务器上安装filebeat,采用上述的安装方式将输出logstash或es的地址改为你想发送的即可

3. .netCore3.1收集日志

建立项目(项目类型不限制,我采取的demo为web appliaction)
**(1)直接发送至es **
serilog收集日志,将日志发送至es
在Startup构造中加入如下代码

 public Startup(IConfiguration configuration)
        {
            Log.Logger = new LoggerConfiguration()
                        .Enrich.FromLogContext()
                        // 最小的日志输出级别
                        .MinimumLevel.Debug()
                         .WriteTo.Elasticsearch(
                         new ElasticsearchSinkOptions(new Uri("http://ip:port"))
                         {
                             MinimumLogEventLevel = LogEventLevel.Verbose,
                             AutoRegisterTemplate = true,
                             IndexFormat = "Api1-{0:yyyy-MM-dd}",// es index模板
                         })
                         .CreateLogger();

            Configuration = configuration;
        }
 //在Configure中添加Serilog
 loggerFactory.AddSerilog();

访问kibana,刚刚自定义的索引已经存在

(2)本地生成日志文件使用filebeat收集发送
Serilog将日志写入.txt文件中

public Startup(IConfiguration configuration)
        {
            Log.Logger = new LoggerConfiguration()
                        .Enrich.FromLogContext()
                        // 最小的日志输出级别
                        //.MinimumLevel.Debug()
                        //.WriteTo.Elasticsearch(
                        // new ElasticsearchSinkOptions(new Uri("http://ip:port"))
                        // {
                           //  MinimumLogEventLevel = LogEventLevel.Verbose,
                           //  AutoRegisterTemplate = true,
                           // IndexFormat = "Api1-{0:yyyy-MM-dd}",// es index模板
                         // })
                         //将日志保存到文件中(两个参数分别是日志的路径和生成日志文件的频次,当前是一天一个文件)
                         .WriteTo.File(Path.Combine("logs", @"log.txt"), rollingInterval: RollingInterval.Day)
                         .CreateLogger();

            Configuration = configuration;
        }

filebeat收集日志文件并发送,参考上文中filebeat读取文件过程
(3)docker部署项目filebeat收集特定容器日志
在建立初始化项目时启动docker会生成DockerFile文件(无文件类型),或者是初始化时没有启动docker自己后续建一个DockerFile文件

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base  //基于来构建镜像
WORKDIR /app  //设置工作目录为 '/app' 文件夹,即容器启动默认的文件夹


COPY . /app //拷贝项目文件夹中的所有文件到docker容器中的app文件夹 这里是两个参数

EXPOSE 8020 //设置Docker容器对外暴露端口

ENTRYPOINT ["dotnet", "ELK-filebeat.dll"] //使用'ELK-filebeat.dll'来运行应用程序

[注]:容器外设置端口为8020 但在项目部署成功后,容器对外端口默认却是80,暂时没排查出原因

项目建立成功后,将项目发布,在docekr中建立文件夹可与本地发布项目文件夹同名也可自定义,将发布文件下的文件全部上传至docker下刚建立的文件下 dockerfile文件必不可少 接下来进入此文件夹运行以下命令,打包生成镜像

docker build -t [image name]:[version] //打包生成镜像

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pUW7iUlw-1597893761735)(uploads/df92d5c13cbefd77ff1b8eb5f1949e12/image.png)]
运行容器

docker run --name [CONTAINER NAME] -d -p [port]:80 [image name]:[version]

版权声明:本文为justinacy原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。