ElasticSearch+Fluentd+Kibana搭建日志系统EFK
引言
学了一个多月的 asp.net core mvc 微服务,对于微服务来说,一个可靠的日志系统对于服务跟踪和查错报警和性能监控是必不可少的。那么目前业界普遍采用的是ELK(ElasticSearch+Logstash+Kibana)来搭建,而Fluentd可以说是Logstash的一个变种。fluentd的特点是使用JSON进行统一日志记录、采用可插拔架构,所需资源较少并且高可用。
Elasticsearch是Elastic Stack核心的分布式搜索和分析引擎。Logstash和Beats有助于收集,聚合和丰富您的数据并将其存储在Elasticsearch中。Kibana能够以交互方式探索,可视化和分享数据,并管理和监控堆栈。Elasticsearch是索引,搜索和分析魔术发生的地方。
详细说明可以参考官网文档:
https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-intro.html
https://www.elastic.co/guide/en/kibana/current/introduction.html
接下来就具体来安装和运行EFK吧,使用docker容器进行安装部署,具体步骤如下。
一、Docker安装ElasticSearch
sysctl -w vm.max_map_count=262144
docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms256m -Xmx256m" docker.elastic.co/elasticsearch/elasticsearch:7.3.0
二、Docker安装’Kibana
docker pull docker.elastic.co/kibana/kibana:7.3.0 docker network create search docker network connect search ElasticSearchNameOrId docker run -d --name kibana --network search -p 5601:5601 docker.elastic.co/kibana/kibana:7.3.0
三、CentOS 7 安装 Fluentd
具体的Fluentd安装配置可以查看官方文档:https://docs.fluentd.org/
- 安装前需要检查下系统的时间和最大的文件描述符大小:
- 检查时间
date #查看时间
ntpdate -u pool.ntp.org #从ntp服务器同步时间
2. 使用命令 ulimit -n 检查文件描述符的大小,如果查询的结果是1024,则需要在 /etc/security/limits.conf 文件添加下面的几行命令,然后重启电脑
ulimit -n
root soft nofile 65536 root hard nofile 65536 * soft nofile 65536 * hard nofile 65536
3. 对于由许多Fluentd实例组成的高负载环境,请将下面的参数添加到/etc/sysctl.conf文件中。通过sysctl -p或重新启动节点以使更改生效。
net.core.somaxconn = 1024 net.core.netdev_max_backlog = 5000 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_wmem = 4096 12582912 16777216 net.ipv4.tcp_rmem = 4096 12582912 16777216 net.ipv4.tcp_max_syn_backlog = 8096 net.ipv4.tcp_slow_start_after_idle = 0 net.ipv4.tcp_tw_reuse = 1 net.ipv4.ip_local_port_range = 10240 65535
- 通过RPM包安装Fluentd
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh #安装
systemctl start td-agent.service #启动
systemctl status td-agent.service #查看运行状态
安装完成后安装文件的目录在/opt/td-agent中,日志文件保存在/var/log/td-agent/td-agent.log中,配置文件在/etc/td-agent/td-agent.conf中。
四、在Asp.Net Core中使用Serilog结构化日志组件来记录日志
与.NET的许多其他库一样,Serilog为文件,控制台和其他地方提供诊断日志记录。它易于设置,具有干净的API,并且可以在最新的.NET平台之间移植。具体介绍可在官网详细了解: https://serilog.net/,其在Github上的地址为:https://github.com/serilog。
这里我新建了一个asp.net core web项目 HelloApi 。为其添加如下Serilog的Nuget包
Install-Package Serilog Install-Package Serilog.AspNetCore Install-Package Serilog.Settings.Configuration Install-Package Serilog.Sinks.Console Install-Package Serilog.Sinks.ElasticSearch
Serilog的使用还是挺简单的,在appsetttings.json中添加如下配置
"Serilog": { "Using": [ "Serilog.Sinks.Console" ], "MinimumLevel": "Verbose", "WriteTo": [ { "Name": "Console" } ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], "Destructure": [ { "Name": "ToMaximumDepth", "Args": { "maximumDestructuringDepth": 4 } }, { "Name": "ToMaximumStringLength", "Args": { "maximumStringLength": 100 } }, { "Name": "ToMaximumCollectionCount", "Args": { "maximumCollectionCount": 10 } } ], "Properties": { "Application": "User.Api" } }
并且在Program.cs中添加如下的UseSerilog,当然更详细全面的配置还需要参考官网,这里就只使用简单的配置即可。
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseSerilog((context, logConfigure) => { logConfigure.ReadFrom.Configuration(context.Configuration); logConfigure.WriteTo.Console(new ElasticsearchJsonFormatter()); }) .UseUrls("http://+:8081");
接着运行HelloApi项目,可以在控制台中看到日志输出,其中以json格式输出并且还有颜色提示。
五、在Docker中运行Asp.Net Core项目,并指定日志输出到Fluentd中
- 为HelloApi添加Dockerfile文件
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base WORKDIR /app EXPOSE 8081 FROM microsoft/dotnet:2.2-sdk AS build WORKDIR /src COPY ["HelloApi/HelloApi.csproj", "HelloApi/"] RUN dotnet restore "HelloApi/HelloApi.csproj" COPY . . WORKDIR "/src/HelloApi" RUN dotnet build "HelloApi.csproj" -c Release -o /app FROM build AS publish RUN dotnet publish "HelloApi.csproj" -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "HelloApi.dll"]
- 将HelloApi项目拷贝到我的虚拟机上,使用docker构建镜像
docker build -t jesen/helloapi:dev .
- 修改fluentd的配置文件,然后通过命令 systemctl restart td-agent.service 重新启动服务
<source> @type forward port 24224 bind 0.0.0.0 format json key_name log </source> <filter> @type parser format json key_name log </filter> <match **> @type elasticsearch host localhost port 9200 logstash_format true </match>
- 运行helloapi的docker镜像,指定fluentd为其日志驱动器
docker run -p 8081:8081 --log-driver=fluentd --log-opt fluentd-address=172.16.129.170:24224 --name helloapi jesen/helloapi:dev
六、在Kibana中显示日志
当完成了上面的配置和运行helloapi镜像后,可以访问 http://172.16.129.170:5601/查看Kibana。刚开始Kibana会要求创建索引,按要求创建后就可以查看到日志了,当索引字段发生变化时,可以通过刷新索引来重新创建索引,关于Kibana的详细配置可以查看官网:https://www.elastic.co/guide/en/kibana/current/settings.html
七、使用Docker添加 Nginx
docker run -d --name nginx --network search --log-driver=fluentd --log-opt fluentd-address=172.16.129.170:24224 -p 8080:8080 nginx
docker network inspect search
docker cp nginx:/etc/nginx . # docker cp 命令将容器nginx的/etc/nginx文件夹复制到当前文件夹下
在 nginx/conf.d中新建文件 helloapi.conf,内容如下:
server{ listen 8080; location / { proxy_pass http://helloapi:8081; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header x-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header x-Forwarded-Host $server_name; } }
然后将其复制回容器nginx中
docker cp . nginx:/etc/nginx
使用命令查看复制后的/etc/nginx/conf.d文件夹,其多了helloapi.conf
docker exec -it nginx bin/bash
接下来要做的就是重启nginx
docker restart nginx
将容器helloapi添加到search网络中
docker network connect search helloapi
使用 docker network inspect search 查看search详细信息,可以看到kibana、elasticsearch、nginx、helloapi都在search中
至此,可以在外部浏览器访问:http://172.16.129.170:8080通过nginx反向代理到HelloApi的站点了,同时也可以在kibana中看到访问日志多了Request.Path等信息
八、添加性能与正确性搜集等信息在kibana的dashboard中展示