當前位置: 妍妍網 > 碼農

asp.net core計畫整合OpenTelemetry輸出到OpenObserve進行可觀測性處理

2024-05-20碼農

雲原生時代的數據監控與管理要求更為靈活、高效且能夠輕松應對PB級別的數據規模。為此,一款名為OpenObserve(簡稱O2)的雲原生可觀測性平台應運而生,它為日誌、指標、跟蹤、分析以及RUM(即時使用者監控 - 效能、錯誤、會話回放)提供了專業解決方案。

不同於Elasticsearch,後者需要使用者對眾多設定進行了解和調優,OpenObserve更加簡潔易操作,可以在不到2分鐘的時間內部署啟用。

OpenObserve可以無縫替代Elasticsearch,適用於那些透過API攝取數據並執行搜尋的使用者群體。而且,OpenObserve內建使用者介面,免去了額外安裝的需要。

根據我們將生產Kubernetes集群的日誌同時推播到Elasticsearch和OpenObserve的結果,使用OpenObserve可以將日誌儲存成本相比於Elasticsearch減少約140倍。

一、安裝OpenObserve和Otel-collector

使用docker-compose 安裝

記得替換下USER_MAIL [email protected]和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/openobserve
volumes:
-ob-v:/data
ports:
-5080:5080
-5081:5081
environment:
-ZO_DATA_DIR=/data
-[email protected]
-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"], outvar 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"], outvar 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的數據流中有對應數據就算成功了