Created
January 24, 2026 15:01
-
-
Save chanwit/6671694140acfd34194a0a83be923d71 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "context" | |
| "encoding/json" | |
| "fmt" | |
| "io" | |
| "log" | |
| "net/http" | |
| "os" | |
| "strings" | |
| "time" | |
| "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" | |
| "go.opentelemetry.io/otel" | |
| "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" | |
| "go.opentelemetry.io/otel/propagation" | |
| "go.opentelemetry.io/otel/sdk/resource" | |
| sdktrace "go.opentelemetry.io/otel/sdk/trace" | |
| semconv "go.opentelemetry.io/otel/semconv/v1.24.0" | |
| ) | |
| type SearchResponse struct { | |
| Token string `json:"token"` | |
| Timestamp time.Time `json:"timestamp"` | |
| } | |
| type ResultResponse struct { | |
| Data string `json:"data"` | |
| Token string `json:"token"` | |
| Timestamp time.Time `json:"timestamp"` | |
| } | |
| func initTracer() (*sdktrace.TracerProvider, error) { | |
| file, err := os.Create("client_traces.json") | |
| if err != nil { | |
| return nil, err | |
| } | |
| exporter, err := stdouttrace.New( | |
| stdouttrace.WithWriter(file), | |
| ) | |
| if err != nil { | |
| return nil, err | |
| } | |
| tp := sdktrace.NewTracerProvider( | |
| sdktrace.WithBatcher(exporter), | |
| sdktrace.WithResource(resource.NewWithAttributes( | |
| semconv.SchemaURL, | |
| semconv.ServiceName("client"), | |
| )), | |
| ) | |
| otel.SetTracerProvider(tp) | |
| otel.SetTextMapPropagator(propagation.TraceContext{}) | |
| return tp, nil | |
| } | |
| func parseSpansFromFile(filename string) ([]map[string]interface{}, error) { | |
| data, err := os.ReadFile(filename) | |
| if err != nil { | |
| return nil, err | |
| } | |
| var spans []map[string]interface{} | |
| // stdouttrace outputs JSON Lines format (one span per line) | |
| lines := strings.Split(string(data), "\n") | |
| for _, line := range lines { | |
| line = strings.TrimSpace(line) | |
| if line == "" { | |
| continue | |
| } | |
| var span map[string]interface{} | |
| if err := json.Unmarshal([]byte(line), &span); err != nil { | |
| // Skip invalid lines | |
| continue | |
| } | |
| spans = append(spans, span) | |
| } | |
| return spans, nil | |
| } | |
| func mergeTraces() error { | |
| // Read and parse client traces | |
| clientSpans, err := parseSpansFromFile("client_traces.json") | |
| if err != nil { | |
| return fmt.Errorf("failed to read client traces: %w", err) | |
| } | |
| // Read and parse server traces | |
| serverSpans, err := parseSpansFromFile("server_traces.json") | |
| if err != nil { | |
| return fmt.Errorf("failed to read server traces: %w", err) | |
| } | |
| // Merge all spans into a single array | |
| allSpans := append(clientSpans, serverSpans...) | |
| // Write merged traces as JSON array | |
| outputFile, err := os.Create("traces.json") | |
| if err != nil { | |
| return fmt.Errorf("failed to create output file: %w", err) | |
| } | |
| defer outputFile.Close() | |
| encoder := json.NewEncoder(outputFile) | |
| encoder.SetIndent("", " ") | |
| if err := encoder.Encode(allSpans); err != nil { | |
| return fmt.Errorf("failed to write merged traces: %w", err) | |
| } | |
| return nil | |
| } | |
| func main() { | |
| tp, err := initTracer() | |
| if err != nil { | |
| log.Fatal("Failed to initialize tracer:", err) | |
| } | |
| // Create instrumented HTTP client | |
| client := &http.Client{ | |
| Transport: otelhttp.NewTransport(http.DefaultTransport), | |
| } | |
| tracer := otel.Tracer("client") | |
| // Wait for server to start | |
| time.Sleep(2 * time.Second) | |
| // Create root span for client workflow | |
| ctx, rootSpan := tracer.Start(context.Background(), "client-workflow") | |
| // Make search request | |
| log.Println("Making search request...") | |
| searchReq, err := http.NewRequestWithContext(ctx, "GET", "http://localhost:8080/search?q=opentelemetry", nil) | |
| if err != nil { | |
| log.Fatal("Failed to create search request:", err) | |
| } | |
| searchResp, err := client.Do(searchReq) | |
| if err != nil { | |
| log.Fatal("Search request failed:", err) | |
| } | |
| defer searchResp.Body.Close() | |
| body, err := io.ReadAll(searchResp.Body) | |
| if err != nil { | |
| log.Fatal("Failed to read search response:", err) | |
| } | |
| var searchResult SearchResponse | |
| if err := json.Unmarshal(body, &searchResult); err != nil { | |
| log.Fatal("Failed to parse search response:", err) | |
| } | |
| log.Printf("Received token: %s", searchResult.Token) | |
| // Make result request with token | |
| log.Println("Making result request...") | |
| resultReq, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://localhost:8080/result?token=%s", searchResult.Token), nil) | |
| if err != nil { | |
| log.Fatal("Failed to create result request:", err) | |
| } | |
| resultResp, err := client.Do(resultReq) | |
| if err != nil { | |
| log.Fatal("Result request failed:", err) | |
| } | |
| defer resultResp.Body.Close() | |
| body, err = io.ReadAll(resultResp.Body) | |
| if err != nil { | |
| log.Fatal("Failed to read result response:", err) | |
| } | |
| var resultData ResultResponse | |
| if err := json.Unmarshal(body, &resultData); err != nil { | |
| log.Fatal("Failed to parse result response:", err) | |
| } | |
| log.Printf("Received data: %s", resultData.Data) | |
| fmt.Println("Client completed successfully") | |
| // End root span | |
| rootSpan.End() | |
| // Flush client traces | |
| if err := tp.Shutdown(context.Background()); err != nil { | |
| log.Printf("Error shutting down tracer: %v", err) | |
| } | |
| // Use raw HTTP client (not instrumented) to call shutdown endpoint | |
| rawClient := &http.Client{Timeout: 5 * time.Second} | |
| shutdownResp, err := rawClient.Get("http://localhost:8080/shutdown") | |
| if err != nil { | |
| log.Printf("Warning: Failed to call shutdown endpoint: %v", err) | |
| } else { | |
| shutdownResp.Body.Close() | |
| } | |
| // Wait for server to flush traces | |
| time.Sleep(1 * time.Second) | |
| // Merge traces | |
| if err := mergeTraces(); err != nil { | |
| log.Printf("Warning: Failed to merge traces: %v", err) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 2026/01/24 21:56:29 Making search request... | |
| 2026/01/24 21:56:29 Received token: 7822179bacedbe74 | |
| 2026/01/24 21:56:29 Making result request... | |
| 2026/01/24 21:56:29 Received data: Results for query: opentelemetry | |
| Client completed successfully |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {"Name":"HTTP GET","SpanContext":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"32296cf8372a12a6","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"f8c2f05b612e6178","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":3,"StartTime":"2026-01-24T21:56:29.485408053+07:00","EndTime":"2026-01-24T21:56:29.537426752+07:00","Attributes":[{"Key":"http.method","Value":{"Type":"STRING","Value":"GET"}},{"Key":"http.url","Value":{"Type":"STRING","Value":"http://localhost:8080/search?q=opentelemetry"}},{"Key":"net.peer.name","Value":{"Type":"STRING","Value":"localhost"}},{"Key":"net.peer.port","Value":{"Type":"INT64","Value":8080}},{"Key":"http.status_code","Value":{"Type":"INT64","Value":200}},{"Key":"http.response_content_length","Value":{"Type":"INT64","Value":79}}],"Events":null,"Links":null,"Status":{"Code":"Unset","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"client"}}],"InstrumentationLibrary":{"Name":"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp","Version":"0.49.0","SchemaURL":""}} | |
| {"Name":"HTTP GET","SpanContext":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"4986658f466edfdd","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"f8c2f05b612e6178","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":3,"StartTime":"2026-01-24T21:56:29.537644311+07:00","EndTime":"2026-01-24T21:56:29.568934293+07:00","Attributes":[{"Key":"http.method","Value":{"Type":"STRING","Value":"GET"}},{"Key":"http.url","Value":{"Type":"STRING","Value":"http://localhost:8080/result?token=7822179bacedbe74"}},{"Key":"net.peer.name","Value":{"Type":"STRING","Value":"localhost"}},{"Key":"net.peer.port","Value":{"Type":"INT64","Value":8080}},{"Key":"http.status_code","Value":{"Type":"INT64","Value":200}},{"Key":"http.response_content_length","Value":{"Type":"INT64","Value":121}}],"Events":null,"Links":null,"Status":{"Code":"Unset","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"client"}}],"InstrumentationLibrary":{"Name":"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp","Version":"0.49.0","SchemaURL":""}} | |
| {"Name":"client-workflow","SpanContext":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"f8c2f05b612e6178","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"00000000000000000000000000000000","SpanID":"0000000000000000","TraceFlags":"00","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-01-24T21:56:29.485208033+07:00","EndTime":"2026-01-24T21:56:29.569047247+07:00","Attributes":null,"Events":null,"Links":null,"Status":{"Code":"Unset","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":2,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"client"}}],"InstrumentationLibrary":{"Name":"client","Version":"","SchemaURL":""}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "context" | |
| "crypto/sha256" | |
| "encoding/hex" | |
| "encoding/json" | |
| "fmt" | |
| "log" | |
| "net/http" | |
| "os" | |
| "os/signal" | |
| "sync" | |
| "syscall" | |
| "time" | |
| "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" | |
| "go.opentelemetry.io/otel" | |
| "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" | |
| "go.opentelemetry.io/otel/propagation" | |
| "go.opentelemetry.io/otel/sdk/resource" | |
| sdktrace "go.opentelemetry.io/otel/sdk/trace" | |
| semconv "go.opentelemetry.io/otel/semconv/v1.24.0" | |
| ) | |
| type SearchResponse struct { | |
| Token string `json:"token"` | |
| Timestamp time.Time `json:"timestamp"` | |
| } | |
| type ResultResponse struct { | |
| Data string `json:"data"` | |
| Token string `json:"token"` | |
| Timestamp time.Time `json:"timestamp"` | |
| } | |
| var ( | |
| tokenStore = make(map[string]string) | |
| mu sync.RWMutex | |
| ) | |
| func initTracer() (*sdktrace.TracerProvider, error) { | |
| file, err := os.Create("server_traces.json") | |
| if err != nil { | |
| return nil, err | |
| } | |
| exporter, err := stdouttrace.New( | |
| stdouttrace.WithWriter(file), | |
| ) | |
| if err != nil { | |
| return nil, err | |
| } | |
| tp := sdktrace.NewTracerProvider( | |
| sdktrace.WithBatcher(exporter), | |
| sdktrace.WithResource(resource.NewWithAttributes( | |
| semconv.SchemaURL, | |
| semconv.ServiceName("server"), | |
| )), | |
| ) | |
| otel.SetTracerProvider(tp) | |
| otel.SetTextMapPropagator(propagation.TraceContext{}) | |
| return tp, nil | |
| } | |
| func searchHandler(w http.ResponseWriter, r *http.Request) { | |
| query := r.URL.Query().Get("q") | |
| if query == "" { | |
| query = "default" | |
| } | |
| log.Printf("Search request received for query: %s", query) | |
| // Simulate processing | |
| time.Sleep(50 * time.Millisecond) | |
| // Generate token | |
| hash := sha256.Sum256([]byte(query + time.Now().String())) | |
| token := hex.EncodeToString(hash[:])[:16] | |
| // Store result | |
| mu.Lock() | |
| tokenStore[token] = fmt.Sprintf("Results for query: %s", query) | |
| mu.Unlock() | |
| response := SearchResponse{ | |
| Token: token, | |
| Timestamp: time.Now(), | |
| } | |
| w.Header().Set("Content-Type", "application/json") | |
| json.NewEncoder(w).Encode(response) | |
| } | |
| func resultHandler(w http.ResponseWriter, r *http.Request) { | |
| token := r.URL.Query().Get("token") | |
| if token == "" { | |
| http.Error(w, "Token required", http.StatusBadRequest) | |
| return | |
| } | |
| log.Printf("Result request received for token: %s", token) | |
| // Simulate processing | |
| time.Sleep(30 * time.Millisecond) | |
| mu.RLock() | |
| data, exists := tokenStore[token] | |
| mu.RUnlock() | |
| if !exists { | |
| http.Error(w, "Token not found", http.StatusNotFound) | |
| return | |
| } | |
| response := ResultResponse{ | |
| Data: data, | |
| Token: token, | |
| Timestamp: time.Now(), | |
| } | |
| w.Header().Set("Content-Type", "application/json") | |
| json.NewEncoder(w).Encode(response) | |
| } | |
| var ( | |
| shutdownChan = make(chan struct{}) | |
| tracerProvider *sdktrace.TracerProvider | |
| ) | |
| func shutdownHandler(w http.ResponseWriter, r *http.Request) { | |
| log.Println("Shutdown request received") | |
| w.WriteHeader(http.StatusOK) | |
| w.Write([]byte("OK")) | |
| // Signal shutdown after response is sent | |
| go func() { | |
| time.Sleep(100 * time.Millisecond) | |
| close(shutdownChan) | |
| }() | |
| } | |
| func main() { | |
| tp, err := initTracer() | |
| if err != nil { | |
| log.Fatal("Failed to initialize tracer:", err) | |
| } | |
| tracerProvider = tp | |
| // Set up signal handling for graceful shutdown | |
| sigChan := make(chan os.Signal, 1) | |
| signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) | |
| // Wrap handlers with otelhttp to extract trace context and create server spans | |
| searchOtelHandler := otelhttp.NewHandler(http.HandlerFunc(searchHandler), "/search") | |
| resultOtelHandler := otelhttp.NewHandler(http.HandlerFunc(resultHandler), "/result") | |
| http.Handle("/search", searchOtelHandler) | |
| http.Handle("/result", resultOtelHandler) | |
| // Shutdown endpoint - not instrumented to avoid extra spans | |
| http.HandleFunc("/shutdown", shutdownHandler) | |
| server := &http.Server{Addr: ":8080"} | |
| go func() { | |
| select { | |
| case <-sigChan: | |
| log.Println("Received signal, shutting down...") | |
| case <-shutdownChan: | |
| log.Println("Shutdown requested via API...") | |
| } | |
| // Flush traces first | |
| if err := tp.Shutdown(context.Background()); err != nil { | |
| log.Printf("Error shutting down tracer: %v", err) | |
| } | |
| // Shutdown the HTTP server | |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | |
| defer cancel() | |
| server.Shutdown(ctx) | |
| }() | |
| log.Println("Server starting on :8080") | |
| if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { | |
| log.Fatal(err) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 2026/01/24 21:56:25 Server starting on :8080 | |
| 2026/01/24 21:56:29 Search request received for query: opentelemetry | |
| 2026/01/24 21:56:29 Result request received for token: 7822179bacedbe74 | |
| 2026/01/24 21:56:29 Shutdown request received | |
| 2026/01/24 21:56:29 Shutdown requested via API... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {"Name":"/search","SpanContext":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"ce52397dc050e001","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"32296cf8372a12a6","TraceFlags":"01","TraceState":"","Remote":true},"SpanKind":2,"StartTime":"2026-01-24T21:56:29.486199862+07:00","EndTime":"2026-01-24T21:56:29.536882424+07:00","Attributes":[{"Key":"http.method","Value":{"Type":"STRING","Value":"GET"}},{"Key":"http.scheme","Value":{"Type":"STRING","Value":"http"}},{"Key":"net.host.name","Value":{"Type":"STRING","Value":"localhost"}},{"Key":"net.host.port","Value":{"Type":"INT64","Value":8080}},{"Key":"net.sock.peer.addr","Value":{"Type":"STRING","Value":"127.0.0.1"}},{"Key":"net.sock.peer.port","Value":{"Type":"INT64","Value":56696}},{"Key":"user_agent.original","Value":{"Type":"STRING","Value":"Go-http-client/1.1"}},{"Key":"http.target","Value":{"Type":"STRING","Value":"/search"}},{"Key":"net.protocol.version","Value":{"Type":"STRING","Value":"1.1"}},{"Key":"http.wrote_bytes","Value":{"Type":"INT64","Value":79}},{"Key":"http.status_code","Value":{"Type":"INT64","Value":200}}],"Events":null,"Links":null,"Status":{"Code":"Unset","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"server"}}],"InstrumentationLibrary":{"Name":"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp","Version":"0.49.0","SchemaURL":""}} | |
| {"Name":"/result","SpanContext":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"abb4289b11b6d83a","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"adcf39e2704f6657367473d1477ca759","SpanID":"4986658f466edfdd","TraceFlags":"01","TraceState":"","Remote":true},"SpanKind":2,"StartTime":"2026-01-24T21:56:29.538010494+07:00","EndTime":"2026-01-24T21:56:29.568429147+07:00","Attributes":[{"Key":"http.method","Value":{"Type":"STRING","Value":"GET"}},{"Key":"http.scheme","Value":{"Type":"STRING","Value":"http"}},{"Key":"net.host.name","Value":{"Type":"STRING","Value":"localhost"}},{"Key":"net.host.port","Value":{"Type":"INT64","Value":8080}},{"Key":"net.sock.peer.addr","Value":{"Type":"STRING","Value":"127.0.0.1"}},{"Key":"net.sock.peer.port","Value":{"Type":"INT64","Value":56696}},{"Key":"user_agent.original","Value":{"Type":"STRING","Value":"Go-http-client/1.1"}},{"Key":"http.target","Value":{"Type":"STRING","Value":"/result"}},{"Key":"net.protocol.version","Value":{"Type":"STRING","Value":"1.1"}},{"Key":"http.wrote_bytes","Value":{"Type":"INT64","Value":121}},{"Key":"http.status_code","Value":{"Type":"INT64","Value":200}}],"Events":null,"Links":null,"Status":{"Code":"Unset","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"server"}}],"InstrumentationLibrary":{"Name":"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp","Version":"0.49.0","SchemaURL":""}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [ | |
| { | |
| "Attributes": [ | |
| { | |
| "Key": "http.method", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "GET" | |
| } | |
| }, | |
| { | |
| "Key": "http.url", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "http://localhost:8080/search?q=opentelemetry" | |
| } | |
| }, | |
| { | |
| "Key": "net.peer.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "localhost" | |
| } | |
| }, | |
| { | |
| "Key": "net.peer.port", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 8080 | |
| } | |
| }, | |
| { | |
| "Key": "http.status_code", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 200 | |
| } | |
| }, | |
| { | |
| "Key": "http.response_content_length", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 79 | |
| } | |
| } | |
| ], | |
| "ChildSpanCount": 0, | |
| "DroppedAttributes": 0, | |
| "DroppedEvents": 0, | |
| "DroppedLinks": 0, | |
| "EndTime": "2026-01-24T21:56:29.537426752+07:00", | |
| "Events": null, | |
| "InstrumentationLibrary": { | |
| "Name": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", | |
| "SchemaURL": "", | |
| "Version": "0.49.0" | |
| }, | |
| "Links": null, | |
| "Name": "HTTP GET", | |
| "Parent": { | |
| "Remote": false, | |
| "SpanID": "f8c2f05b612e6178", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "Resource": [ | |
| { | |
| "Key": "service.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "client" | |
| } | |
| } | |
| ], | |
| "SpanContext": { | |
| "Remote": false, | |
| "SpanID": "32296cf8372a12a6", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "SpanKind": 3, | |
| "StartTime": "2026-01-24T21:56:29.485408053+07:00", | |
| "Status": { | |
| "Code": "Unset", | |
| "Description": "" | |
| } | |
| }, | |
| { | |
| "Attributes": [ | |
| { | |
| "Key": "http.method", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "GET" | |
| } | |
| }, | |
| { | |
| "Key": "http.url", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "http://localhost:8080/result?token=7822179bacedbe74" | |
| } | |
| }, | |
| { | |
| "Key": "net.peer.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "localhost" | |
| } | |
| }, | |
| { | |
| "Key": "net.peer.port", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 8080 | |
| } | |
| }, | |
| { | |
| "Key": "http.status_code", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 200 | |
| } | |
| }, | |
| { | |
| "Key": "http.response_content_length", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 121 | |
| } | |
| } | |
| ], | |
| "ChildSpanCount": 0, | |
| "DroppedAttributes": 0, | |
| "DroppedEvents": 0, | |
| "DroppedLinks": 0, | |
| "EndTime": "2026-01-24T21:56:29.568934293+07:00", | |
| "Events": null, | |
| "InstrumentationLibrary": { | |
| "Name": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", | |
| "SchemaURL": "", | |
| "Version": "0.49.0" | |
| }, | |
| "Links": null, | |
| "Name": "HTTP GET", | |
| "Parent": { | |
| "Remote": false, | |
| "SpanID": "f8c2f05b612e6178", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "Resource": [ | |
| { | |
| "Key": "service.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "client" | |
| } | |
| } | |
| ], | |
| "SpanContext": { | |
| "Remote": false, | |
| "SpanID": "4986658f466edfdd", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "SpanKind": 3, | |
| "StartTime": "2026-01-24T21:56:29.537644311+07:00", | |
| "Status": { | |
| "Code": "Unset", | |
| "Description": "" | |
| } | |
| }, | |
| { | |
| "Attributes": null, | |
| "ChildSpanCount": 2, | |
| "DroppedAttributes": 0, | |
| "DroppedEvents": 0, | |
| "DroppedLinks": 0, | |
| "EndTime": "2026-01-24T21:56:29.569047247+07:00", | |
| "Events": null, | |
| "InstrumentationLibrary": { | |
| "Name": "client", | |
| "SchemaURL": "", | |
| "Version": "" | |
| }, | |
| "Links": null, | |
| "Name": "client-workflow", | |
| "Parent": { | |
| "Remote": false, | |
| "SpanID": "0000000000000000", | |
| "TraceFlags": "00", | |
| "TraceID": "00000000000000000000000000000000", | |
| "TraceState": "" | |
| }, | |
| "Resource": [ | |
| { | |
| "Key": "service.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "client" | |
| } | |
| } | |
| ], | |
| "SpanContext": { | |
| "Remote": false, | |
| "SpanID": "f8c2f05b612e6178", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "SpanKind": 1, | |
| "StartTime": "2026-01-24T21:56:29.485208033+07:00", | |
| "Status": { | |
| "Code": "Unset", | |
| "Description": "" | |
| } | |
| }, | |
| { | |
| "Attributes": [ | |
| { | |
| "Key": "http.method", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "GET" | |
| } | |
| }, | |
| { | |
| "Key": "http.scheme", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "http" | |
| } | |
| }, | |
| { | |
| "Key": "net.host.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "localhost" | |
| } | |
| }, | |
| { | |
| "Key": "net.host.port", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 8080 | |
| } | |
| }, | |
| { | |
| "Key": "net.sock.peer.addr", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "127.0.0.1" | |
| } | |
| }, | |
| { | |
| "Key": "net.sock.peer.port", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 56696 | |
| } | |
| }, | |
| { | |
| "Key": "user_agent.original", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "Go-http-client/1.1" | |
| } | |
| }, | |
| { | |
| "Key": "http.target", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "/search" | |
| } | |
| }, | |
| { | |
| "Key": "net.protocol.version", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "1.1" | |
| } | |
| }, | |
| { | |
| "Key": "http.wrote_bytes", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 79 | |
| } | |
| }, | |
| { | |
| "Key": "http.status_code", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 200 | |
| } | |
| } | |
| ], | |
| "ChildSpanCount": 0, | |
| "DroppedAttributes": 0, | |
| "DroppedEvents": 0, | |
| "DroppedLinks": 0, | |
| "EndTime": "2026-01-24T21:56:29.536882424+07:00", | |
| "Events": null, | |
| "InstrumentationLibrary": { | |
| "Name": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", | |
| "SchemaURL": "", | |
| "Version": "0.49.0" | |
| }, | |
| "Links": null, | |
| "Name": "/search", | |
| "Parent": { | |
| "Remote": true, | |
| "SpanID": "32296cf8372a12a6", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "Resource": [ | |
| { | |
| "Key": "service.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "server" | |
| } | |
| } | |
| ], | |
| "SpanContext": { | |
| "Remote": false, | |
| "SpanID": "ce52397dc050e001", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "SpanKind": 2, | |
| "StartTime": "2026-01-24T21:56:29.486199862+07:00", | |
| "Status": { | |
| "Code": "Unset", | |
| "Description": "" | |
| } | |
| }, | |
| { | |
| "Attributes": [ | |
| { | |
| "Key": "http.method", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "GET" | |
| } | |
| }, | |
| { | |
| "Key": "http.scheme", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "http" | |
| } | |
| }, | |
| { | |
| "Key": "net.host.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "localhost" | |
| } | |
| }, | |
| { | |
| "Key": "net.host.port", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 8080 | |
| } | |
| }, | |
| { | |
| "Key": "net.sock.peer.addr", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "127.0.0.1" | |
| } | |
| }, | |
| { | |
| "Key": "net.sock.peer.port", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 56696 | |
| } | |
| }, | |
| { | |
| "Key": "user_agent.original", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "Go-http-client/1.1" | |
| } | |
| }, | |
| { | |
| "Key": "http.target", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "/result" | |
| } | |
| }, | |
| { | |
| "Key": "net.protocol.version", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "1.1" | |
| } | |
| }, | |
| { | |
| "Key": "http.wrote_bytes", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 121 | |
| } | |
| }, | |
| { | |
| "Key": "http.status_code", | |
| "Value": { | |
| "Type": "INT64", | |
| "Value": 200 | |
| } | |
| } | |
| ], | |
| "ChildSpanCount": 0, | |
| "DroppedAttributes": 0, | |
| "DroppedEvents": 0, | |
| "DroppedLinks": 0, | |
| "EndTime": "2026-01-24T21:56:29.568429147+07:00", | |
| "Events": null, | |
| "InstrumentationLibrary": { | |
| "Name": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp", | |
| "SchemaURL": "", | |
| "Version": "0.49.0" | |
| }, | |
| "Links": null, | |
| "Name": "/result", | |
| "Parent": { | |
| "Remote": true, | |
| "SpanID": "4986658f466edfdd", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "Resource": [ | |
| { | |
| "Key": "service.name", | |
| "Value": { | |
| "Type": "STRING", | |
| "Value": "server" | |
| } | |
| } | |
| ], | |
| "SpanContext": { | |
| "Remote": false, | |
| "SpanID": "abb4289b11b6d83a", | |
| "TraceFlags": "01", | |
| "TraceID": "adcf39e2704f6657367473d1477ca759", | |
| "TraceState": "" | |
| }, | |
| "SpanKind": 2, | |
| "StartTime": "2026-01-24T21:56:29.538010494+07:00", | |
| "Status": { | |
| "Code": "Unset", | |
| "Description": "" | |
| } | |
| } | |
| ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment