上帝视角——使用ELK APM 对 asp.net core做性能、链路监控
前言
使用elk apm对 .net core应用做监控,有两种方式:一种是通过引用官方的nuget包;另一种是使用Profiler Auto instrumentation。本篇假设你已经配置好了ES、kibana、Apm等基础环境,着重在代码及系统配置层面做介绍,欢迎大家提出问题和意见。
所使用环境
系统 | 版本 |
---|---|
.net core | 6.0 |
linux | ubuntu 20.4 |
docker | - |
Elasticsearch | 8.3.2 |
Kibana | 8.3.2 |
Apm-server | 8.3.2 |
方法一:引用Elastic.Apm.NetCoreAll包
备注:官方还有一个包:Elastic.Apm.AspNetCore,可以理解为all包含了所有,使用UseElasticApm需要指定想要的subscriber,简单起见,这里直接使用NetCoreAll安装包。
引用包的方式简单,这也是笔者第一次尝试的方式,步骤如下:
- 安装apm依赖包,选择合适的版本即可,也可以直接下载最新。
Install-Package Elastic.Apm.NetCoreAll -Version 1.25.0
- 在appsettings.json中添加logLevel节点,新增"Elastic.Apm": "None",如果不加此节点会生成大量的系统日志,造成磁盘空间压力,这里我们直接关闭,也可以修改为其它日志等级。
"LogLevel": {
"Elastic.Apm": "None"
}
- 在appsettings.json中继续添加 ElasticApm节点,这里面填的是apm服务器的相关信息 ,注意,如果你在apm中配置了token,这里需要带上token。
{
"ElasticApm": {
"ServerUrls": "http://10.10.1.51:8200", //apm服务器地址
"SecretToken": " "
"ServiceName": "platform", //应用名称
"Environment": "production", // 生产环境:production,测试环境:test, 开发环境: development
}
}
- 在startup中添加apm服务,注意必须需要放在第一行,否则代理将无法正确测量请求的时间,并且代理可能会错过完整的请求。
The app.UseAllElasticApm(...) line must be the first line in the Configure method, otherwise the agent won’t be able to properly measure the timing of your requests, and complete requests may potentially be missed by the agent.
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAllElasticApm(Configuration);
//…rest of the method
}
//…rest of the class
}
如果一切顺利的话,至此就完成了,我们会在kibana中看到已经监控到的应用程序,也能看到系统、应用接口等各种性能指标。
但是,往往事情没有想象的那个顺利,我们在点进一个接口查看trace数据时,发现了一个问题:trace中没有显示sql语句、redis调用、kafka等依赖项的数据,说好的全链接跟踪呢! 比如下图所示的这里应该要显示我的sql语句才对呀。(注:笔者所在的公司使用的pgsql)
排查原因:难道是pg配置的不对?apm没开启pg相关监控?redis还需要额外的配置?这里省略尝试的各种可能性,最终在官方的论坛发现了一个国际友人的提问:https://discuss.elastic.co/t/not-creating-spans-for-postgresql-query-running-on-apm-net-6-agent/309274 ,这不是巧了吗,这不就是我遇到的问题,很幸运,该帖子下官方做了回答:
这不是坑人么!这么重要的说明为啥没有放在文档最显眼的位置。既然知道了问题,迫不及待,让我们赶紧尝试下这种方式。
方法二:Profiler Auto instrumentation
简单来说就是在.net的进程上附加一个探针,收集span数据,具体如何做呢,官网的文章介绍了在不同的环境下的配置方法,你可以不修改任何代码就可以对.net进程进行监控,也可以和方法一结合使用,本文分别介绍在linux环境下和docker容器中的配置方法。
linux安装
- 从官网的链接中下载探测包,并放到主机的某个目录下。如下图的示例中就是放到了“/db1/elastic-apm”下。注意:如果代码中已经引用了Elastic.Apm.NetCoreAll包,那么这里下载的探测包需要和程序中引用的包版本是一致的。
- 设置环境变量,注意设置的环境变量需要让程序能访问到,最好在启动脚本里添加,随应用一起启动,建议代码中通过控制台打印出环境变量的值。
Environment=CORECLR_ENABLE_PROFILING=1
Environment=CORECLR_PROFILER={FA65FE15-F085-4681-9B20-95E04F6C03CC}
Environment=CORECLR_PROFILER_PATH="/db1/elastic-apm/libelastic_apm_profiler.so"
Environment=ELASTIC_APM_PROFILER_HOME="/db1/elastic-apm"
Environment=ELASTIC_APM_PROFILER_INTEGRATIONS="/db1/elastic-apm/integrations.yml"
Environment=ELASTIC_APM_SERVER_URL="http://10.10.1.51:8200"
Environment=ELASTIC_APM_PROFILER_LOG_DIR="/db1/elastic-apm/logs"
#Environment=ELASTIC_APM_PROFILER_LOG="info"
docker安装(多阶段构建)
stage0:
#定义全局的版本变量,注意多阶段使用到的时候需要定义ARG AGENT_VERSION来获取这个变量的值
ARG AGENT_VERSION=1.25.0
stage1:
FROM alpine:latest AS build
ARG AGENT_VERSION
# 替换镜像源为阿里云镜像源(也可以换成别的镜像源,这一步很重要,官网没有写,但是不要忽略,否则会遇到一些莫名其妙的报错)
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list
WORKDIR /source
# install unzip
RUN apk update && apk add zip curl
# 地址从https://github.com/elastic/apm-agent-dotnet/releases取
RUN curl -L -o elastic_apm_profiler_${AGENT_VERSION}.zip https://github.com/elastic/apm-agent-dotnet/releases/download/v${AGENT_VERSION}/elastic_apm_profiler_${AGENT_VERSION}.zip && \
unzip elastic_apm_profiler_${AGENT_VERSION}.zip -d /elastic_apm_profiler_${AGENT_VERSION}
stage2:
#定义变量获取stage0中的全局变量
ARG AGENT_VERSION
#从stage1构建结果的路径中复制elastic_apm_profiler_${AGENT_VERSION}文件夹到目标文件夹
COPY --from=build /elastic_apm_profiler_${AGENT_VERSION} /opt/elastic_apm_profiler
#设置环境变量
ENV CORECLR_ENABLE_PROFILING=1
ENV CORECLR_PROFILER={FA65FE15-F085-4681-9B20-95E04F6C03CC}
ENV CORECLR_PROFILER_PATH=/elastic_apm_profiler/libelastic_apm_profiler.so
ENV ELASTIC_APM_PROFILER_HOME=/elastic_apm_profiler
ENV ELASTIC_APM_PROFILER_INTEGRATIONS=/elastic_apm_profiler/integrations.yml
ENTRYPOINT ["dotnet", "your-application.dll"]
验证配置是否正确(这一步很重要,有时你以为设置成功了,其实没有设置成功)
容器中验证
- 查看拷贝的文件夹、进入容器中查看环境变量
效果
一切设置完毕,激动人心的时刻,看最终效果:
通过这种方式可以收集到NpgsqlCommand、Kafka、MQ等数据。
注意事项:
-
遇到一个错误 failed size validation: 8049 != 7726: failed precondition,原因是没有设置国内镜像源,设置下即可。
-
elastic_apm_profiler的地址不同版本对应的后缀是不一样的,可以从release中查看下载链接,不过因为众所周知的原因可能在容器中下载不下来,你可以直接从github中下载下来复制到镜像路径中即可,如:
COPY /elastic_apm_profiler_1.25.0-linux-x64 /db/recloudtools/elastic_apm_profiler