OpenTelemetryã®zero-codeè¨è£ ã試ãã¦ããããã®3ãJava/Kotlin
Goã.NETã¨ãã¦ãä»åã¯Javaã§ã®zero-codeè¨è£ ã®ãã©ã¤ã§ããã
kmuto.hatenablog.com kmuto.hatenablog.com
å ¬å¼ãµã¤ãã«ããã°ãJava Agentã使ãæ¹æ³ã¨ãSpring Boot starterã使ãæ¹æ³ãããã
ã¾ãã¯Java Agentã§è©¦ããã¨ã«ããã
Java Agentã®å ´åãã·ã³ãã«ã«opentelemetry-javaagent.jarãã¨ã¼ã¸ã§ã³ãçµã¿è¾¼ã¿ããã ãã§JVMããæ å ±ãã²ã£ã±ã£ã¦ãã¦ãããã
java -javaagent:path/to/opentelemetry-javaagent.jar -Dotel.service.name=your-service-name -jar myapp.jar
ãªãã»ã©ç°¡åãå¼æ°ã®ã»ãç°å¢å¤æ°ãããããã£ãã¡ã¤ã«ã§æå®ãããã¨ãã§ããã
ã§ããã£ããç´ ããç«ã¦ãããWebãµã¼ãã¼ã¨ãã¦sun.net.httpserver.HttpServer
ã使ã£ã¦ç«ã¦ãã®ã ãâ¦JVMã®ã¡ããªãã¯ã¯é£ã¶ãã®ã®ããã¬ã¼ã¹ãå
¨ç¶éãããªãã
ãµãã¼ãã©ã¤ãã©ãªã®å¯¾è±¡ã«ãªãã£ãããããªâ¦ã
æ¨æºã©ã¤ãã©ãªç¯çã ã¨Java Http Clientãloggingãããã®å¯¾å¿ãããã®ã ããWebãµã¼ãã¼ã ã¨çµå±KtorãSpringã«ãªãããã ã
Javaã¨ä¸è¨ã§è¡¨ãã«ã¯å¤§æããã«ãªã£ã¦ãã¾ããã®ã®ãKotlinã®Ktorã§è©¦ããã¨ã«ããã
Kotlinã¯ææ¸ç±å¶ä½ã§æ¤è¨¼ããã®ã«ä½¿ã£ããããã§ãå®å ¨ã«å¿å´ãã¨ã¯ãããå ¬å¼ãµã¤ããè¦ãªããé©å½ã«ãã£ããã§ããã
Project Generatorããktor-sample.zipããã¦ã³ãã¼ãããå±éããã
src/main/kotlin/Routing.kt
ã«/500
ã¨/error
ã®ãã³ãã©ã追å ããã
package com.example import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* fun Application.configureRouting() { routing { get("/") { call.respondText("Hello World!") } get("/500") { call.respondText("Error", status = io.ktor.http.HttpStatusCode.InternalServerError) } get("/error") { throw RuntimeException("Runtime Error") } } }
ãã«ããã¦ãæ£å¸¸ã«åä½ããã試ãã
./gradlew build java -jar build/libs/ktor-sample-all.jar
ãã¼ã8080ã§åãã¦ããã®ã§ãcurlããå¼ã³åºãã
$ curl http://localhost:8080 Hello World! $ curl http://localhost:8080/error ï¼ä½ãåºãªããã©ãµã¼ãã¼å´ã¯ä¾å¤ãåºã¦ããï¼ $ curl http://localhost:8080/500 Error
ãã¤ãã®ããã«OpenTelemetry Collectorãå®è¡ãã¦ããã
receivers: otlp: protocols: http: exporters: debug: verbosity: detailed service: pipelines: traces: receivers: [otlp] exporters: [debug]
ã§ã¯zero-codeè¨è£ ãæ³¨å ¥ããã
java -javaagent:./opentelemetry-javaagent.jar -Dotel.service.name=kotlin-zerocode -jar build/libs/ktor-sample-all.jar
ããã§å度curlã試ãã¦ã¿ãã¨ããã¬ã¼ã¹ãåºã¦ããã
2025-01-19T17:50:04.119+0900 info Traces {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1} 2025-01-19T17:50:04.119+0900 info ResourceSpans #0 Resource SchemaURL: https://opentelemetry.io/schemas/1.24.0 Resource attributes: -> host.arch: Str(amd64) -> host.name: Str(...) -> os.description: Str(Linux 6.1.0-30-amd64) -> os.type: Str(linux) -> process.command_args: Slice(["/usr/lib/jvm/java-17-openjdk-amd64/bin/java","-javaagent:./opentelemetry-javaagent.jar","-Dotel.service.name=kotlin-zerocode","-jar","build/libs/ktor-sample-all.jar"]) -> process.executable.path: Str(/usr/lib/jvm/java-17-openjdk-amd64/bin/java) -> process.pid: Int(349907) -> process.runtime.description: Str(Debian OpenJDK 64-Bit Server VM 17.0.13+11-Debian-2deb12u1) -> process.runtime.name: Str(OpenJDK Runtime Environment) -> process.runtime.version: Str(17.0.13+11-Debian-2deb12u1) -> service.instance.id: Str(0da10240-547e-4a45-b28c-6133d3ffe1b5) -> service.name: Str(kotlin-zerocode) -> telemetry.distro.name: Str(opentelemetry-java-instrumentation) -> telemetry.distro.version: Str(2.12.0) -> telemetry.sdk.language: Str(java) -> telemetry.sdk.name: Str(opentelemetry) -> telemetry.sdk.version: Str(1.46.0) ScopeSpans #0 ScopeSpans SchemaURL: InstrumentationScope io.opentelemetry.netty-4.1 2.12.0-alpha Span #0 Trace ID : 287f6d7cab81f813910f909ac1ff0570 Parent ID : ID : aac3e33359775de7 Name : GET / Kind : Server Start time : 2025-01-19 08:50:03.077627907 +0000 UTC End time : 2025-01-19 08:50:03.126250246 +0000 UTC Status code : Unset Status message : Attributes: -> network.peer.address: Str(127.0.0.1) -> server.address: Str(localhost) -> client.address: Str(127.0.0.1) -> url.path: Str(/) -> server.port: Int(8080) -> http.request.method: Str(GET) -> thread.id: Int(35) -> http.response.status_code: Int(200) -> http.route: Str(/) -> user_agent.original: Str(curl/7.88.1) -> network.peer.port: Int(34344) -> network.protocol.version: Str(1.1) -> url.scheme: Str(http) -> thread.name: Str(eventLoopGroupProxy-3-1) {"kind": "exporter", "data_type": "traces", "name": "debug"} 2025-01-19T17:50:39.123+0900 info Traces {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1} 2025-01-19T17:50:39.123+0900 info ResourceSpans #0 Resource SchemaURL: https://opentelemetry.io/schemas/1.24.0 Resource attributes: -> host.arch: Str(amd64) -> host.name: Str(...) -> os.description: Str(Linux 6.1.0-30-amd64) -> os.type: Str(linux) -> process.command_args: Slice(["/usr/lib/jvm/java-17-openjdk-amd64/bin/java","-javaagent:./opentelemetry-javaagent.jar","-Dotel.service.name=kotlin-zerocode","-jar","build/libs/ktor-sample-all.jar"]) -> process.executable.path: Str(/usr/lib/jvm/java-17-openjdk-amd64/bin/java) -> process.pid: Int(349907) -> process.runtime.description: Str(Debian OpenJDK 64-Bit Server VM 17.0.13+11-Debian-2deb12u1) -> process.runtime.name: Str(OpenJDK Runtime Environment) -> process.runtime.version: Str(17.0.13+11-Debian-2deb12u1) -> service.instance.id: Str(0da10240-547e-4a45-b28c-6133d3ffe1b5) -> service.name: Str(kotlin-zerocode) -> telemetry.distro.name: Str(opentelemetry-java-instrumentation) -> telemetry.distro.version: Str(2.12.0) -> telemetry.sdk.language: Str(java) -> telemetry.sdk.name: Str(opentelemetry) -> telemetry.sdk.version: Str(1.46.0) ScopeSpans #0 ScopeSpans SchemaURL: InstrumentationScope io.opentelemetry.netty-4.1 2.12.0-alpha Span #0 Trace ID : 5b2a39ea9e9b83b2695d6f537901a5b8 Parent ID : ID : 1009964c6a9cba86 Name : GET /error Kind : Server Start time : 2025-01-19 08:50:38.102411829 +0000 UTC End time : 2025-01-19 08:50:38.112710928 +0000 UTC Status code : Error Status message : Attributes: -> network.peer.address: Str(127.0.0.1) -> server.address: Str(localhost) -> client.address: Str(127.0.0.1) -> url.path: Str(/error) -> error.type: Str(500) -> server.port: Int(8080) -> http.request.method: Str(GET) -> thread.id: Int(40) -> http.response.status_code: Int(500) -> http.route: Str(/error) -> user_agent.original: Str(curl/7.88.1) -> network.peer.port: Int(60186) -> network.protocol.version: Str(1.1) -> url.scheme: Str(http) -> thread.name: Str(eventLoopGroupProxy-3-2) {"kind": "exporter", "data_type": "traces", "name": "debug"} 2025-01-19T17:50:44.124+0900 info Traces {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1} 2025-01-19T17:50:44.124+0900 info ResourceSpans #0 Resource SchemaURL: https://opentelemetry.io/schemas/1.24.0 Resource attributes: -> host.arch: Str(amd64) -> host.name: Str(...) -> os.description: Str(Linux 6.1.0-30-amd64) -> os.type: Str(linux) -> process.command_args: Slice(["/usr/lib/jvm/java-17-openjdk-amd64/bin/java","-javaagent:./opentelemetry-javaagent.jar","-Dotel.service.name=kotlin-zerocode","-jar","build/libs/ktor-sample-all.jar"]) -> process.executable.path: Str(/usr/lib/jvm/java-17-openjdk-amd64/bin/java) -> process.pid: Int(349907) -> process.runtime.description: Str(Debian OpenJDK 64-Bit Server VM 17.0.13+11-Debian-2deb12u1) -> process.runtime.name: Str(OpenJDK Runtime Environment) -> process.runtime.version: Str(17.0.13+11-Debian-2deb12u1) -> service.instance.id: Str(0da10240-547e-4a45-b28c-6133d3ffe1b5) -> service.name: Str(kotlin-zerocode) -> telemetry.distro.name: Str(opentelemetry-java-instrumentation) -> telemetry.distro.version: Str(2.12.0) -> telemetry.sdk.language: Str(java) -> telemetry.sdk.name: Str(opentelemetry) -> telemetry.sdk.version: Str(1.46.0) ScopeSpans #0 ScopeSpans SchemaURL: InstrumentationScope io.opentelemetry.netty-4.1 2.12.0-alpha Span #0 Trace ID : b3d80bd3e7474a883e1213c4688219df Parent ID : ID : efb2d40bf565f9f9 Name : GET /500 Kind : Server Start time : 2025-01-19 08:50:40.462618021 +0000 UTC End time : 2025-01-19 08:50:40.464162334 +0000 UTC Status code : Error Status message : Attributes: -> network.peer.address: Str(127.0.0.1) -> server.address: Str(localhost) -> client.address: Str(127.0.0.1) -> url.path: Str(/500) -> error.type: Str(500) -> server.port: Int(8080) -> http.request.method: Str(GET) -> thread.id: Int(42) -> http.response.status_code: Int(500) -> http.route: Str(/500) -> user_agent.original: Str(curl/7.88.1) -> network.peer.port: Int(56010) -> network.protocol.version: Str(1.1) -> url.scheme: Str(http) -> thread.name: Str(eventLoopGroupProxy-3-3) {"kind": "exporter", "data_type": "traces", "name": "debug"}
.NETã¨ã ãããåãé°å²æ°ã ãã
Collectorã§ã¡ããªãã¯ãåãä»ããæå¹ã«ãã¦ã¿ãã¨ãããHTTP request durationãéã£ãã¹ãã³ã®æ°ãJVMãªã½ã¼ã¹ç¶æ³ãªã©ãã¡ããªãã¯ã¨ãã¦éåºããã¦ãã¦ããï¼Goã.NETãã¡ããªãã¯ãéã£ã¦ãã¦ãããã ãã©ããããã°ã¡ããã¨è¦ã¦ããªãã£ããªï¼ã
æ§åãè¦ããã¨ãã«ã¯OpenTelemetry Collectorã®è¨å®ã以ä¸ã®ããã«å¤ããã°ããã
service: pipelines: metrics: receivers: [otlp] exporters: [debug] logs: receivers: [otlp] exporters: [debug] traces: receivers: [otlp] exporters: [debug]
Springããã®ãã¡è©¦ããã¨æãããã¾ãã¯ã»ãã®è¨èªãã²ã¨ã¨ããè¦ã¦ããã«ããã
ãã¾ã©ãJavaã§æ¸ãã«ã¯ä½ããã®ãã¬ã¼ã ã¯ã¼ã¯ã使ã£ã¦ããã ãããããJava Agentã«ããzero-codeè¨è£ ã¯.NETåæ§ã«æ軽ã ã便å©ããã ãªã¨æããã
æ®ãã¯PHPãPythonãJavaScriptãã
ãµãã£ã¨è¦ã¦ãããããªissueããã£ãã
OpenTelemetryã®zero-codeè¨è£ ã試ãã¦ããããã®2ã.NET
ååã®Goã«å¼ãç¶ããä»åº¦ã¯.NETã§ã®zero-codeè¨è£ ã試ãã¦ã¿ãã
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 build
ã§bin/Debug/net9.0/dotnet-web
ãã§ããã
bin/Debug/net9.0/dotnet-web
ãå®è¡ããcurlãªã©ã§http://localhost:5000
ãhttp://localhost:5000/error
ãhttp://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"}
ãªãã»ã©ããªã½ã¼ã¹æ å ±ãã¾ãã£ã¨å ¥ã£ã¦ãã¦ããã
è¨å®ãè¦ã¦ããã¨ãç°å¢å¤æ°ãè¨å®ãã¡ã¤ã«ã使ã£ã¦ããªãããããã¨ã«ã¹ã¿ãã¤ãºã§ãããã§ãå å®ãã¦ãããªãã
OpenTelemetryã®zero-codeè¨è£ ã試ãã¦ãããã¾ãã¯Go
ãªãã¶ã¼ãããªãã£ã§OpenTelemetryã®è¨è£ ãããå§ãããï¼ã¨ããã¨ãã«ããããè¨ããã¦ããä»ããã³ã¼ããã¼ã¹ã«ä½ã追å ããã®ã¯å«ãªããããâ¦â¦ãã¨ãããã¨ã¯ããã«ããããããªè©±ã
ããã§OpenTelemetryãæä¾ãã¦ããææ³ã¨ãã¦zero-code instrumentationãããããèªåè¨è£ ã¨ãããã®ãããã
ãã®ææ³ã§ã¯ãã¨ã¼ã¸ã§ã³ããããã¯ã¨ã¼ã¸ã§ã³ãã©ã¤ã¯ãªãã®ã¨ãã¦ããã¤ãã³ã¼ãæä½ãã¢ã³ãã¼ããããeBPFãªã©ã®æ段ã§ã¢ããªã±ã¼ã·ã§ã³ã«è¨è£ ãæ¿å ¥ããããç¾æç¹ã§å ¬å¼ãã¼ã¸ã«æ¸ããã¦ããã®ã¯.NETãGoãJavaãJavaScriptãPHPãPythonã¨ãªã£ã¦ããã
ã©ã®ç¨åº¦ãããå®ç¨çããããã¯ã¦ã¼ã¶ã¼ã«ã¨ã£ã¦å¬ãããæãããããããç¥ã£ã¦ãããã¨ã1æ¥1è¨èªâ¦ã¨ããã¤ããã ã£ããã©ãã¾ãæéçä½è£ããªããããæ°æ¥ã§ã¯Goã¨.NETã試ãã¦ãããä»æ¥ã¯Goã®çµæãã¾ã¨ãã¦ããã
Goã®ã¯ymtdzzzããã®è¨äºã«ã ãããå ¨é¨æ¸ããã¦ããã®ã§ãã¡ããã¨ãããã¨ã¯ãã£ã¡ãè¦ãã»ããæ©ããæ¬è¨äºããã®è¿½è©¦ã«ãããªãã¨è¨ããã
Goè¨èªã®zero-codeè¨è£ ï¼opentelemetry-go-instrumentationï¼
Goè¨èªã®å ´åã¯å®è¡ãã¤ããªãããã ãã§å®çµãã¦ããã®ã§ãã©ã³ã¿ã¤ã ã«å²ãè¾¼ããããªãã¨ãã§ããªãã
å ¬å¼ã§æ¡å ããã¦ããopentelemetry-go-instrumentationã¯ãLinuxã«ã¼ãã«ã®eBPFã使ã£ã¦ã¤ãã³ããåå¾ããæ段ãã¨ã£ã¦ããããã®ãããLinuxãã¤ãã£ãã§ãªãå ´åã¯ãDockerã¤ã¡ã¼ã¸ãããã¯é©å½ãªLinux VMãç«ã¦ã¦ä»£ç¨ãããã¨ã«ãªãã
ãã¤ãã£ãDebian GNU/Linuxç°å¢ãªã®ã§ãæ®éã«GitHubããå±éãã¦otel-go-instrumentationããã«ãããã
git clone https://github.com/open-telemetry/opentelemetry-go-instrumentation.git
cd opentelemetry-go-instrumentation
make build
次ã«ãTCP/5000ãã¼ãã§åããæå®ãã¹ã«ãã£ã¦ã¨ã©ã¼ãèµ·ããé©å½ãªã¢ããªã±ã¼ã·ã§ã³hello-server
ãä½ã£ã¦ãã«ããã¦ããã
package main import "net/http" func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, World!\n")) }) http.HandleFunc("/error", func(w http.ResponseWriter, r *http.Request) { http.Error(w, "Internal Server Error", http.StatusInternalServerError) }) http.ListenAndServe(":5000", nil) }
OpenTelemetry Collectorãèµ·åãã¦ããããã¬ã¼ã¹ããã¦ãã®ããããã°ããã®ã§è¨å®ã¯é©å½ã
receivers: otlp: protocols: http: exporters: debug: verbosity: detailed service: pipelines: traces: receivers: [otlp] exporters: [debug]
ã§ã¯è©¦ãã¦ã¿ããã
otel-go-instrumentation
ã®å®è¡ãã¤ããªã¯ã«ã¬ã³ããã©ã«ãã«ããã¨ãã- ã¢ããªã±ã¼ã·ã§ã³ã®å®è¡ãã¤ããªã¯
/home/kmuto/hello-server/hello-server
ãã¹ã«ããã¨ãã
対象ãã¤ããªãå®è¡ãããã®ãå¾ ã¡æ§ããã
sudo OTEL_GO_AUTO_TARGET_EXE=/home/kmuto/hello-server/hello-server OTEL_SERVICE_NAME=go-zerocode OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 ./otel-go-instrumentation
/home/kmuto/hello-server/hello-server
ãå®è¡ããcurlãªã©ã§http://localhost:5000
ã¨http://localhost:5000/error
ã«ã¢ã¯ã»ã¹ããã¨ãOpenTelemetry Collectorã®ã»ãã«ãã¬ã¼ã¹ã¨ã¹ãã³ãåºåãããã
2025-01-18T23:04:27.708+0900 info Traces {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1} 2025-01-18T23:04:27.708+0900 info ResourceSpans #0 Resource SchemaURL: https://opentelemetry.io/schemas/1.26.0 Resource attributes: -> process.runtime.description: Str(go version 1.23.1 linux/amd64) -> process.runtime.name: Str(go) -> process.runtime.version: Str(1.23.1) -> service.name: Str(go-zerocode) -> telemetry.distro.name: Str(opentelemetry-go-instrumentation) -> telemetry.distro.version: Str(v0.19.0-alpha) -> telemetry.sdk.language: Str(go) ScopeSpans #0 ScopeSpans SchemaURL: https://opentelemetry.io/schemas/1.26.0 InstrumentationScope go.opentelemetry.io/auto/net/http v0.19.0-alpha Span #0 Trace ID : f52b9e7c56d58516909ab0dbf4f6d866 Parent ID : ID : 4f212cd3e2c29532 Name : GET / Kind : Server Start time : 2025-01-18 14:04:23.501669372 +0000 UTC End time : 2025-01-18 14:04:23.50167801 +0000 UTC Status code : Unset Status message : Attributes: -> http.request.method: Str(GET) -> url.path: Str(/) -> http.response.status_code: Int(200) -> network.peer.address: Str(127.0.0.1) -> network.peer.port: Int(40270) -> server.address: Str(localhost) -> server.port: Int(5000) -> network.protocol.version: Str(1.1) -> http.route: Str(/) {"kind": "exporter", "data_type": "traces", "name": "debug"} 2025-01-18T23:04:32.712+0900 info Traces {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1} 2025-01-18T23:04:32.712+0900 info ResourceSpans #0 Resource SchemaURL: https://opentelemetry.io/schemas/1.26.0 Resource attributes: -> process.runtime.description: Str(go version 1.23.1 linux/amd64) -> process.runtime.name: Str(go) -> process.runtime.version: Str(1.23.1) -> service.name: Str(go-zerocode) -> telemetry.distro.name: Str(opentelemetry-go-instrumentation) -> telemetry.distro.version: Str(v0.19.0-alpha) -> telemetry.sdk.language: Str(go) ScopeSpans #0 ScopeSpans SchemaURL: https://opentelemetry.io/schemas/1.26.0 InstrumentationScope go.opentelemetry.io/auto/net/http v0.19.0-alpha Span #0 Trace ID : 6d7626cdf485322abd7d2785d00b31b9 Parent ID : ID : 2c801415b9953b48 Name : GET /error Kind : Server Start time : 2025-01-18 14:04:30.454387577 +0000 UTC End time : 2025-01-18 14:04:30.454400865 +0000 UTC Status code : Error Status message : Attributes: -> http.request.method: Str(GET) -> url.path: Str(/error) -> http.response.status_code: Int(500) -> network.peer.address: Str(127.0.0.1) -> network.peer.port: Int(41402) -> server.address: Str(localhost) -> server.port: Int(5000) -> network.protocol.version: Str(1.1) -> http.route: Str(/error) {"kind": "exporter", "data_type": "traces", "name": "debug"}
1ãã¬ã¼ã¹1ã¹ãã³ã§ããèªä½ã¯ããã¦é¢ç½ããã®ã§ã¯ãªãããã¨ã©ã¼ã®ã¨ãã¯ã¡ããã¨ã¨ã©ã¼ã®status codeã«ãªã£ã¦ããã
Vaxilaã§ã¯ãã¾ãåãåããªãã£ããJaegerã§ããªããå¤ãªæ°ãããã
Goè¨èªã®zero-codeè¨è£ ï¼opentelemetry-go-auto-instrumentationï¼
ãã1ã¤ã®zero-codeã¨ãã¦ã¯ãalibaba/opentelemetry-go-auto-instrumentationããããããã¯ãã«ãæã«è¨è£ ãä»è¾¼ããã®ã
Alibabaã¨ãããã¨ã«å°ã ããããã¯ããã®ã ãããããã«ç®ã«è¦ãããã®ã§ä»è¾¼ãã§ã¯ããªãã ããâ¦ãã¨ã¯è¨ããã®ã®ãå ¨é¨Dockerã§éããç°å¢ã«ããã
Dockerfile
ãç¨æã
FROM golang:1.23 WORKDIR /usr/src/app RUN apt update \ && apt install -y sudo curl \ && curl -fsSL https://cdn.jsdelivr.net/gh/alibaba/opentelemetry-go-auto-instrumentation@main/install.sh | bash COPY go.mod main.go ./ RUN go mod download & go mod verify RUN otel go build -o hello-server-alibaba main.go CMD ["./hello-server-alibaba"]
docker-compose.yml
ã
services: alibaba: build: context: . dockerfile: ./Dockerfile ports: - "5000:5000" environment: OTEL_EXPORTER_OTLP_ENDPOINT: "http://otelcol:4318" OTEL_EXPORTER_OTLP_INSECURE: true OTEL_SERVICE_NAME: "go-zerocode-alibaba" otelcol: image: otel/opentelemetry-collector-contrib:latest volumes: - ./otel-col-alibaba.yaml:/etc/otelcol-contrib/config.yaml ports: - "4318:4318"
otel-col-alibaba.yaml
ã¯ãã¤ã³ãã¢ãã¬ã¹ãã°ãã¼ãã«ã«ããã ãã
receivers: otlp: protocols: http: endpoint: "0.0.0.0:4318" exporters: debug: verbosity: detailed service: pipelines: traces: receivers: [otlp] exporters: [debug]
docker compose up
ã§èµ·åããhttp://localhost:5000
ãhttp//localhost:5000/error
ã«curlã§ã¢ã¯ã»ã¹ãã¦ãã¬ã¼ã¹ãéã£ã¦ã¿ãã
otelcol-1 | 2025-01-18T15:02:31.587Z info TracesExporter {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 2} otelcol-1 | 2025-01-18T15:02:31.587Z info ResourceSpans #0 otelcol-1 | Resource SchemaURL: https://opentelemetry.io/schemas/1.26.0 otelcol-1 | Resource attributes: otelcol-1 | -> service.name: Str(go-zerocode-alibaba) otelcol-1 | -> telemetry.sdk.language: Str(go) otelcol-1 | -> telemetry.sdk.name: Str(opentelemetry) otelcol-1 | -> telemetry.sdk.version: Str(1.33.0) otelcol-1 | ScopeSpans #0 otelcol-1 | ScopeSpans SchemaURL: otelcol-1 | InstrumentationScope pkg/rules/http/server_setup.go v0.7.0 otelcol-1 | Span #0 otelcol-1 | Trace ID : 3b2ffa25076e74ef6b111af48c2494df otelcol-1 | Parent ID : otelcol-1 | ID : c3c9a8fbc916debf otelcol-1 | Name : GET / otelcol-1 | Kind : Server otelcol-1 | Start time : 2025-01-18 15:02:27.286134194 +0000 UTC otelcol-1 | End time : 2025-01-18 15:02:27.286153625 +0000 UTC otelcol-1 | Status code : Unset otelcol-1 | Status message : otelcol-1 | Attributes: otelcol-1 | -> http.request.method: Str(GET) otelcol-1 | -> url.scheme: Str(http) otelcol-1 | -> url.path: Str(/) otelcol-1 | -> url.query: Str() otelcol-1 | -> user_agent.original: Str(curl/7.88.1) otelcol-1 | -> http.response.status_code: Int(200) otelcol-1 | -> network.protocol.name: Str(http) otelcol-1 | -> network.protocol.version: Str(1.1) otelcol-1 | -> network.transport: Str(tcp) otelcol-1 | -> network.type: Str(ipv4) otelcol-1 | -> network.local.address: Str() otelcol-1 | -> network.peer.address: Str(localhost:5000) otelcol-1 | -> http.route: Str(/) otelcol-1 | Span #1 otelcol-1 | Trace ID : 5c071af6c91bb08a9a34fcbe942b2b70 otelcol-1 | Parent ID : otelcol-1 | ID : dd5524e5dbf689c9 otelcol-1 | Name : GET /error otelcol-1 | Kind : Server otelcol-1 | Start time : 2025-01-18 15:02:28.919892825 +0000 UTC otelcol-1 | End time : 2025-01-18 15:02:28.919909903 +0000 UTC otelcol-1 | Status code : Error otelcol-1 | Status message : INVALID_HTTP_STATUS_CODE otelcol-1 | Attributes: otelcol-1 | -> http.request.method: Str(GET) otelcol-1 | -> url.scheme: Str(http) otelcol-1 | -> url.path: Str(/error) otelcol-1 | -> url.query: Str() otelcol-1 | -> user_agent.original: Str(curl/7.88.1) otelcol-1 | -> http.response.status_code: Int(500) otelcol-1 | -> network.protocol.name: Str(http) otelcol-1 | -> network.protocol.version: Str(1.1) otelcol-1 | -> network.transport: Str(tcp) otelcol-1 | -> network.type: Str(ipv4) otelcol-1 | -> network.local.address: Str() otelcol-1 | -> network.peer.address: Str(localhost:5000) otelcol-1 | -> http.route: Str(/error) otelcol-1 | {"kind": "exporter", "data_type": "traces", "name": "debug"} otelcol-1 | 2025-01-18T15:02:36.588Z info TracesExporter {"kind": "exporter", "data_type": "traces", "name": "debug", "resource spans": 1, "spans": 1} otelcol-1 | 2025-01-18T15:02:36.588Z info ResourceSpans #0 otelcol-1 | Resource SchemaURL: https://opentelemetry.io/schemas/1.26.0 otelcol-1 | Resource attributes: otelcol-1 | -> service.name: Str(go-zerocode-alibaba) otelcol-1 | -> telemetry.sdk.language: Str(go) otelcol-1 | -> telemetry.sdk.name: Str(opentelemetry) otelcol-1 | -> telemetry.sdk.version: Str(1.33.0) otelcol-1 | ScopeSpans #0 otelcol-1 | ScopeSpans SchemaURL: otelcol-1 | InstrumentationScope pkg/rules/http/client_setup.go v0.7.0 otelcol-1 | Span #0 otelcol-1 | Trace ID : f3c89464869497c7d71975e077f55b6f otelcol-1 | Parent ID : otelcol-1 | ID : 76adf95e3720a020 otelcol-1 | Name : POST otelcol-1 | Kind : Client otelcol-1 | Start time : 2025-01-18 15:02:31.587172333 +0000 UTC otelcol-1 | End time : 2025-01-18 15:02:31.5880139 +0000 UTC otelcol-1 | Status code : Unset otelcol-1 | Status message : otelcol-1 | Attributes: otelcol-1 | -> http.request.method: Str(POST) otelcol-1 | -> url.full: Str(http://otelcol:4318/v1/traces) otelcol-1 | -> server.address: Str(otelcol:4318) otelcol-1 | -> server.port: Int(4318) otelcol-1 | -> http.response.status_code: Int(200) otelcol-1 | -> network.protocol.name: Str(http) otelcol-1 | -> network.protocol.version: Str(1.1) otelcol-1 | -> network.transport: Str(tcp) otelcol-1 | -> network.type: Str(ipv4) otelcol-1 | -> network.local.address: Str() otelcol-1 | -> network.peer.address: Str(otelcol:4318) otelcol-1 | -> network.peer.port: Int(4318) otelcol-1 | {"kind": "exporter", "data_type": "traces", "name": "debug"}
1ãã¬ã¼ã¹ã1ã¹ãã³ã§ãããã¨ã¯åãã ãå±æ§ã¯å°ãç´°ããæããStatus messageãä¸å¯§ã«ãªã£ã¦ãããCollectorã¸ã®éä¿¡èªä½ããã¬ã¼ã¹ã«ã®ã£ãã¦ããã®ããªã
ãã¡ãã¯Vaxilaã§ããã¾ãåããã¨ãã§ãã¦ããã
ãã¤ããªã¯ãããªãã«å¤§ãããªã£ããæ®éã®ãã«ãã ã¨7,521,614ãã¤ããotelãã«ãã ã¨22,813,463ãã¤ãã
ã¨ããããGoçã®ã試ãã¯ããã¾ã§ã