asp.netcore项目集成OpenTelemetry输出到OpenObserve进行可观测性处理

程序员有二十年 2024-05-20 19:39:26

云原生时代的数据监控与管理要求更为灵活、高效且能够轻松应对PB级别的数据规模。为此,一款名为OpenObserve(简称O2)的云原生可观测性平台应运而生,它为日志、指标、跟踪、分析以及RUM(实时用户监控 - 性能、错误、会话回放)提供了专业解决方案。

不同于Elasticsearch,后者需要用户对众多设置进行了解和调优,OpenObserve更加简洁易操作,可以在不到2分钟的时间内部署启用。

OpenObserve可以无缝替代Elasticsearch,适用于那些通过API摄取数据并执行搜索的用户群体。而且,OpenObserve自带用户界面,免去了额外安装的需要。

根据我们将生产Kubernetes集群的日志同时推送到Elasticsearch和OpenObserve的结果,使用OpenObserve可以将日志存储成本相比于Elasticsearch减少约140倍。

一、安装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:write stream to disk failed · Issue #2166 · openobserve/openobserve (github.com)

openobserve占用了5080(http)、5081(grpc)两个端口otel-collector占用了5078和5079两个端口来作为对外提供服务的入口,后边的配置会有解释,其他端口有注释这里就不赘述了

新建一个openobserve目录,新建docker-compose.yaml文件,内容如下

version: '3'services:main:image: openobserve/openobservevolumes:- ob-v:/dataports:- 5080:5080- 5081:5081environment:- ZO_DATA_DIR=/data- ZO_ROOT_USER_EMAIL=xxx@xx.com- ZO_ROOT_USER_PASSWORD=xxxx- TZ=Asia/Shanghairestart: alwaysotel-collector:image: otel/opentelemetry-collector-contribrestart: alwaysvolumes:- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yamlports:- 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 extensionvolumes:ob-v: {}otel-collector-config配置

然后在当前目录新建otel-collector-config.yaml内容如下指定了两个端点,5079和5078,让测试环境和生产环境走不同的流水线处理。otel-collector-config配置参考文档记得替换下边的myapp为自己的项目名称

receivers:otlp:protocols:grpc:endpoint: 0.0.0.0:5079otlp/2:protocols:grpc:endpoint: 0.0.0.0:5078processors:batch:exporters:otlp:endpoint: main:5081headers:Authorization: "Basic xxxxxx=="organization: myapp_teststream-name: defaulttls:insecure: trueotlp/2:endpoint: main:5081headers:Authorization: "Basic xxxxxx=="organization: myapp_productionstream-name: defaulttls:insecure: trueextensions: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"]); }) ); }C#复制全屏

最后项目运行起来在OpenObserve的数据流中有对应数据就算成功了

0 阅读:0

程序员有二十年

简介:感谢大家的关注