Skip to content
Last9
Book demo

AWS SDK v2

Instrument AWS SDK v2 Go applications with the Last9 Go Agent for automatic service call tracing

Use the Last9 Go Agent to instrument AWS SDK v2 calls with automatic tracing. Every SDK call — S3, DynamoDB, SQS, SNS, Lambda, and others — produces a span with attributes for the AWS service, operation, region, and request ID. Per-service attributes (e.g. DynamoDB table name, SQS queue URL) are captured automatically.

Prerequisites

  • Go 1.22 or higher
  • AWS SDK v2 (github.com/aws/aws-sdk-go-v2)
  • Last9 account with OTLP credentials

Installation

  1. Install the Last9 Go Agent

    go get github.com/last9/go-agent
  2. Set Environment Variables

    export OTEL_SERVICE_NAME="your-service"
    export OTEL_EXPORTER_OTLP_ENDPOINT="$last9_otlp_endpoint"
    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=$last9_otlp_auth_header"
    export OTEL_TRACES_SAMPLER="always_on"
    export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production"
  3. Instrument your AWS config

    Call last9aws.InstrumentSDK(&cfg) once after loading your AWS config, before creating any service clients:

    package main
    import (
    "context"
    "log"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/sqs"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    "github.com/last9/go-agent"
    last9aws "github.com/last9/go-agent/integrations/aws"
    )
    func main() {
    if err := agent.Start(); err != nil {
    log.Fatalf("failed to start agent: %v", err)
    }
    defer agent.Shutdown()
    ctx := context.Background()
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
    log.Fatal(err)
    }
    // Instrument once — all clients created from cfg are automatically traced
    last9aws.InstrumentSDK(&cfg)
    s3Client := s3.NewFromConfig(cfg)
    sqsClient := sqs.NewFromConfig(cfg)
    dynClient := dynamodb.NewFromConfig(cfg)
    // All SDK calls now produce traces automatically
    _ = s3Client
    _ = sqsClient
    _ = dynClient
    }

Example: S3 Operations

import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
s3Client := s3.NewFromConfig(cfg)
// GetObject — produces a span: aws.s3.GetObject
result, err := s3Client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("data/file.json"),
})
// PutObject — produces a span: aws.s3.PutObject
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("data/output.json"),
Body: reader,
})

Example: SQS Operations

import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/sqs"
)
sqsClient := sqs.NewFromConfig(cfg)
// SendMessage — span includes queue URL attribute
_, err := sqsClient.SendMessage(ctx, &sqs.SendMessageInput{
QueueUrl: aws.String("https://sqs.us-east-1.amazonaws.com/123456789/my-queue"),
MessageBody: aws.String(`{"event": "order.created"}`),
})
// ReceiveMessage
output, err := sqsClient.ReceiveMessage(ctx, &sqs.ReceiveMessageInput{
QueueUrl: aws.String(queueURL),
MaxNumberOfMessages: 10,
})

Example: DynamoDB Operations

import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)
dynClient := dynamodb.NewFromConfig(cfg)
// PutItem — span includes table name attribute
_, err := dynClient.PutItem(ctx, &dynamodb.PutItemInput{
TableName: aws.String("users"),
Item: map[string]types.AttributeValue{
"user_id": &types.AttributeValueMemberS{Value: "abc-123"},
"name": &types.AttributeValueMemberS{Value: "Alice"},
},
})
// GetItem
result, err := dynClient.GetItem(ctx, &dynamodb.GetItemInput{
TableName: aws.String("users"),
Key: map[string]types.AttributeValue{
"user_id": &types.AttributeValueMemberS{Value: "abc-123"},
},
})

Custom Options

Pass otelaws.Option values to extend or override how attributes are recorded:

import "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws"
last9aws.InstrumentSDK(&cfg,
otelaws.WithAttributeBuilder(myCustomAttributeBuilder),
)

What Gets Traced Automatically

AttributeExample
rpc.systemaws-api
rpc.serviceS3, DynamoDB, SQS
rpc.methodGetObject, PutItem, SendMessage
aws.regionus-east-1
aws.request_idabc123...
aws.dynamodb.table_namesusers (DynamoDB only)
aws.sqs.queue_urlhttps://sqs... (SQS only)

View Traces

After running your application, navigate to Trace Explorer in Last9. Filter by rpc.system = aws-api to see all AWS SDK calls.


Troubleshooting

Please get in touch with us on Discord or Email if you have any questions.