Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Migrasi ke Go OpenTelemetry
Gunakan contoh kode berikut untuk mengarahkan aplikasi Go Anda secara manual dengan OpenTelemetry SDK saat bermigrasi dari X-Ray.
Instrumentasi manual dengan SDK
- Tracing setup with X-Ray SDK
-
Saat menggunakan X-Ray SDK for Go, plugin layanan atau aturan pengambilan sampel lokal harus dikonfigurasi sebelum menginstrumentasi kode Anda.
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
-
Konfigurasikan OpenTelemetry SDK dengan membuat instance TracerProvider dan mendaftarkannya sebagai penyedia pelacak global. Kami merekomendasikan untuk mengonfigurasi komponen-komponen berikut:
-
OTLP Trace Exporter - Diperlukan untuk mengekspor jejak ke Agen atau Kolektor CloudWatch OpenTelemetry
-
X-Ray Propagator — Diperlukan untuk menyebarkan konteks jejak ke AWS layanan yang terintegrasi dengan X-Ray
-
X-Ray Remote Sampler — Diperlukan untuk permintaan sampling menggunakan aturan sampling X-Ray
-
Detektor sumber daya - Untuk mendeteksi metadata host yang menjalankan aplikasi Anda
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 }
-
Menelusuri permintaan yang masuk (instrumentasi penangan HTTP)
- With X-Ray SDK
-
Untuk instrumen handler HTTP dengan X-Ray, metode handler X-Ray digunakan untuk menghasilkan segmen menggunakan. 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
Untuk instrumen handler HTTP dengan OpenTelemetry, gunakan metode NewHandler untuk membungkus kode handler asli Anda. OpenTelemetry
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 Instrumentasi SDK for Go v2
- With X-Ray SDK
-
Untuk menginstrumentasi AWS permintaan keluar dari AWS SDK, klien Anda diinstrumentasi sebagai berikut:
// 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
-
Menelusuri dukungan untuk panggilan AWS SDK hilir disediakan oleh SDK for AWS Go OpenTelemetry v2 Instrumentation. Berikut adalah contoh penelusuran panggilan klien 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 }
Instrumentasi panggilan HTTP keluar
- With X-Ray SDK
-
Untuk instrumen panggilan HTTP keluar dengan X-Ray, Xray.client digunakan untuk membuat salinan klien HTTP yang disediakan.
myClient := xray.Client(http-client) resp, err := ctxhttp.Get(ctx, xray.Client(nil), url)
- With OpenTelemetry SDK
-
Untuk instrumen klien HTTP dengan OpenTelemetry, gunakan OpenTelemetry otelhttp. NewTransport metode untuk membungkus 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)
Dukungan instrumentasi untuk perpustakaan lain
Anda dapat menemukan daftar lengkap instrumentasi pustaka yang didukung untuk OpenTelemetry Go di bawah paket Instrumentasi
Atau, Anda dapat mencari OpenTelemetry registri untuk mengetahui apakah OpenTelemetry mendukung instrumentasi untuk perpustakaan Anda di bawah Registry
Membuat data jejak secara manual
- With X-Ray SDK
-
Dengan X-Ray SDK, BeginSubsegment metode BeginSegment dan diperlukan untuk membuat segmen dan sub-segmen X-Ray secara manual.
// 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
Gunakan rentang kustom untuk memantau kinerja aktivitas internal yang tidak ditangkap oleh pustaka instrumentasi. Perhatikan bahwa hanya rentang jenis Server yang diubah menjadi segmen X-Ray, semua rentang lainnya diubah menjadi sub-segmen X-Ray.
Pertama, Anda perlu membuat Tracer untuk menghasilkan bentang, yang dapat Anda peroleh melalui metode ini
otel.Tracer
. Ini akan memberikan instance Tracer dari TracerProvider yang terdaftar secara global dalam contoh Tracing Setup. Anda dapat membuat instance Tracer sebanyak yang diperlukan, tetapi biasanya memiliki satu Tracer untuk seluruh aplikasi.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()
Menambahkan anotasi dan metadata ke jejak dengan SDK OpenTelemetry
Dalam contoh di atas,
WithAttributes
metode ini digunakan untuk menambahkan atribut ke setiap rentang. Perhatikan bahwa secara default, semua atribut rentang diubah menjadi metadata dalam data mentah X-Ray. Untuk memastikan bahwa atribut diubah menjadi anotasi dan bukan metadata, tambahkan kunci atribut ke daftar atribut.aws.xray.annotations
Untuk informasi selengkapnya, lihat Mengaktifkan Anotasi X-Ray yang Disesuaikan.
Instrumentasi manual Lambda
- With X-Ray SDK
-
Dengan X-Ray SDK, setelah Lambda Anda mengaktifkan Active Tracing, tidak ada konfigurasi tambahan yang diperlukan untuk menggunakan X-Ray SDK. Lambda membuat segmen yang mewakili pemanggilan penangan Lambda, dan Anda membuat sub-segmen menggunakan X-Ray SDK tanpa konfigurasi tambahan.
- With OpenTelemetry SDK
-
Kode fungsi Lambda berikut (tanpa instrumentasi) membuat ListBuckets panggilan Amazon S3 dan permintaan HTTP keluar.
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) }
Untuk menginstruksikan handler Lambda Anda dan klien Amazon S3 secara manual, lakukan hal berikut:
-
Di main (), buat instance a TracerProvider (tp) dan daftarkan sebagai penyedia pelacak global. TracerProvider Disarankan untuk dikonfigurasi dengan:
-
Prosesor Rentang Sederhana dengan eksportir rentang UDP X-Ray untuk mengirim Jejak ke titik akhir X-Ray UDP Lambda
-
Sumber daya dengan service.name disetel ke nama fungsi Lambda
-
-
Ubah penggunaan
lambda.Start(lambdaHandler)
kelambda.Start(otellambda.InstrumentHandler(lambdaHandler, xrayconfig.WithRecommendedOptions(tp)...))
. -
Instrumentasikan klien Amazon S3 dengan instrumentasi OpenTemetry AWS SDK dengan menambahkan OpenTelemetry middleware ke dalam
aws-sdk-go-v2
konfigurasi klien Amazon S3. -
Instrumen klien http dengan menggunakan OpenTelemetry
otelhttp.NewTransport
metode untuk membungkushttp.DefaultTransport
.
Kode berikut adalah contoh bagaimana Fungsi Lambda akan terlihat seperti setelah perubahan. Anda dapat secara manual membuat rentang kustom tambahan selain rentang yang disediakan secara otomatis.
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)...)) }
-
Saat memanggil Lambda, Anda akan melihat jejak berikut Trace Map
di CloudWatch konsol:
