package module
Version: v0.0.0-...-04e87a2 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2019 License: Apache-2.0 Imports: 21 Imported by: 0


awshoney - AWS fields for your traces

API Reference


Overview is an application performance monitoring service. They recommend enriching spans and traces with as much metadata as you see fit. We've found adding fields describing the AWS Lambda function, AWS ECS task and EC2 instances our apps run in very helpful.

Traces inside AWS ECS tasks have the following fields added:

  "aws.env":               "ecs",
  "aws.region":            "us-east-1",
  "aws.availability-zone": "us-east-1c",
  "aws.ecs.cluster":       "default",
  "aws.ecs.launchtype":    "ec2",
  "aws.ecs.task.arn":      "arn:aws:ecs:us-east-1:01234567890:task/default/3f3b08db6c984e0f98f05e5d3af242c3",
  "":   "worker",
  "aws.ecs.task.revision": "4",

Traces inside AWS EC2 instances have the following fields added:

  "aws.env":               "ecs",
  "aws.region":            "us-east-1",
  "aws.availability-zone": "us-east-1c",
  "aws.ec2.image-id":      "ami-01234abc",
  "aws.ec2.instance-type": "c5.xlarge",
  "aws.ec2.instance-id":   "i-0012456abc",

Traces inside AWS Lambda functions have the following fields added:

  "aws.env":                      "lambda",
  "aws.region":                   "us-east-1",
  "aws.lambda.handler":           "handlerName",
  "":              "functionName",
  "aws.lambda.runtime":           "go1.x",
  "aws.lambda.version":           "$LATEST",
  "aws.lambda.memory":            "128",
  "aws.lambda.execution-context": "9d4ee6310ced4ef48754dcfc55754f82",

awshoney.WrapLambda() adds the following fields to Lambda functions:

  "aws.lambda.cold-start":         "false",
  "aws.lambda.invocation-counter": "65",
  "aws.lambda.request-id":         "abcde6310ced4ef48754dcfc55754f82",
  "aws.lambda.invoked-version":    "$LATEST (or '5', or 'live', etc)",

Adding fields to AWS API calls

Calls to AWS APIs can be instrumented to automatically record spans, tagged with the AWS service and action called. That works as follows:

func main() {
  // obviously it won't be too helpful if you do this. you'd want to
  // pass in a context from a real span
  ctx, _ := beeline.StartSpan(context.Background(), "example")

  sess := session.Must(session.NewSession())
  baseApi := s3.New(sess)

  api := s3ctx.New(baseApi, awshoney.Contexter)

  // the other methods that aren't WithContext won't pass through
  // the honeycomb trace id
  _, _ = api.ListObjectsWithContext(ctx, &s3.ListObjectsInput{
    Bucket: aws.String("bucket-name"),

    The above will create a new span named `aws.api` with the following
    span-level fields added:

      "aws.service": "s3",
      "aws.action":  "ListObjects",

Bonus SQS

If you use the `sqsctx.SQS` (as described above) when performing `SendMessageWithContext` or `SendMessageBatchWithContext` actions, messages will be annotated with the Honeycomb trace ID for cross-system tracing. On the "receiving end", you should do:

func main() {
  sess := session.Must(session.NewSession())
  baseApi := sqs.New(sess)

  // you don't need to use the sqsctx.SQS wrapper here (but it won't hurt)
  resp, _ := baseApi.ReceiveMessage(&sqs.ReceiveMessageInput{
    QueueUrl:              aws.String("queue-url"),
    // by default sqs won't retrieve message attributes
    MessageAttributeNames: []*string{aws.String(propagation.TracePropagationHTTPHeader)},

  msg := resp.Messages[0]
  ctx, _ := awshoney.StartSpanFromSqs(context.Background(), msg)
  // do something with ctx



This section is empty.


View Source
var Contexter = awsctx.ContexterFunc(contexter)
View Source
var MetadataClient = &http.Client{
	Timeout: 3 * time.Second,


func AddFieldsToClient

func AddFieldsToClient(c *libhoney.Client)

Adds aws.* fields to all traces and spans recorded by c. If c is nil, the default client will be used. Usually you will invoke this right after beeline.Init()

func InsertTraceSqsAttribute

func InsertTraceSqsAttribute(ctx context.Context, attrs *map[string]*sqs.MessageAttributeValue)

func Map

func Map() map[string]string

func StartSpanFromSqs

func StartSpanFromSqs(ctx context.Context, msg *sqs.Message) (context.Context, *trace.Span)


type LambdaWrapper

type LambdaWrapper struct {
	TraceIdentifier func(ctx context.Context, payload []byte) string
	// contains filtered or unexported fields

func WrapLambda

func WrapLambda(spanName string, inner interface{}) *LambdaWrapper

WrapLambda takes a root span name and an "inner" lambda handler to wrap. This inner handler can either be a plain function (i.e. one compatible with lambda.Start()) or a type implementing the lambda.Handler interface.

If the context does not already have a trace, a new one is started. Either way, the current or new span has additional Lambda fields added.

It returns a lambda.Handler that can be passed to lambda.StartHandler().

func (*LambdaWrapper) Invoke

func (w *LambdaWrapper) Invoke(ctx context.Context, payload []byte) (output []byte, err error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL