ã¯ããã«
Mackerelã§ã¯å ããã忣ãã¬ã¼ã·ã³ã°ãµã¼ãã¹ã®Vaxilaã使ããããã«ãªãã¾ãããMackerelãããã¾ã§æä¾ãã¦ããç£è¦ï¼ã¢ãã¿ãªã³ã°ï¼ãããã®åº¦ã使ãããã ããããã«ãªã£ããã¬ã¼ã·ã³ã°ããã·ã¹ãã ã®ç¶æ ã®ææ¡ãçè§£ãããããã®ææ³ã§ãããè¦ç¹ãææ³ãç°ãªãã¾ãã
ãã®ã¨ã³ããªã§ã¯ãããã·ã³ãã«ãªã¢ããªã±ã¼ã·ã§ã³ãããã¬ã¼ã¹ãã¹ãã³ãéä¿¡ãVaxilaã®ç»é¢ã交ããªããããã¬ã¼ã·ã³ã°ã®è¦æ¹ãæ´»ç¨æ¹æ³ããç´¹ä»ãã¾ãã
- ã¯ããã«
- ãã¬ã¼ã·ã³ã°ã¨ã¯ä½ã
- ã·ã³ãã«ãªWebã¢ããªã±ã¼ã·ã§ã³ãç¨ãããã¬ã¼ã·ã³ã°ã®ä¾
- ãã¬ã¼ã¹ç»é¢ã®è¦æ¹
- ãã¬ã¼ã·ã³ã°ãç¨ãã¦ã©ã®ããã«èª²é¡ãçºè¦ããã
- ã¾ã¨ã
ãã¬ã¼ã·ã³ã°ã¨ã¯ä½ã
ã¾ãããã¬ã¼ã·ã³ã°ã«ã¤ãã¦ãããããã¾ãããã
ãã¬ã¼ã·ã³ã°ã¨ã¯ãã¢ããªã±ã¼ã·ã§ã³ã®å¦çããã¼ãå¯è¦åãããªã¯ã¨ã¹ãããã¼ã¿ã®æµããã·ã¹ãã å ãã©ã®ããã«ç§»åãä½ãèµ·ãã£ã¦ãããã追跡ããæè¡ã§ããç¹ã«æ¨ä»ã§ã¯ã·ã¹ãã ãè¤éåãã¢ããªã±ã¼ã·ã§ã³ã大ãããªã£ã¦ããããè¤æ°ã®ãã¤ã¯ããµã¼ãã¹ãå調ãã¦åããããªã·ã¹ãã ç°å¢ã§ã¯ããªã¯ã¨ã¹ããè¤æ°ã®ãµã¼ãã¹ãã¾ããã§å¦çãããããããã®å ¨ä½åãææ¡ããã®ã¯å°é£ã§ããããã§ãã¬ã¼ã·ã³ã°ãæ´»èºãã¾ãã
ãã¬ã¼ã·ã³ã°ã§ã¯ã以ä¸ã®ãããªè¦ç´ ãææ¡ã§ãã¾ãã
- åãµã¼ãã¹ã§ã®å¦çæéãé å»¶ã®è¦å
- ã¨ã©ã¼ãä¾å¤ãçºçããç®æã¨ãã®åå
- ãªã¯ã¨ã¹ããã©ã®ãµã¼ãã¹ãã©ã®ãããªé çªã§ééããã
ãã¨ãã°ãããã¦ã¼ã¶ã¼ããããã°æç¨¿ããã¿ã³ãã¯ãªãã¯ããã¨ãã¾ãããããã®ãªã¯ã¨ã¹ãã¯ãããã³ãã¨ã³ãããããã¯ã¨ã³ãã®ã¢ããªã±ã¼ã·ã§ã³ããã¼ã¿ãã¼ã¹ãçµç±ãã¦å¦çããããä¿åãããå¾ãã¬ã¹ãã³ã¹ã¨ãã¦ã¯ã©ã¤ã¢ã³ãã§ããã¦ã¼ã¶ã¼ã¸è¿å´ããã¾ãããã¬ã¼ã·ã³ã°ã¯ããã®ä¸é£ã®æµãããã¹ãã³ãã¨ããåä½ã§è¨é²ããå¯è¦åãã¾ãã
徿¥ã®ç£è¦ã§ã¯åä¸ã®ãµã¼ãã¼ãã·ã¹ãã å ¨ä½ã®ç¶æ ãèµ·ãã¦ãããã¨ãææ¡ãããã¨ãã§ãã¾ãããããã¬ã¼ã·ã³ã°ã§ã¯ããç¹å®ã®ãªã¯ã¨ã¹ããå¦çã®æµãã«çç®ãããã®ä¸ã®ã©ãã§ä½ãèµ·ãã£ã¦ããããç¹å®ã§ããã¨ããç¹ãç°ãªãã¾ãã
ã·ã³ãã«ãªWebã¢ããªã±ã¼ã·ã§ã³ãç¨ãããã¬ã¼ã·ã³ã°ã®ä¾
以ä¸ã¯Goã§æ¸ããã·ã³ãã«ãªWebã¢ããªã±ã¼ã·ã§ã³ã§ãã¬ã¼ã¹ãOpenTelemetryã«ãã£ã¦è¨è£ ãããã®ã§ããOpenTelemetryã¨ã¯ãã³ãã¼ããã¼ã«ã«ä¾åããªãããã¬ã¡ããªãã¼ã¿ï¼ã¡ããªãã¯ããã¬ã¼ã¹ãªã©ï¼ã使ã»ç®¡çããããã®ãã¼ã«ãããã§ããMackerelã§ãã©ãã«ä»ãã¡ããªãã¯ãVaxilaãOpenTelemetyã«å¯¾å¿ãã¦ãã¾ãã以ä¸ã®ä¾ã«ã¯ããã¬ã¼ã·ã³ã°ãOpenTelemetryã«é¢ããæ¦å¿µãããã¤ãåºã¦ãã¾ããããªã³ã¯ãã¦ããããã¥ã¡ã³ãããåç §ãã ããã
ã¢ããªã±ã¼ã·ã§ã³ã®å¦çã®æµãã¯æ¬¡ã®éãã§ããã½ã¼ã¹ã³ã¼ãä¸ã®(1)ã®ãããªæ°å表è¨ã¨å¯¾å¿ãã¦ãã¾ãã
- ã¨ã³ããã¤ã³ãã¯
/heavy
ã®ã¿ãåä½ãã¦ãã¾ãããã®ã¨ã³ããã¤ã³ãã§ã¯ä»¥ä¸ã®ãããªå¦çãè¡ãã¾ã (1)- 2ç§éã¹ãªã¼ããã¾ã (2)
- éãå¦çããã颿°ãç´åã«3åå¼ã³åºãã¾ã (3)
- æå¾ã«
This is heavy endpoint
ã¨ããããã¹ããã¬ã¹ãã³ã¹ã¨ãã¦è¿ãã¾ã (4)
ã¾ããã¢ããªã±ã¼ã·ã§ã³ã®å¦çã«å¯¾ãã¦ãã¬ã¼ã¹ãè¨è£ ããããã®æºåãããé¨åã®ã³ã¼ãã¯ä»¥ä¸ã®ããã«ãªãã¾ããã½ã¼ã¹ã³ã¼ãä¸ã®(a)ã®ãããªã¢ã«ãã¡ãããã®å°æå表è¨ã¨å¯¾å¿ãã¦ãã¾ãã
- Vaxilaã®APIã«HTTPã§ãã¬ã¼ã¹ãéä¿¡ããã¯ã©ã¤ã¢ã³ããåæåãã¾ã (a)
- ãã¬ã¼ã¹ã¨ã¯ã¹ãã¼ã¿ã¼ãåæåãã¯ã©ã¤ã¢ã³ããè¨å®ãã¾ã (b)
- ãªã½ã¼ã¹ã®è¨å®ããã¾ã (c)
- ãã¬ã¼ãµã¼ãããã¤ãã¼ãåæåãã¨ã¯ã¹ãã¼ã¿ã¼ã¨ãªã½ã¼ã¹ãè¨å®ãã¾ã (d)
æå¾ã«ãã¬ã¼ã¹ã®ããã®ã¹ãã³ã使ãã¦ããé¨åã¯ä»¥ä¸ã®ããã«ãªã£ã¦ãã¾ããã½ã¼ã¹ã³ã¼ãä¸ã®(A)ã®ãããªã¢ã«ãã¡ãããã®å¤§æå表è¨ã¨å¯¾å¿ãã¦ãã¾ãã
otelhttp.NewHandler
ãç¨ãããã¨ã§ã¨ã³ããã¤ã³ãã®ãã³ãã©ã¼ãã©ããããã¹ãã³ã使ãã¾ã (A)- éãå¦çããã颿°ã表ãã¹ãã³ã®ä½æãã¾ããååã¯å¼æ°ã¨ãã¦ä¸ããããç§æ°
n
ãç¨ãã¦span n
ã¨ãã¾ã (B) - 5ç§ããå¦çã«æéãããã£ãå ´åãã¹ãã³ã¤ãã³ãã«ä¾å¤ããã¹ãã³ã¹ãã¼ã¿ã¹ã«
Error
ãããããè¨å®ãã¾ã (C)
ãã®ããã°ã©ã ã¯ä»¥ä¸ã®ãã¼ã¸ã§ã³ã§åä½ç¢ºèªããã¦ãã¾ãã
- Go 1.23.4
- [email protected]
- [email protected]
package main import ( "context" "fmt" "net/http" "os" "time" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.20.0" "go.opentelemetry.io/otel/trace" ) func initTracerProvider(ctx context.Context) (*sdktrace.TracerProvider, error) { // (a) ãã¬ã¼ã¹ãéä¿¡ããã¯ã©ã¤ã¢ã³ãã®åæå client := otlptracehttp.NewClient( otlptracehttp.WithEndpoint("otlp-vaxila.mackerelio.com"), otlptracehttp.WithHeaders(map[string]string{ "Accept": "*/*", "Mackerel-Api-Key": os.Getenv("MACKEREL_APIKEY"), }), otlptracehttp.WithCompression(otlptracehttp.GzipCompression), ) // (b) ãã¬ã¼ã¹ã¨ã¯ã¹ãã¼ã¿ã¼ã®åæå exporter, err := otlptrace.New(ctx, client) if err != nil { return nil, err } // (c) ãªã½ã¼ã¹æ å ±ã®è¨å® resources, err := resource.New( ctx, resource.WithProcessPID(), resource.WithHost(), resource.WithAttributes( semconv.ServiceName("sample-service"), semconv.DeploymentEnvironment("development"), semconv.ServiceNamespace("sample-namespace"), ), ) if err != nil { return nil, err } // (d) ãã¬ã¼ãµã¼ãããã¤ãã¼ã®åæå tp := sdktrace.NewTracerProvider( sdktrace.WithBatcher(exporter), sdktrace.WithResource(resources), ) otel.SetTracerProvider(tp) return tp, nil } // 弿°ã§ä¸ããããç§æ°ã ãã¹ãªã¼ããã颿° func superHeavyFunc(ctx context.Context, t trace.Tracer, n int) { // (B) superHeavyFunc ã®ã¹ãã³ã使 _, span := t.Start(ctx, fmt.Sprintf("Heavy func %d", n)) defer span.End() time.Sleep(time.Duration(n) * time.Second) // (C) 5ç§ããå¦çã«æéãããã£ããã¨ã©ã¼ã¨ãã if n > 5 { msg := "timeout!" span.RecordError(fmt.Errorf("%s", msg)) span.SetStatus(codes.Error, msg) } } func main() { ctx := context.Background() tp, err := initTracerProvider(ctx) if err != nil { panic(err) } defer tp.Shutdown(ctx) tracer := tp.Tracer("main") // (1) /heavy ã¨ã³ããã¤ã³ãã®å®ç¾© http.Handle("/heavy", // (A) ã¹ãã³ã§ãã³ãã©ã¼ãã©ãã otelhttp.NewHandler( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // (2) 2ç§éã¹ãªã¼ã time.Sleep(time.Duration(2) * time.Second) // (3) éãå¦çããã颿°ã3åå¼ã³åºã superHeavyFunc(r.Context(), tracer, 8) superHeavyFunc(r.Context(), tracer, 3) superHeavyFunc(r.Context(), tracer, 5) // (4) ããã¹ãã§ã¬ã¹ãã³ã¹ãè¿ã fmt.Fprintln(w, "This is heavy endpoint") }), "heavy-endpoint", ) ) fmt.Println("Starting server at :8080...") if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println("Server failed:", err) } }
ã¢ããªã±ã¼ã·ã§ã³ãèµ·åãã
ãã®ã¢ããªã±ã¼ã·ã§ã³ããMackerelã«ãã¬ã¼ã¹ãéä¿¡ããæºåããã¾ãã
ã¾ãã以ä¸ã®ã¨ã³ããªãåèã«APIãã¼ãåå¾ãã¦ãã ããã
åå¾ããAPIãã¼ãç°å¢å¤æ° MACKEREL_APIKEY
ã«ã»ãããã¦ããã°ã©ã ãèµ·åãã¾ãã以ä¸ã¯ããã°ã©ã ã main.go
ã¨ãã¦ä¿åããä¾ã§ãã
$ export MACKEREL_APIKEY={åå¾ããAPIãã¼} $ go run main.go Starting server at :8080...
次ã«ãèµ·åããã¢ããªã±ã¼ã·ã§ã³ã«ãã©ã¦ã¶ããã¢ã¯ã»ã¹ãã¦ã¿ã¾ããããhttp://localhost:8080/heavy ã«ãã©ã¦ã¶ããã¢ã¯ã»ã¹ãããã°ããããã¨ä»¥ä¸ã®ããã« This is heavy endpoint
ã¨è¡¨ç¤ºããã¾ããããã§ãã¬ã¼ã¹ã確èªããæºåãæ´ãã¾ããã

ãã¬ã¼ã¹ç»é¢ã®è¦æ¹
Mackerelã®ãã¬ã¼ã¹ç»é¢ã«ã¢ã¯ã»ã¹ãããµã¼ãã¹ãã sample-service|sample-namespace
ã鏿ãã¾ãããã¬ã¼ã¹ã®éä¿¡ãæåãã¦ããå ´åãç»é¢ã®ä¸é¨ã«ãã¬ã¼ã¹ã表示ããã¦ããã¯ãã§ãããã®ãã¡ã®ä¸ã¤ãéã詳細ãè¦ã¦ã¿ã¾ãããã

å ¨ä½ã®ãªã¯ã¨ã¹ãããã¼
Vaxilaã®ãã¬ã¼ã¹ç»é¢ã§ã¯ããªã¯ã¨ã¹ãã /heavy
ã¨ã³ããã¤ã³ãã«å°éããsuperHeavyFunc
ãå¼ã³åºãããæµããè¦è¦çã«ç¤ºããã¾ããããã«ãããã©ã®å¦çã§ããã«ããã¯ãçºçãã¦ããããä¸ç®ã§ç¢ºèªã§ãã¾ãã
heavy-endpoint
ã¹ãã³ã®ä¸ã« Heavy func
ã¹ãã³ã3ã¤ä¸¦ãã§ãããã¨ãããheavy-endpoint
ã¹ãã³ã®åã¹ãã³ã3ã¤ããã¨ãããã¨ããããã¾ãããã®ãã¨ãã Heavy func
ã®åå¦ç㯠heavy-endpoint
ããå¼ã³åºããããã¤ç´åã«å¦çããã¦ããã¨ãããã¨ããããã¾ãã

åã¹ãã³ã®è©³ç´°ãè¦ã¦ãã
åã¹ãã³ã詳細ã«è¦ã¦ããã¾ããããæä¸ã®(A)ã(d)ãªã©ã®è¨è¼ã¯ãå ã»ã©æç¤ºããã½ã¼ã¹ã³ã¼ãããã³è§£èª¬ã¨å¯¾å¿ãã¦ãã¾ãã
heavy-endpoint
ããã®ã¨ã³ããã¤ã³ãå
¨ä½ã®ã¹ãã³(A)ããã®ä¸ã«ä¸¦ãã§ãã Heavy func: 8
, Heavy func: 3
, Heavy func: 5
ããããã superHeavyFunc
ãå¼ã³åºãã¦ããæ§åã§ã(B)ãããã«ãHeavy func: 8
ã¯5ç§ããå¦çã«æéãããã£ã¦ããããã¨ã©ã¼ã¨ãªã赤ã表示ããã¾ã(C)ã
åã¹ãã³ã«ã¯ãéå§æå»ãçµäºæå»ãå¦çæéãã¨ã©ã¼ã¡ãã»ã¼ã¸ï¼ããã°ï¼ã屿§ãè¨é²ããã¦ãã¾ãããããã®æ
å ±ããã¨ã«ãé
å»¶ãã¨ã©ã¼ã®åå ãç¹å®ã§ãã¾ããã¾ããtraceId
ãspanId
ãparentSpanId
ããããã®ã¹ãã³ã¯ã©ã®ãã¬ã¼ã¹ã®ä¸é¨ãªã®ãã親ãã©ã®ã¹ãã³ãªã®ããªã©ããããã¾ãã

otelhttp
ã©ã¤ãã©ãªã«ãã£ã¦è¨é²ãããã¨ã³ããã¤ã³ãã®ã¹ãã³(A)ã®è©³ç´°ãè¦ãã¨ãhttp.
ã net.
ã§å§ã¾ã屿§ã user_agent.original
ã¨ãã屿§ãè¨é²ããã¦ãã¾ãããã®ã¨ã³ããã¤ã³ããã©ã®ãããªãªã¯ã¨ã¹ãã§ã©ã®ãããªã¬ã¹ãã³ã¹ãè¿ããããªã©ããããã¾ãã

ã¾ããã¨ã©ã¼ã¨ãªã£ã¦ãã Heavy func: 8
ã¹ãã³(C)ã®è©³ç´°ãè¦ãã¨ãä¾å¤(exception
)ã®ã¤ãã³ããçºçããã¹ãã¼ã¿ã¹ã¯ ERROR
ã«è¨å®ãã timeout!
ã¨ããã¨ã©ã¼ã¡ãã»ã¼ã¸ã表示ããã¦ãã¾ããç¾å®ã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ã¨ã©ã¼ã®åå ã®ç¹å®ã«å½¹ç«ã¤æ
å ±ãã¨ã©ã¼ã¡ãã»ã¼ã¸ã«è¨å®ããã¨ããã§ãããã

å
¨ã¦ã®ã¹ãã³ã«å
±éãã¦è¨é²ããã¦ãããªã½ã¼ã¹ã¯ãã¬ã¼ã¹ãçæããå®ä½ã表ãã¾ããã½ã¼ã¹ã³ã¼ãä¸ã®(c)ã®é¨åã§ãã®ã¢ããªã±ã¼ã·ã§ã³ã®ããã»ã¹IDãåä½ãã¦ãããã¹ãåãè¨å®ãã¦ãã¾ããã¾ããsemconv.
ã§å§ã¾ã颿°ãç¨ãã¦è¨å®ããã¦ãã屿§ã¯ãSemantic Conventionsï¼ç¥ãã¦semconvï¼ã¨å¼ã°ããOpenTelemetryã§ç¨ããããå½åè¦ç´ã§ããããã¯ãã¬ã¼ã¹ã«éãããã¡ããªã¯ã¹ã§ãç¨ãããã¾ããsemconvã®æç¾©ã«é¢ãã¦ã¯ãOpenTelemetry Casual Talk - ã³ã³ã»ããã®ããããã¨å®è·µå
¥éï¼ãã§ã®ãOpenTelemetry ã®ãµã¼ãã¹ã¨ããæ¦å¿µã«ã¤ãã¦ãã¨ãããã¼ã¯ã§ã解説ãã¦ãã¾ãã®ã§ã覧ãã ããã

ãã¬ã¼ã·ã³ã°ãç¨ãã¦ã©ã®ããã«èª²é¡ãçºè¦ããã
ããã¾ã§è¦ã¦ããããã«ããã¬ã¼ã·ã³ã°ã¯ã¹ãã³ã«ãã£ã¦åå¦çãå¯è¦åããããããåé¡ã®ããå¦çãç´ æ©ãç¹å®ã§ããã¹ãã³ã®è©³ç´°ãè¦ããã¨ã§å¦çæéãã¨ã©ã¼ã®åå ãåæã§ãã¾ãã
ä¾ãã°ãã±ã£ã¨è¦ã§ã¹ãã³ã®å¹ ãåºããã®ãããã°è©³ç´°ãéãå¦çæéã確èªãããããã«åã¹ãã³ãè¦ã¦ãããã¨ã§å¦çã«æéã®ãããã¡ã¤ã³ãã¸ãã¯ãN+1ã«ãªã£ã¦ãã颿°å¼ã³åºããå¦çã«æéã®ãããSQLã¯ã¨ãªã®çºè¡ãªã©ãè¦ã¤ãããã¨ãã§ããããããã¾ãããã¾ããä»åã¯åä¸ã®ã·ã³ãã«ãªã¢ããªã±ã¼ã·ã§ã³ãä¾ã«ãã¾ããããåä¸ã®ã¢ããªã±ã¼ã·ã§ã³ã§ãè¦æ¨¡ã大ããã£ãããè¤æ°ã®ãã¤ã¯ããµã¼ãã¹ãããªãã·ã¹ãã ã®å ´åã¯ãå¦çã«æéãããã£ã¦ããç®æãã¨ã©ã¼ãçºçãã¦ããç®æããã°ããç¹å®ãããã¨ã®æå©ãã¨ãªãã¯ãã§ãã
ã¾ã¨ã
æ¬ã¨ã³ããªã§ã¯ãç°¡åãªWebã¢ããªã±ã¼ã·ã§ã³ã顿ã¨ãã¦ãã¬ã¼ã·ã³ã°ã®å§ãæ¹ã解説ãã¾ãããä»åãã¬ã¼ã¹ã®å¯è¦åã«ä½¿ç¨ãã忣ãã¬ã¼ã·ã³ã°ãµã¼ãã¹Vaxilaã¯ç¾å¨ç¡æã§ã使ãããã ãã¾ãã以ä¸ã®ã¨ã³ããªã«å§ãæ¹ãæ²è¼ãã¦ãã¾ãã®ã§ãã²ã試ããã ããï¼ãè¦æãä½¿ãæ¹ã®çåãªã©ãããã¾ããããWebã³ã³ã½ã¼ã«å³ä¸ã«è¡¨ç¤ºããã¦ãããµãã¼ããã¼ã ã¸é£çµ¡ãããæ°è»½ã«ãå¯ããã ããã