Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Esegui la migrazione a OpenTelemetry Go
Usa i seguenti esempi di codice per strumentare manualmente le tue applicazioni Go con l' OpenTelemetry SDK durante la migrazione da X-Ray.
Strumentazione manuale con l'SDK
- Tracing setup with X-Ray SDK
-
Quando si utilizzava X-Ray SDK for Go, era necessario configurare i plug-in di servizio o le regole di campionamento locali prima di utilizzare la strumentazione del codice.
func init() { if os.Getenv("ENVIRONMENT") == "production" { ec2.Init() } xray.Configure(xray.Config{ DaemonAddr: "127.0.0.1:2000", ServiceVersion: "1.2.3", }) }
- Set up tracing with OpenTelemetry SDK
-
Configura l' OpenTelemetry SDK creando un'istanza e registrandolo come provider di tracciamento globale TracerProvider . Ti consigliamo di configurare i seguenti componenti:
-
OTLP Trace Exporter: necessario per esportare le tracce nell'agente o nel raccoglitore CloudWatch OpenTelemetry
-
X-Ray Propagator: necessario per propagare il contesto di traccia ai AWS servizi integrati con X-Ray
-
X-Ray Remote Sampler: necessario per le richieste di campionamento che utilizzano le regole di campionamento a raggi X
-
Rilevatori di risorse: per rilevare i metadati dell'host che esegue l'applicazione
import ( "go.opentelemetry.io/contrib/detectors/aws/ec2" "go.opentelemetry.io/contrib/propagators/aws/xray" "go.opentelemetry.io/contrib/samplers/aws/xray" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/sdk/trace" ) func setupTracing() error { ctx := context.Background() exporterEndpoint := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") if exporterEndpoint == "" { exporterEndpoint = "localhost:4317" } traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint(exporterEndpoint)) if err != nil { return fmt.Errorf("failed to create OTLP trace exporter: %v", err) } remoteSampler, err := xray.NewRemoteSampler(ctx, "my-service-name", "ec2") if err != nil { return fmt.Errorf("failed to create X-Ray Remote Sampler: %v", err) } ec2Resource, err := ec2.NewResourceDetector().Detect(ctx) if err != nil { return fmt.Errorf("failed to detect EC2 resource: %v", err) } tp := trace.NewTracerProvider( trace.WithSampler(remoteSampler), trace.WithBatcher(traceExporter), trace.WithResource(ec2Resource), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(xray.Propagator{}) return nil }
-
Tracciamento delle richieste in arrivo (strumentazione del gestore HTTP)
- With X-Ray SDK
-
Per strumentare un gestore HTTP con X-Ray, è stato utilizzato il metodo del gestore X-Ray per generare segmenti utilizzando. NewFixedSegmentNamer
func main() { http.Handle("/", xray.Handler(xray.NewFixedSegmentNamer("myApp"), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello!")) }))) http.ListenAndServe(":8000", nil) }
- With OpenTelemetry SDK
Per strumentare un gestore HTTP OpenTelemetry, utilizzate il metodo NewHandler per racchiudere il codice OpenTelemetry del gestore originale.
import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) helloHandler := func(w http.ResponseWriter, req *http.Request) { ctx := req.Context() span := trace.SpanFromContext(ctx) span.SetAttributes(attribute.Bool("isHelloHandlerSpan", true), attribute.String("attrKey", "attrValue")) _, _ = io.WriteString(w, "Hello World!\n") } otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello") http.Handle("/hello", otelHandler) err = http.ListenAndServe(":8080", nil) if err != nil { log.Fatal(err) }
AWS SDK per strumentazione Go v2
- With X-Ray SDK
-
Per gestire le AWS richieste in uscita da AWS SDK, i vostri clienti hanno utilizzato la seguente strumentazione:
// Create a segment ctx, root := xray.BeginSegment(context.TODO(), "AWSSDKV2_Dynamodb") defer root.Close(nil) cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-west-2")) if err != nil { log.Fatalf("unable to load SDK config, %v", err) } // Instrumenting AWS SDK v2 awsv2.AWSV2Instrumentor(&cfg.APIOptions) // Using the Config value, create the DynamoDB client svc := dynamodb.NewFromConfig(cfg) // Build the request with its input parameters _, err = svc.ListTables(ctx, &dynamodb.ListTablesInput{ Limit: aws.Int32(5), }) if err != nil { log.Fatalf("failed to list tables, %v", err) }
- With OpenTelemetry SDK
-
Il supporto di tracciamento per le chiamate AWS SDK downstream è fornito da SDK for AWS Go OpenTelemetry v2 Instrumentation. Ecco un esempio di tracciamento di una chiamata client S3:
import ( ... "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "go.opentelemetry.io/otel" oteltrace "go.opentelemetry.io/otel/trace" awsConfig "github.com/aws/aws-sdk-go-v2/config" "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws" ) ... // init aws config cfg, err := awsConfig.LoadDefaultConfig(ctx) if err != nil { panic("configuration error, " + err.Error()) } // instrument all aws clients otelaws.AppendMiddlewares(&.APIOptions) // Call to S3 s3Client := s3.NewFromConfig(cfg) input := &s3.ListBucketsInput{} result, err := s3Client.ListBuckets(ctx, input) if err != nil { fmt.Printf("Got an error retrieving buckets, %v", err) return }
Analisi delle chiamate HTTP in uscita
- With X-Ray SDK
-
Per strumentare le chiamate HTTP in uscita con X-Ray, XRay.Client è stato utilizzato per creare una copia di un client HTTP fornito.
myClient := xray.Client(http-client) resp, err := ctxhttp.Get(ctx, xray.Client(nil), url)
- With OpenTelemetry SDK
-
Per strumentare i client HTTP, usa's otelhttp. OpenTelemetry OpenTelemetry NewTransport metodo per avvolgere l'http. DefaultTransport.
import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" ) // Create an instrumented HTTP client. httpClient := &http.Client{ Transport: otelhttp.NewTransport( http.DefaultTransport, ), } req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.github.com/repos/aws-observability/aws-otel-go/releases/latest", nil) if err != nil { fmt.Printf("failed to create http request, %v\n", err) } res, err := httpClient.Do(req) if err != nil { fmt.Printf("failed to make http request, %v\n", err) } // Request body must be closed defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { fmt.Printf("failed to close http response body, %v\n", err) } }(res.Body)
Supporto alla strumentazione per altre librerie
Creazione manuale di dati di traccia
- With X-Ray SDK
-
Con X-Ray SDK, erano necessari i BeginSubsegment metodi BeginSegment and per creare manualmente segmenti e sottosegmenti X-Ray.
// Start a segment ctx, seg := xray.BeginSegment(context.Background(), "service-name") // Start a subsegment subCtx, subSeg := xray.BeginSubsegment(ctx, "subsegment-name") // Add metadata or annotation here if necessary xray.AddAnnotation(subCtx, "annotationKey", "annotationValue") xray.AddMetadata(subCtx, "metadataKey", "metadataValue") subSeg.Close(nil) // Close the segment seg.Close(nil)
- With OpenTelemetry SDK
Utilizza intervalli personalizzati per monitorare le prestazioni delle attività interne che non vengono acquisite dalle librerie di strumentazione. Nota che solo gli intervalli di tipo Server vengono convertiti in segmenti X-Ray, tutti gli altri intervalli vengono convertiti in sottosegmenti X-Ray.
Innanzitutto, è necessario creare un Tracer per generare intervalli, che è possibile ottenere tramite il metodo.
otel.Tracer
Ciò fornirà un'istanza Tracer tra quelle registrate globalmente nell'esempio di Tracing Setup. TracerProvider È possibile creare tutte le istanze Tracer necessarie, ma è comune avere una sola istanza Tracer per un'intera applicazione.tracer := otel.Tracer("application-tracer")
import ( ... oteltrace "go.opentelemetry.io/otel/trace" ) ... var attributes = []attribute.KeyValue{ attribute.KeyValue{Key: "metadataKey", Value: attribute.StringValue("metadataValue")}, attribute.KeyValue{Key: "annotationKey", Value: attribute.StringValue("annotationValue")}, attribute.KeyValue{Key: "aws.xray.annotations", Value: attribute.StringSliceValue([]string{"annotationKey"})}, } ctx := context.Background() parentSpanContext, parentSpan := tracer.Start(ctx, "ParentSpan", oteltrace.WithSpanKind(oteltrace.SpanKindServer), oteltrace.WithAttributes(attributes...)) _, childSpan := tracer.Start(parentSpanContext, "ChildSpan", oteltrace.WithSpanKind(oteltrace.SpanKindInternal)) // ... childSpan.End() parentSpan.End()
Aggiungere annotazioni e metadati alle tracce con SDK OpenTelemetry
Nell'esempio precedente, il
WithAttributes
metodo viene utilizzato per aggiungere attributi a ogni intervallo. Si noti che per impostazione predefinita, tutti gli attributi span vengono convertiti in metadati nei dati grezzi X-Ray. Per garantire che un attributo venga convertito in un'annotazione e non in metadati, aggiungete la chiave dell'attributo all'elenco dell'attributo.aws.xray.annotations
Per ulteriori informazioni, vedere Abilitare le annotazioni X-Ray personalizzate.
Strumentazione manuale Lambda
- With X-Ray SDK
-
Con l'SDK X-Ray, dopo aver abilitato l'Active Tracing in Lambda, non erano necessarie configurazioni aggiuntive per utilizzare l'SDK X-Ray. Lambda ha creato un segmento che rappresenta l'invocazione del gestore Lambda e tu hai creato dei sottosegmenti utilizzando X-Ray SDK senza alcuna configurazione aggiuntiva.
- With OpenTelemetry SDK
-
Il seguente codice di funzione Lambda (senza strumentazione) effettua una chiamata Amazon S3 e una richiesta HTTP in uscita ListBuckets .
package main import ( "context" "encoding/json" "fmt" "io" "net/http" "os" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" ) func lambdaHandler(ctx context.Context) (interface{}, error) { // Initialize AWS config. cfg, err := awsconfig.LoadDefaultConfig(ctx) if err != nil { panic("configuration error, " + err.Error()) } s3Client := s3.NewFromConfig(cfg) // Create an HTTP client. httpClient := &http.Client{ Transport: http.DefaultTransport, } input := &s3.ListBucketsInput{} result, err := s3Client.ListBuckets(ctx, input) if err != nil { fmt.Printf("Got an error retrieving buckets, %v", err) } fmt.Println("Buckets:") for _, bucket := range result.Buckets { fmt.Println(*bucket.Name + ": " + bucket.CreationDate.Format("2006-01-02 15:04:05 Monday")) } fmt.Println("End Buckets.") req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.github.com/repos/aws-observability/aws-otel-go/releases/latest", nil) if err != nil { fmt.Printf("failed to create http request, %v\n", err) } res, err := httpClient.Do(req) if err != nil { fmt.Printf("failed to make http request, %v\n", err) } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { fmt.Printf("failed to close http response body, %v\n", err) } }(res.Body) var data map[string]interface{} err = json.NewDecoder(res.Body).Decode(&data) if err != nil { fmt.Printf("failed to read http response body, %v\n", err) } fmt.Printf("Latest ADOT Go Release is '%s'\n", data["name"]) return events.APIGatewayProxyResponse{ StatusCode: http.StatusOK, Body: os.Getenv("_X_AMZN_TRACE_ID"), }, nil } func main() { lambda.Start(lambdaHandler) }
Per strumentare manualmente il gestore Lambda e il client Amazon S3, procedi come segue:
-
In main (), crea un'istanza a TracerProvider (tp) e registralo come fornitore di soluzioni di tracciamento globale. Si TracerProvider consiglia di configurarlo con:
-
Simple Span Processor con un esportatore di span UDP a raggi X per inviare tracce all'endpoint UDP X-Ray di Lambda
-
Risorsa con service.name impostato sul nome della funzione Lambda
-
-
Cambia l'utilizzo di to.
lambda.Start(lambdaHandler)
lambda.Start(otellambda.InstrumentHandler(lambdaHandler, xrayconfig.WithRecommendedOptions(tp)...))
-
Strumenta il client Amazon S3 con la strumentazione OpenTemetry AWS SDK aggiungendo OpenTelemetry middleware per
aws-sdk-go-v2
nella configurazione del client Amazon S3. -
Strumenta il client http utilizzando il metodo's per avvolgere il. OpenTelemetry
otelhttp.NewTransport
http.DefaultTransport
Il codice seguente è un esempio di come apparirà la funzione Lambda dopo le modifiche. È possibile creare manualmente intervalli personalizzati aggiuntivi oltre agli intervalli forniti automaticamente.
package main import ( "context" "encoding/json" "fmt" "io" "net/http" "os" "github.com/aws-observability/aws-otel-go/exporters/xrayudp" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" lambdadetector "go.opentelemetry.io/contrib/detectors/aws/lambda" "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-lambda-go/otellambda" "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-lambda-go/otellambda/xrayconfig" "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/contrib/propagators/aws/xray" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.26.0" ) func lambdaHandler(ctx context.Context) (interface{}, error) { // Initialize AWS config. cfg, err := awsconfig.LoadDefaultConfig(ctx) if err != nil { panic("configuration error, " + err.Error()) } // Instrument all AWS clients. otelaws.AppendMiddlewares(&cfg.APIOptions) // Create an instrumented S3 client from the config. s3Client := s3.NewFromConfig(cfg) // Create an instrumented HTTP client. httpClient := &http.Client{ Transport: otelhttp.NewTransport( http.DefaultTransport, ), } // return func(ctx context.Context) (interface{}, error) { input := &s3.ListBucketsInput{} result, err := s3Client.ListBuckets(ctx, input) if err != nil { fmt.Printf("Got an error retrieving buckets, %v", err) } fmt.Println("Buckets:") for _, bucket := range result.Buckets { fmt.Println(*bucket.Name + ": " + bucket.CreationDate.Format("2006-01-02 15:04:05 Monday")) } fmt.Println("End Buckets.") req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.github.com/repos/aws-observability/aws-otel-go/releases/latest", nil) if err != nil { fmt.Printf("failed to create http request, %v\n", err) } res, err := httpClient.Do(req) if err != nil { fmt.Printf("failed to make http request, %v\n", err) } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { fmt.Printf("failed to close http response body, %v\n", err) } }(res.Body) var data map[string]interface{} err = json.NewDecoder(res.Body).Decode(&data) if err != nil { fmt.Printf("failed to read http response body, %v\n", err) } fmt.Printf("Latest ADOT Go Release is '%s'\n", data["name"]) return events.APIGatewayProxyResponse{ StatusCode: http.StatusOK, Body: os.Getenv("_X_AMZN_TRACE_ID"), }, nil } func main() { ctx := context.Background() detector := lambdadetector.NewResourceDetector() lambdaResource, err := detector.Detect(context.Background()) if err != nil { fmt.Printf("failed to detect lambda resources: %v\n", err) } var attributes = []attribute.KeyValue{ attribute.KeyValue{Key: semconv.ServiceNameKey, Value: attribute.StringValue(os.Getenv("AWS_LAMBDA_FUNCTION_NAME"))}, } customResource := resource.NewWithAttributes(semconv.SchemaURL, attributes...) mergedResource, _ := resource.Merge(lambdaResource, customResource) xrayUdpExporter, _ := xrayudp.NewSpanExporter(ctx) tp := trace.NewTracerProvider( trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(xrayUdpExporter)), trace.WithResource(mergedResource), ) defer func(ctx context.Context) { err := tp.Shutdown(ctx) if err != nil { fmt.Printf("error shutting down tracer provider: %v", err) } }(ctx) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(xray.Propagator{}) lambda.Start(otellambda.InstrumentHandler(lambdaHandler, xrayconfig.WithRecommendedOptions(tp)...)) }
-
Quando richiami Lambda, vedrai la seguente traccia Trace Map
nella CloudWatch console:
