Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

OpenTelemetryのzero-code計装を試している〜その2。.NET

前回のGoに引き続き、今度は.NETでのzero-code計装を試してみる。

kmuto.hatenablog.com

Debian GNU/Linux上に.NET 9環境をセットアップした。

.NETは完全初見なのだけど、Webサーバーは簡単に作れるらしいとのことで作成。

mkdir dotnet-web
cd dotnet-web
dotnet new web

これで各種ファイルが用意される。Program.csにすでにWebサーバーのコードが入っている。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

超簡単だな…! エラーを出すパターンをCoPilot受けながら適当に補完してみる。

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");
app.MapGet("/error", (HttpContext context) => throw new Exception("Error!"));
app.MapGet("/500", () => {
    return Results.Problem("Error!", statusCode: 500);
});

app.Run();

dotnet buildbin/Debug/net9.0/dotnet-webができた。

bin/Debug/net9.0/dotnet-webを実行し、curlなどでhttp://localhost:5000http://localhost:5000/errorhttp://localhost:5000/500にアクセスして結果を確認。

$ curl http://localhost:5000
Hello World!
$ curl http://localhost:5000/error
(何も出ないけどサーバー側は例外が出ている)
$ curl http://localhost:5000/500
{"type":"https://tools.ietf.org/html/rfc9110#section-15.6.1","title":"An error occurred while processing your request.","status":500,"detail":"Error!"}

アプリケーションができたので、.NET zero-code instrumentationに従ってzero-code計装をやってみる。

例のごとくOpenTelemetry Collectorをローカルで適当な設定で動かす。

receivers:
  otlp:
    protocols:
      http:

exporters:
  debug:
    verbosity: detailed

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [debug]

.NETのzero-code計装ライブラリのセットアップ。

curl -sSfL https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh -O
sh ./otel-dotnet-auto-install.sh
chmod +x $HOME/.otel-dotnet-auto/instrument.sh

現在のシェルに環境変数を取り込む。これで、今のシェル内で.NETアプリケーションを動かすとzero-code計装が有効な状態になっている。

. $HOME/.otel-dotnet-auto/instrument.sh

サービス名やバージョンを指定してアプリケーションを実行。

OTEL_SERVICE_NAME=dotnet-zerocode OTEL_RESOURCE_ATTRIBUTES=service.version=1.0.0 bin/Debug/net9.0/dotnet-web

これらはLinuxの例だけど、ドキュメントにはWindowsアプリケーション・Windowsサービス・ASP.NETでのやり方も書いてある。

ではcurlからアクセスして、Collectorにトレースが送られてくるのを見る。

2025-01-19T09:08:36.212+0900    info    Traces  {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 2}
2025-01-19T09:08:36.212+0900    info    ResourceSpans #0
Resource SchemaURL: 
Resource attributes:
     -> os.type: Str(linux)
     -> os.description: Str(Debian GNU/Linux 12 (bookworm))
     -> os.build_id: Str(6.1.0-30-amd64)
     -> os.name: Str(Debian GNU/Linux)
     -> os.version: Str(12)
     -> host.name: Str(...)
     -> host.id: Str(86fdb17091114232ba104aea4bc5250d)
     -> process.owner: Str(kmuto)
     -> process.pid: Int(175395)
     -> process.runtime.description: Str(.NET 9.0.1)
     -> process.runtime.name: Str(.NET)
     -> process.runtime.version: Str(9.0.1)
     -> container.id: Str(8dcad6c724a5)
     -> telemetry.distro.name: Str(opentelemetry-dotnet-instrumentation)
     -> telemetry.distro.version: Str(1.9.0)
     -> telemetry.sdk.name: Str(opentelemetry)
     -> telemetry.sdk.language: Str(dotnet)
     -> telemetry.sdk.version: Str(1.9.0)
     -> service.name: Str(dotnet-zerocode)
     -> service.version: Str(1.0.0)
ScopeSpans #0
ScopeSpans SchemaURL: 
InstrumentationScope Microsoft.AspNetCore 
Span #0
    Trace ID       : d28fbe5ac778ff1c7bc29adf76ad2d63
    Parent ID      : 
    ID             : 622c1673e23ecb0e
    Name           : GET /
    Kind           : Server
    Start time     : 2025-01-19 00:08:32.1050609 +0000 UTC
    End time       : 2025-01-19 00:08:32.1881126 +0000 UTC
    Status code    : Unset
    Status message : 
Attributes:
     -> server.address: Str(localhost)
     -> server.port: Int(5000)
     -> http.request.method: Str(GET)
     -> url.scheme: Str(http)
     -> url.path: Str(/)
     -> network.protocol.version: Str(1.1)
     -> user_agent.original: Str(curl/7.88.1)
     -> http.route: Str(/)
     -> http.response.status_code: Int(200)
Span #1
    Trace ID       : c64908bdcf00dc51d84bb946a55a6e30
    Parent ID      : 
    ID             : d999c17988b97b14
    Name           : GET /error
    Kind           : Server
    Start time     : 2025-01-19 00:08:34.8026373 +0000 UTC
    End time       : 2025-01-19 00:08:34.8154717 +0000 UTC
    Status code    : Error
    Status message : 
Attributes:
     -> server.address: Str(localhost)
     -> server.port: Int(5000)
     -> http.request.method: Str(GET)
     -> url.scheme: Str(http)
     -> url.path: Str(/error)
     -> network.protocol.version: Str(1.1)
     -> user_agent.original: Str(curl/7.88.1)
     -> error.type: Str(System.Exception)
     -> http.route: Str(/error)
     -> http.response.status_code: Int(500)
        {"kind": "exporter", "data_type": "traces", "name": "debug"}
2025-01-19T09:08:41.233+0900    info    Traces  {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1}
2025-01-19T09:08:41.233+0900    info    ResourceSpans #0
Resource SchemaURL: 
Resource attributes:
     -> os.type: Str(linux)
     -> os.description: Str(Debian GNU/Linux 12 (bookworm))
     -> os.build_id: Str(6.1.0-30-amd64)
     -> os.name: Str(Debian GNU/Linux)
     -> os.version: Str(12)
     -> host.name: Str(...)
     -> host.id: Str(86fdb17091114232ba104aea4bc5250d)
     -> process.owner: Str(kmuto)
     -> process.pid: Int(175395)
     -> process.runtime.description: Str(.NET 9.0.1)
     -> process.runtime.name: Str(.NET)
     -> process.runtime.version: Str(9.0.1)
     -> container.id: Str(8dcad6c724a5)
     -> telemetry.distro.name: Str(opentelemetry-dotnet-instrumentation)
     -> telemetry.distro.version: Str(1.9.0)
     -> telemetry.sdk.name: Str(opentelemetry)
     -> telemetry.sdk.language: Str(dotnet)
     -> telemetry.sdk.version: Str(1.9.0)
     -> service.name: Str(dotnet-zerocode)
     -> service.version: Str(1.0.0)
ScopeSpans #0
ScopeSpans SchemaURL: 
InstrumentationScope Microsoft.AspNetCore 
Span #0
    Trace ID       : bd5555309bda6d0a5c055169ee9f5749
    Parent ID      : 
    ID             : 8f2b25897bd33a16
    Name           : GET /500
    Kind           : Server
    Start time     : 2025-01-19 00:08:37.6004667 +0000 UTC
    End time       : 2025-01-19 00:08:37.6297872 +0000 UTC
    Status code    : Error
    Status message : 
Attributes:
     -> server.address: Str(localhost)
     -> server.port: Int(5000)
     -> http.request.method: Str(GET)
     -> url.scheme: Str(http)
     -> url.path: Str(/500)
     -> network.protocol.version: Str(1.1)
     -> user_agent.original: Str(curl/7.88.1)
     -> http.route: Str(/500)
     -> http.response.status_code: Int(500)
        {"kind": "exporter", "data_type": "traces", "name": "debug"}

なるほど、リソース情報もまるっと入ってきている。

設定を見ていると、環境変数か設定ファイルを使ってかなりいろいろとカスタマイズできそうで、充実しているな〜。