ããã¯ãOpenTelemetry Advent Calendar 2024 16æ¥ç®ã®è¨äºã§ãã
Table of Contents
ã¯ããã«
ããã¾ã§Goã§æ¸ãããã¢ããªã±ã¼ã·ã§ã³ãOpenTelemetryã§è¨è£
ããã«ã¯ãnet/http
ãredigo
ãdatabase/sql
ãªã©åã©ã¤ãã©ãªæ¯ã«å¯¾å¿ããè¨è£
ã©ã¤ãã©ãªãå°å
¥ãå·®ãæ¿ããå¿
è¦ãããã¾ãããããã¯ãJavaãNodeJSãPHPã¨ãã£ãzero-codeè¨è£
ãå¯è½ãªè¨èªã«æ¯ã¹ãã¨å°å
¥ãã¼ãã«ãé«ããªãè¦å ã«ãªãå¾ã¾ãã
zero-codeè¨è£ ãé£ããè¦å ã¨ãã¦ãGolangãã³ã³ãã¤ã«è¨èªã§ããå®è¡æã«è¨è£ ç¨ã³ã¼ããå·®ãè¾¼ããã¨ãå°é£ãªãã¨ãæãããã¾ãã
ãããæè¿Golangã®zero-codeè¨è£ ãçãä¸ãããè¦ãã¦ãããzero-codeè¨è£ ã®ããã®ä»çµã¿ãçã¾ãã¦ãã¦ãã¾ãããã®è¨äºã§ã¯ä¸è¨ã®ï¼ãããã¯ããåãä¸ããå®éã«ä½¿ãå¿å°ã確ããã¦ã¿ã¾ãã
- alibaba/opentelemetry-go-auto-instrumentationï¼ãã«ãæã«è¨è£ ã³ã¼ããå·®ãè¾¼ãï¼
- open-telemetry/opentelemetry-go-instrumentationï¼eBPFã®ä»çµã¿ãå©ç¨ï¼
è¨è£ ãããµã³ãã«ã¢ããª
ymtdzzz/go-auto-instrumentation-test
server_a
ã¨server_b
ã¨ããï¼ã¤ã®ã¢ããªã±ã¼ã·ã§ã³ãç¨æãã¾ãããserver_a
ã®/call-b
ã¨ã³ããã¤ã³ãã«GETã§ã¢ã¯ã»ã¹ããã¨ãããããMySQLã¨Redisã«é©å½ãªãªã¯ã¨ã¹ããæãã¤ã¤server_b
ã®/data
ã¨ã³ããã¤ã³ãã«å
é¨çã«éä¿¡ãè¡ããã¾ãã
ã¾ããserver_a
ã¨server_b
ã¯ããããGinã¨Echoãç°å¢å¤æ°ãè¨å®ããã¨net/httpã§ãµã¼ãã¼ãèµ·åããããã«ãã¦ãã¾ãã
åä½ç°å¢
åä½ç¢ºèªã¯ä¸è¨ã®ç°å¢ã§è¡ãã¾ããããã®ãããMacOSãªã©ç°ãªãç°å¢ã§ã¯åä½ããªãå¯è½æ§ãããã¾ãã
alibaba/opentelemetry-go-auto-instrumentation
ï¼ã¤ç®ã¯alibaba/opentelemetry-go-auto-instrumentationã§ããããã¯ãã«ãæã«è¨è£ ç¨ã®ã³ã¼ããå·®ãè¾¼ããã¨ã§zero-codeè¨è£ ãå¯è½ã«ãã¦ãã¾ãã
å©ç¨æ¹æ³ã¯ç°¡åã§ãã¢ããªã±ã¼ã·ã§ã³ã®ãã«ãæã«go build
ãå©ãå¤ããã«otel go build
ã«å·®ãæ¿ãã¦ãã«ããè¡ããã¨ã§OpenTelemetryé¢é£ã®ã³ã¼ããæèããã«è¨è£
ãè¡ããã¨ãã§ããããã«ãªãã¾ãã
# Dockerfile.a_alibaba
# Install alibaba's auto instrumentation command
# NOTE: Quickly install sudo command because it's used in install.sh
RUN apt update \
&& apt install -y sudo \
&& curl -fsSL https://cdn.jsdelivr.net/gh/alibaba/opentelemetry-go-auto-instrumentation@main/install.sh | bash
RUN otel go build -o main ./server_a
ãã«ãããããã¤ããªã®å®è¡æ¹æ³ã¯ç¹ã«å¤æ´ã¯ç¡ããã¾ãããµã¤ãã«ã¼ãªã©ãä¸è¦ã§ã¹ã¿ã³ãã¢ãã¼ã³ã§åä½ãã¾ãã
OpenTelemetryç¨ã®ç°å¢å¤æ°ãè¨å®ãã¦èµ·åããã°ããã¬ã¡ããªãéä¿¡ããã¾ãï¼ä»åã®OTel Collectorã¯ãããã°ç¨ã«otel-tuiãå©ç¨ãã¾ãï¼ã
# docker-compose.yml
server_a_alibaba:
build:
context: .
dockerfile: ./Dockerfile.a_alibaba
ports:
- "8080:8080"
environment:
# ...
# OTelç¨ã®è¨å®
OTEL_EXPORTER_OTLP_ENDPOINT: "http://oteltui:4318"
OTEL_EXPORTER_OTLP_INSECURE: true
OTEL_SERVICE_NAME: server_a_alibaba
oteltui:
image: ymtdzzz/otel-tui:latest
container_name: otel-tui
stdin_open: true
tty: true
docker compose up
ã§ç°å¢ãèµ·åããhttp://localhost:8080/call-b
ã«ã¢ã¯ã»ã¹ããã¨ãTraceãMetricãéä¿¡ããå§ãã¾ãã
attributesã®åºåå 容ãªã©ãç³ãåãªãããã«æãã¾ãããç¹ã«contextãåã渡ããããã¦ããªãã®ã«ãé¢ããããã¬ã¼ã¹ããã¡ãã¨ç¹ãã£ã¦ãããã¨ã«é©ãã¾ããï¼redisã®durationããã¤ãã¹ã«ãªã£ã¦ãã®ã¯PINGã®ãããªä¸ç¬ã§çµããå¦çã ããï¼ï¼ã
// å
ã³ã¼ãã§ã¯contextã渡ãã¦ããªããããã¡ãã¨ç¹ãã£ã¦ãã
_, err := rdb.Do("PING") // this works even if we don't pass the context, wow!
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
serverbURL := os.Getenv("SERVER_B_DATA_URL")
resp, err := http.Get(serverbURL)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
defer resp.Body.Close()
ã¾ãããã°ã«ã¤ãã¦ãåºåå
容ã«trace_id
ã¨span_id
ãappendããã¦ãããã¨ããããã¾ãã
ãã¬ã¡ããªã¨ãã¦Logãåºãã®ã¯æªå¯¾å¿ã£ã½ãã§ãããããã¯ãããã³ã°ã§ããã®ã§åå許容ç¯å²ãªæ°ããã¾ãã
ç°¡åã«å®è£ ãè¦ãã¦ã¿ã
詳細ã¯ãªãã¸ããªã®how-it-works.mdãèªãã®ãè¯ãããã§ãããç°¡åã«ãç´¹ä»ãã¾ãã
alibaba/opentelemetry-go-auto-instrumentationã§ã¯ãGolangã®toolexecã¨ãããã«ãæã«ä»»æã®ã³ã¼ããå·®ãè¾¼ããã¨ã§ãã«ãããã»ã¹ãæ¡å¼µããä»çµã¿ãå©ç¨ããè¨è£ ç¨ã³ã¼ãã®å·®ãè¾¼ã¿ããã«ãæã«è¡ãããã«ãã¦ãã¾ãã
ä¾åããã±ã¼ã¸ããã¼ã¸ã§ã³ã®è§£æ±ºãªã©è²ã ã¨è¤éãªãã¨ãã£ã¦ããããã«è¦ãã¾ãã®ã§ãããã¯ã¹ã«ã¼ãã¦ã¾ãã¯åããã±ã¼ã¸æ¯ã«ç¨æãããruleãè¦ã¦ã¿ã¾ãã
å ç¨ã®åä½ç¢ºèªæãnet/httpã®clientã§contextã渡ãã¦ããªãã®ã«ãã¡ãã¨ãã¬ã¼ã¹ãç¹ãã£ã¦ããã®ãä¸æè°ã ã£ãã®ã§ãnet/httpã®ruleãè¦ã¦ã¿ã¾ãã
ã¾ãã¯ruleã®è¨å®ãã¡ã¤ã«ã確èªãã¾ãã
https://github.com/alibaba/opentelemetry-go-auto-instrumentation/blob/32af42919579fef40a724bf5fe6bb2a53455003e/pkg/data/default.json#L388-L395
{
"ImportPath": "net/http",
"Function": "RoundTrip",
"ReceiverType": "*Transport",
"OnEnter": "clientOnEnter",
"OnExit": "clientOnExit",
"Path": "github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/rules/http"
},
ããã±ã¼ã¸ã®import pathãhookããã対象ã®functionãæå®ãã¦ããããã§ããã¾ããOnEnter
ã¨OnExit
ã§æå®ããã¦ããé¢æ°ãè¨è£
ãå·®ãè¾¼ãå¦çã£ã½ãã®ã§ããããæ¢ãã¦ã¿ã¾ãã
// https://github.com/alibaba/opentelemetry-go-auto-instrumentation/blob/32af42919579fef40a724bf5fe6bb2a53455003e/pkg/rules/http/client_setup.go#L29-L48
func clientOnEnter(call api.CallContext, t *http.Transport, req *http.Request) {
if netHttpFilter.FilterUrl(req.URL) {
return
}
netHttpRequest := &netHttpRequest{
method: req.Method,
url: req.URL,
header: req.Header,
host: req.Host,
isTls: req.TLS != nil,
}
netHttpRequest.version = getProtocolVersion(req.ProtoMajor, req.ProtoMinor)
ctx := netHttpClientInstrumenter.Start(req.Context(), netHttpRequest)
req = req.WithContext(ctx)
call.SetParam(1, req)
data := make(map[string]interface{}, 1)
data["ctx"] = ctx
call.SetData(data)
return
}
ãã£ã¨èªãã æããRequestå
容ãnetHttpClientInstrumenter
ã«æ¸¡ããæ»ã£ã¦ããctx
ãreq
ã«è©°ãã¦ããããã§ããæããTrace Contextã®çæã¯netHttpClientInstrumenter
ã§ãã£ã¦ãããªã®ã§ããã¡ããè¦ãã¦ã¿ã¾ãã
// https://github.com/alibaba/opentelemetry-go-auto-instrumentation/blob/32af42919579fef40a724bf5fe6bb2a53455003e/pkg/rules/http/net_http_otel_instrumenter.go#L201C1-L219C2
func BuildNetHttpClientOtelInstrumenter() *instrumenter.PropagatingToDownstreamInstrumenter[*netHttpRequest, *netHttpResponse] {
builder := &instrumenter.Builder[*netHttpRequest, *netHttpResponse]{}
clientGetter := netHttpClientAttrsGetter{}
commonExtractor := http.HttpCommonAttrsExtractor[*netHttpRequest, *netHttpResponse, http.HttpClientAttrsGetter[*netHttpRequest, *netHttpResponse], net.NetworkAttrsGetter[*netHttpRequest, *netHttpResponse]]{HttpGetter: clientGetter, NetGetter: clientGetter}
networkExtractor := net.NetworkAttrsExtractor[*netHttpRequest, *netHttpResponse, net.NetworkAttrsGetter[*netHttpRequest, *netHttpResponse]]{Getter: clientGetter}
return builder.Init().SetSpanStatusExtractor(http.HttpClientSpanStatusExtractor[*netHttpRequest, *netHttpResponse]{Getter: clientGetter}).SetSpanNameExtractor(&http.HttpClientSpanNameExtractor[*netHttpRequest, *netHttpResponse]{Getter: clientGetter}).
SetSpanKindExtractor(&instrumenter.AlwaysClientExtractor[*netHttpRequest]{}).
AddOperationListeners(http.HttpClientMetrics(), http.HttpClientMetrics()).
SetInstrumentationScope(instrumentation.Scope{
Name: utils.NET_HTTP_CLIENT_SCOPE_NAME,
Version: version.Tag,
}).
AddAttributesExtractor(&http.HttpClientAttrsExtractor[*netHttpRequest, *netHttpResponse, http.HttpClientAttrsGetter[*netHttpRequest, *netHttpResponse], net.NetworkAttrsGetter[*netHttpRequest, *netHttpResponse]]{Base: commonExtractor, NetworkExtractor: networkExtractor}).BuildPropagatingToDownstreamInstrumenter(func(n *netHttpRequest) propagation.TextMapCarrier {
if n.header == nil {
return nil
}
return propagation.HeaderCarrier(n.header)
}, otel.GetTextMapPropagator())
}
Requestãããã¬ã¡ããªã®Attributeã«ã»ããããããã®æ
å ±ãåå¾ããExtractorãå®ç¾©ããã¦ãã¾ããå¦çã®å®ä½ã¯*instrumenter.PropagatingToDownstreamInstrumenter
ã¿ãããªã®ã§ãããã¡ããæã£ã¦ã¿ã¾ãã
// https://github.com/alibaba/opentelemetry-go-auto-instrumentation/blob/32af42919579fef40a724bf5fe6bb2a53455003e/pkg/inst-api/instrumenter/instrumenter.go#L48-L52
type PropagatingToDownstreamInstrumenter[REQUEST any, RESPONSE any] struct {
carrierGetter func(REQUEST) propagation.TextMapCarrier
prop propagation.TextMapPropagator
base InternalInstrumenter[REQUEST, RESPONSE]
}
ããã«InternalInstrumenter
ã確èªãã¾ãã
// https://github.com/alibaba/opentelemetry-go-auto-instrumentation/blob/32af42919579fef40a724bf5fe6bb2a53455003e/pkg/inst-api/instrumenter/instrumenter.go#L89-L115
func (i *InternalInstrumenter[REQUEST, RESPONSE]) doStart(parentContext context.Context, request REQUEST, timestamp time.Time, options ...trace.SpanStartOption) context.Context {
if i.enabler != nil && !i.enabler.Enable() {
return parentContext
}
for _, listener := range i.operationListeners {
parentContext = listener.OnBeforeStart(parentContext, timestamp)
}
// extract span name
spanName := i.spanNameExtractor.Extract(request)
spanKind := i.spanKindExtractor.Extract(request)
options = append(options, trace.WithSpanKind(spanKind))
newCtx, span := i.tracer.Start(parentContext, spanName, options...)
attrs := make([]attribute.KeyValue, 0, 20)
// extract span attrs
for _, extractor := range i.attributesExtractors {
attrs, newCtx = extractor.OnStart(attrs, newCtx, request)
}
// execute context customizer hook
for _, customizer := range i.contextCustomizers {
newCtx = customizer.OnStart(newCtx, request, attrs)
}
for _, listener := range i.operationListeners {
newCtx = listener.OnBeforeEnd(newCtx, attrs, timestamp)
}
span.SetAttributes(attrs...)
return i.spanSuppressor.StoreInContext(newCtx, spanKind, span)
}
ã©ããããããè¨è£ å¦çã®å®ä½ã®ããã§ããããã§Spanãã¹ã¿ã¼ãããå ç¨ã»ããããExtractorãå¼ã³åºãã¦Attributeã«ã»ãããã¦ããããã§ããããã¦ãæå¾ã«æ°ããªcontextãè¿å´ãã¦ãã¾ãã
ruleã®è¨å®ãã¡ã¤ã«ãä½æããããã«åããã¦å¿ è¦ãªExtractorãå®ç¾©ãã¦ããããã¨ã§ãä»ã®ããã±ã¼ã¸ã§ãèªç±ã«zero-codeãããã¨ãã§ãããã§ããã
ããã¥ã¡ã³ãã§ã¯os.Getenv()
ã®ruleãä½æããç°¡åãªäºä¾ãç´¹ä»ããã¦ãã¾ãã®ã§ãèå³ã®ããæ¹ã¯ãåç
§ãã ããã
open-telemetry/opentelemetry-go-instrumentation
ç¶ãã¦open-telemetry/opentelemetry-go-instrumentationã§ãããã¡ãã¯å ç¨ã¨ã¯ç°ãªããeBPFã®ä»çµã¿ãå©ç¨ããzero-codeè¨è£ ã®è©¦ã¿ã¨ãªãã¾ããeBPFã«ã¤ãã¦ã¯ç§èªèº«ãã¾ã詳ãããªãã§ãããã¦ã¼ã¶ã¼é åã§å®è¡ä¸ã®ããã°ã©ã ï¼ããã»ã¹ï¼ã«å¯¾ãã¦ç¹å®ã®ã¤ãã³ãã«ããã¯ãã¦ä»»æã®å¦çãã«ã¼ãã«ã®ãµã³ãããã¯ã¹åãããã¡ã¢ãªä¸ã§å®è¡ããä»çµã¿ã§ãã
ã§ã¯æ©é使ã£ã¦ã¿ã¾ãããã ããç¾ç¶å¯¾å¿ããã±ã¼ã¸ãå°ãªãï¼å¾è¿°ï¼ãHTTPãµã¼ãã¼ã¯net/httpã®ã¿å¯¾å¿ãã¦ããããããµã³ãã«ã¢ããªã±ã¼ã·ã§ã³ã§ã¯å®è£ ãnet/httpãå©ç¨ãããã®ã«åãæ¿ãã¦ãã¾ãï¼ã¨ãã£ã¦ãç°å¢å¤æ°ã§å¦çãåå²ãã¦ãã ãã§ããï¼ã
# docker-compose.yml
server_a_otel:
build:
context: .
dockerfile: ./Dockerfile.a_otel
ports:
- "8082:8080"
environment:
# ...
SERVER_MODE: "net/http" # ããã§åãæ¿ã
depends_on:
- redis
- mysql
volumes:
- server_a_otel_binary:/app
ã¾ããeBPFããã°ã©ã ããµã¤ãã«ã¼ã¨ãã¦åããå¿
è¦ãããã¾ãããã®ãããdocker composeã§è¨è£
ããããã«ã¯å®è¡ãã¡ã¤ã«ãé
ç½®ãããvolumeã¨ãããã»ã¹æ
å ±åå¾ç¨ã«/proc
ããã¦ã³ãããå¿
è¦ãããã¾ãã
# docker-compose.yml
server_a_otel_agent:
image: otel/autoinstrumentation-go
privileged: true
pid: "host"
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: "http://oteltui:4318"
OTEL_EXPORTER_OTLP_INSECURE: true
OTEL_GO_AUTO_TARGET_EXE: /app/main_a # ãã¦ã³ãããå®è¡ãã¡ã¤ã«ãæå®
OTEL_SERVICE_NAME: server_a_otel
OTEL_PROPAGATORS: tracecontext,baggage
OTEL_GO_AUTO_INCLUDE_DB_STATEMENT: true
OTEL_GO_AUTO_PARSE_DB_STATEMENT: true
volumes:
- server_a_otel_binary:/app # è¨è£
対象ã®ã³ã³ããã¨ã·ã§ã¢ãã¦ããå®è¡ãã¡ã¤ã«ã®volume
- /proc:/host/proc
depends_on:
- server_a_otel
volumes:
server_a_otel_binary:
å
ç¨ã¨åæ§ã«docker composeã§èµ·åå¾http://localhost:8082/call-b
ã«ã¢ã¯ã»ã¹ããã¨ãã¬ã¼ã¹ãåéã§ãã¾ãã
ãã¡ãããã¡ãã¨ãã¬ã¼ã¹ãç¹ãã£ã¦ãã¾ããããªããRedisã¯ã©ã¤ã¢ã³ãã«ã¤ãã¦ã¯ãµãã¼ãããã¦ããªããããã¬ã¼ã¹ã¯åºåããã¾ããã
ãã®æ¹æ³ã®æ³¨æç¹ã¨ãã¦ã¯ãã³ã¼ãå ã§ãã¡ãã¨contextãå¼ãåãå®è£ ã«ãªã£ã¦ããªãã¨ãã¬ã¼ã¹ãéåãã¦ãã¾ãç¹ã§ãã
ãªããä»çµã¿ãå®è£ ã«ã¤ãã¦ã¯æéã®é½åï¼ç§ã®eBPFã«å¯¾ããç¥èä¸è¶³ã®ããçç¥ãã¾ãï¼è©³ç´°ã¯How it worksããåç §ãã ããã
両è ã®æ¯è¼
軽ã触ã£ãã ãã§ã¯ããã¾ããã両è ãç°¡åã«æ¯è¼ãã¦ã¿ã¾ãã
対å¿ããã±ã¼ã¸
対å¿ããã±ã¼ã¸ã¯alibabaã®æ¹ãå å®ãã¦ã¾ãããã¾ããlogãslog, zapãªã©ã®Loggerã«ã対å¿ãã¦ããã®ããããããã§ãã
ã©ã¤ãã©ãª | alibaba | otel |
---|---|---|
database/sql | â | â |
echo | â | â |
elasticsearch | â | â |
fasthttp | â | â |
gin | â | â |
go-redis | â | â |
gorm | â | â |
grpc | â | â |
hertz | â | â |
kratos | â | â |
log | â | â |
logrus | â | â |
mongodb | â | â |
mux | â | â |
net/http | â | â |
redigo | â | â |
slog | â | â |
zap | â | â |
fiber | â | â |
kafka-go | â | â |
æ¡å¼µæ§
alibabaã®ãã«ãæã«å·®ãè¾¼ãæ¹å¼ã«ã¤ãã¦ã¯JSONã¨Golangã§Ruleãå®ç¾©ãããã¨ã§æ¡å¼µãå¯è½ã§ããã¾ãããã«ãããã»ã¹ã§ã³ã¼ãã®å·®ãæ¿ããè¡ãªã£ã¦ãããããcontextã®å·®ãè¾¼ã¿ãªã©æè»æ§ãé«ããã§ããä»å¾è²ã ãªããã±ã¼ã¸ã対å¿ãããããªæ°é ãæãã¾ãï¼ãã§ã«ããªãå å®ãã¦ãã¾ãããï¼ã
対ãã¦OTelã®eBPFæ¹å¼ã¯ãprobeã®å®è£ ã«Cè¨èªã®ã³ã¼ããåå¨ããããeBPFããèªä½ã¸ã®ãã£ããã¢ãããå«ãã¦ãã¼ãã«ã¯é«ããã«æããã¾ãããï¼éã«ãã®è¾ºãã«è©³ãã人ã ã£ããã©ãã©ãæ¡å¼µã§ããã®ããªãï¼ï¼
ããã¾ã§ãGolangã®å俵ã§ãã¨èããã¨alibabaã®ãã«ãæ¹å¼ã«è»é ãä¸ããããããã¾ããã
å©ç¨ãããã
ã©ã¡ããå°å ¥ã¯æ¥½ã§ãããalibabaã®ãã«ãæ¹å¼ã¯ãã«ãã³ãã³ãã®å·®ãæ¿ããotelã®eBPFæ¹å¼ã¯ãµã¤ãã«ã¼ã§å®è¡ãã¡ã¤ã«ã¨ããã»ã¹ã®å ±æã§ããã°ã·ã¥ãã¨å°å ¥ã§ãã¾ãã
ãã ãeBPFã®å ´åå¼·ãã®æ¨©éãå²ãå½ã¦ãå¿ è¦ããã£ãããå ±æããªã¥ã¼ã ã®ãã¦ã³ããªã©ã¯ãã¼ãã«ã«ãªãã±ã¼ã¹ãããããããã¾ããã
äºæ ãã«ãã
å®è¡ãã¡ã¤ã«ã¸ã®å½±é¿åº¦ãå®è¡æã¨ã©ã¼ã®èµ·ããã«ããã«ã¤ãã¦ã¯ããã»ã¹ãåé¢ãã¦ããeBPFã®æ¹ãè¯ãããã§ãã
ãã«ãæ¹å¼ã§ãã¨ã©ã¼ãã³ããªã³ã°ã¯ä¸å¯§ã«è¡ã£ã¦ããã¡ã¤ã³å¦çã«å½±é¿ãä¸ããªããããªé æ ®ã¯å®è£ ä¸è¦åãããã¾ããããã®æè»æ§ã®é«ãæ ã«å®è¡æã¨ã©ã¼ãå¼ãèµ·ãããªã¹ã¯ã¯ããããã«æãã¾ãï¼ãããè¨ããªãè¨è£ ã©ã¤ãã©ãªã¿ããªããã§ããï¼ã
ããã©ã¼ãã³ã¹
ãã³ããã¼ã¯ã¯ã¨ã£ã¦ãªãã®ã§ä»åã¯è¨åã§ãã¾ãããæ§æãå ¨ç¶éãã®ã§ä½ãããããªãï¼èª°ããï¼
ãããã«
ã©ã¡ããå®é¨çãªãã§ã¼ãºãã¨æãã¾ããä½ãã³ã¼ãããã£ã¦ãªãã®ã«ã¡ããã¨ãã¬ã¡ããªåºã¦æåãã¾ããããã¤ãã«Golangã«ãzero-codeè¨è£ ã®æ代ããã£ã¦ãããã»ã»ã»ï¼ãã¨æãã¾ããã
å人çã«alibabaã®ãã«ãæ¹å¼ã¯toolexecã¨ããGolangã®ä»çµã¿ã«ä¸æã«ä¹ã£ãã£ã¦ããæãããã¦ã¨ã¦ã好ãã§ããeBPFã®ä»çµã¿ãã¨ã¦ãå¯è½æ§ãæãããã¾ããã
å¼ãç¶ãzero-codeè¨è£ çéã¯watchãã¦ãããã¨æãã¾ãï¼ç¾å ´ããã¯ä»¥ä¸ã§ãï¼