asp.net core项目集成OpenTelemetry输出到OpenObserve进行可观测性处理
一、安装OpenObserve和Otel-collector
使用docker-compose 安装
记得替换下USER_MAIL xxx@xx.com和PASSWORD xxx
这里解释下为啥要用named volume来映射openobserve的data目录,因为目前版本(0.7.2)在windows的docker desktop里使用会有bug,导致stream无法正确写入文件持久化,一直在生成新的stream文件,而使用named volume则正常,详情请见issue
openobserve占用了5080(http)、5081(grpc)两个端口
otel-collector占用了5078和5079两个端口来作为对外提供服务的入口,后边的配置会有解释,其他端口有注释这里就不赘述了
新建一个openobserve目录,新建docker-compose.yaml文件,内容如下
version: '3'
services:
main:
image: openobserve/openobserve
volumes:
- ob-v:/data
ports:
- 5080:5080
- 5081:5081
environment:
- ZO_DATA_DIR=/data
- ZO_ROOT_USER_EMAIL=xxx@xx.com
- ZO_ROOT_USER_PASSWORD=xxxx
- TZ=Asia/Shanghai
restart: always
otel-collector:
image: otel/opentelemetry-collector-contrib
restart: always
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
ports:
- 1888:1888 # pprof extension
- 8888:8888 # Prometheus metrics exposed by the Collector
- 8889:8889 # Prometheus exporter metrics
- 13133:13133 # health_check extension
- 5078:5078 # OTLP gRPC receiver
- 5079:5079 # OTLP/2 gRPC receiver
#- 55679:55679 # zpages extension
volumes:
ob-v: {}
otel-collector-config配置
然后在当前目录新建otel-collector-config.yaml内容如下
指定了两个端点,5079和5078,让测试环境和生产环境走不同的流水线处理。otel-collector-config配置参考文档
记得替换下边的myapp为自己的项目名称
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:5079
otlp/2:
protocols:
grpc:
endpoint: 0.0.0.0:5078
processors:
batch:
exporters:
otlp:
endpoint: main:5081
headers:
Authorization: "Basic xxxxxx=="
organization: myapp_test
stream-name: default
tls:
insecure: true
otlp/2:
endpoint: main:5081
headers:
Authorization: "Basic xxxxxx=="
organization: myapp_production
stream-name: default
tls:
insecure: true
extensions:
health_check:
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
traces/2:
receivers: [otlp/2]
processors: [batch]
exporters: [otlp/2]
metrics/2:
receivers: [otlp/2]
processors: [batch]
exporters: [otlp/2]
logs/2:
receivers: [otlp/2]
processors: [batch]
exporters: [otlp/2]
然后使用命令行运行docker-compose up -d
浏览器访问 服务器ip:5080, 用户名和密码是上边设置的邮箱和密码
点击左侧采集--Trace(OpenTelemetry)复制其中的Authorization: 后边的部分,替换otel-collector-config.yaml中的Basic xxxxxx==
最后执行docker-compose restart
重启容器完成配置
二、asp.net core项目增加OpenTelemetry导出
引用OpenTelemetry Nuget包
在web api项目的csproj文件中增加以下nuget包引用
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.7.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.7.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.7.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.8" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.7.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.5.1" />
在appsettings.json中配置启用开关
"OpenTelemetry": {
"ServiceName": "UserService",
"EndPoint": "http://192.168.1.101:5079",
"Enable": true
}
其中ServiceName是该web api项目名称,EndPoint是otel-collector的一个grpc端点
比如测试环境的项目使用了5079端口,那生成环境就改为5078端口,如果还有演示环境、预发布环境之类的就继续在配置里增加端口
代码中配置启用Logging Metrics Traces
配置Logging导出
由于ConfigureLogging方法是IHostBuilder的扩展方法,所以只能在CreateDefaultBuilder这里调用
Host.CreateDefaultBuilder(args)
.ConfigureLogging((c,l) =>
{
if (bool.TryParse(c.Configuration["OpenTelemetry:Enable"], out var e) && e)
{
l.AddOpenTelemetry(logging =>
logging.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(c.Configuration["OpenTelemetry:ServiceName"]))
.AddOtlpExporter(o =>
{
o.Endpoint = new Uri(c.Configuration["OpenTelemetry:Endpoint"]);
}));
}
})
配置 Tracing和Metrics导出
在有IServiceCollection的地方执行AddOpenTelemetry扩展方法
if (bool.TryParse(_appConfiguration["OpenTelemetry:Enable"], out var otelEnable) && otelEnable)
{
services
.AddOpenTelemetry()
.ConfigureResource(builder => builder
.AddService(serviceName: _appConfiguration["OpenTelemetry:ServiceName"], serviceInstanceId: Environment.MachineName))
.WithTracing(builder => builder
.SetSampler(new AlwaysOnSampler())
.AddEntityFrameworkCoreInstrumentation(options => options.SetDbStatementForText = true)
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation(options =>
{
options.RecordException = true;
})
.AddOtlpExporter(o =>
{
o.Endpoint = new Uri(_appConfiguration["OpenTelemetry:Endpoint"]);
})
)
.WithMetrics(builder => builder
.AddRuntimeInstrumentation()
.AddAspNetCoreInstrumentation()
.AddOtlpExporter(o =>
{
o.Endpoint = new Uri(_appConfiguration["OpenTelemetry:Endpoint"]);
})
);
}
最后项目运行起来在OpenObserve的数据流中有对应数据就算成功了