diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c17288ba94..d3abf68175b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add the new `go.opentelemetry.io/contrib/instrgen` package to provide auto-generated source code instrumentation. (#3068) - `otelmux`: Add new `WithSpanNameFormatter` option to `go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux` to allow customizing span names. (#3041) +- Add missing recommended AWS Lambda resource attributes `faas.instance` and `faas.max_memory` in `go.opentelemetry.io/contrib/detectors/aws/lambda`. (#3148) - Improve documentation for `samplers/jaegerremote` by providing examples of sampling endpoints. (#3147) ## [1.12.0/0.37.0/0.6.0] diff --git a/detectors/aws/lambda/README.md b/detectors/aws/lambda/README.md index 0f8f1bbe24e..505b9f8f871 100644 --- a/detectors/aws/lambda/README.md +++ b/detectors/aws/lambda/README.md @@ -46,6 +46,8 @@ Now your `TracerProvider` will have the following resource attributes and attach |`cloud.region` | us-east-1 |`faas.name` | MyLambdaFunction |`faas.version` | $LATEST +|`faas.instance` | 2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de +|`faas.max_memory`| 128 Of note, `faas.id` and `cloud.account.id` are not set by the Lambda resource detector because they are not available outside a Lambda invocation. For this reason, when using the AWS Lambda Instrumentation these attributes are set as additional span attributes. diff --git a/detectors/aws/lambda/detector.go b/detectors/aws/lambda/detector.go index ff60db88b0f..07cea8f57bd 100644 --- a/detectors/aws/lambda/detector.go +++ b/detectors/aws/lambda/detector.go @@ -18,6 +18,7 @@ import ( "context" "errors" "os" + "strconv" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" @@ -30,6 +31,8 @@ const ( lambdaFunctionNameEnvVar = "AWS_LAMBDA_FUNCTION_NAME" awsRegionEnvVar = "AWS_REGION" lambdaFunctionVersionEnvVar = "AWS_LAMBDA_FUNCTION_VERSION" + lambdaLogStreamNameEnvVar = "AWS_LAMBDA_LOG_STREAM_NAME" + lambdaMemoryLimitEnvVar = "AWS_LAMBDA_FUNCTION_MEMORY_SIZE" ) var ( @@ -57,13 +60,23 @@ func (detector *resourceDetector) Detect(context.Context) (*resource.Resource, e } awsRegion := os.Getenv(awsRegionEnvVar) functionVersion := os.Getenv(lambdaFunctionVersionEnvVar) + // The instance attributes corresponds to the log stream name for AWS lambda, + // see the FaaS resource specification for more details. + instance := os.Getenv(lambdaLogStreamNameEnvVar) attrs := []attribute.KeyValue{ semconv.CloudProviderAWS, semconv.CloudRegionKey.String(awsRegion), + semconv.FaaSInstanceKey.String(instance), semconv.FaaSNameKey.String(lambdaName), semconv.FaaSVersionKey.String(functionVersion), } + maxMemoryStr := os.Getenv(lambdaMemoryLimitEnvVar) + maxMemory, err := strconv.Atoi(maxMemoryStr) + if err == nil { + attrs = append(attrs, semconv.FaaSMaxMemoryKey.Int(maxMemory)) + } + return resource.NewWithAttributes(semconv.SchemaURL, attrs...), nil } diff --git a/detectors/aws/lambda/detector_test.go b/detectors/aws/lambda/detector_test.go index 9c6c65d308a..311362d8cdd 100644 --- a/detectors/aws/lambda/detector_test.go +++ b/detectors/aws/lambda/detector_test.go @@ -32,12 +32,16 @@ func TestDetectSuccess(t *testing.T) { _ = os.Setenv(lambdaFunctionNameEnvVar, "testFunction") _ = os.Setenv(awsRegionEnvVar, "us-texas-1") _ = os.Setenv(lambdaFunctionVersionEnvVar, "$LATEST") + _ = os.Setenv(lambdaLogStreamNameEnvVar, "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc") + _ = os.Setenv(lambdaMemoryLimitEnvVar, "128") attributes := []attribute.KeyValue{ semconv.CloudProviderAWS, semconv.CloudRegionKey.String("us-texas-1"), semconv.FaaSNameKey.String("testFunction"), semconv.FaaSVersionKey.String("$LATEST"), + semconv.FaaSInstanceKey.String("2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc"), + semconv.FaaSMaxMemoryKey.Int(128), } expectedResource := resource.NewWithAttributes(semconv.SchemaURL, attributes...) detector := resourceDetector{} diff --git a/instrumentation/github.com/aws/aws-lambda-go/otellambda/lambda_test.go b/instrumentation/github.com/aws/aws-lambda-go/otellambda/lambda_test.go index caa823ce8af..537b3d757a4 100644 --- a/instrumentation/github.com/aws/aws-lambda-go/otellambda/lambda_test.go +++ b/instrumentation/github.com/aws/aws-lambda-go/otellambda/lambda_test.go @@ -54,6 +54,8 @@ func setEnvVars() { _ = os.Setenv("AWS_LAMBDA_FUNCTION_NAME", "testFunction") _ = os.Setenv("AWS_REGION", "us-texas-1") _ = os.Setenv("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST") + _ = os.Setenv("AWS_LAMBDA_LOG_STREAM_NAME", "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc") + _ = os.Setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "128") _ = os.Setenv("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1") } diff --git a/instrumentation/github.com/aws/aws-lambda-go/otellambda/test/lambda_test.go b/instrumentation/github.com/aws/aws-lambda-go/otellambda/test/lambda_test.go index edc73b9ad71..87b246f24b6 100644 --- a/instrumentation/github.com/aws/aws-lambda-go/otellambda/test/lambda_test.go +++ b/instrumentation/github.com/aws/aws-lambda-go/otellambda/test/lambda_test.go @@ -102,6 +102,8 @@ func setEnvVars() { _ = os.Setenv("AWS_LAMBDA_FUNCTION_NAME", "testFunction") _ = os.Setenv("AWS_REGION", "us-texas-1") _ = os.Setenv("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST") + _ = os.Setenv("AWS_LAMBDA_LOG_STREAM_NAME", "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc") + _ = os.Setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "128") _ = os.Setenv("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1") } @@ -148,7 +150,9 @@ var ( attribute.String("cloud.provider", "aws"), attribute.String("cloud.region", "us-texas-1"), attribute.String("faas.name", "testFunction"), - attribute.String("faas.version", "$LATEST")), + attribute.String("faas.version", "$LATEST"), + attribute.String("faas.instance", "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc"), + attribute.Int("faas.max_memory", 128)), InstrumentationLibrary: instrumentation.Library{Name: "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-lambda-go/otellambda", Version: otellambda.SemVersion()}, } ) @@ -336,7 +340,9 @@ var ( attribute.String("cloud.provider", "aws"), attribute.String("cloud.region", "us-texas-1"), attribute.String("faas.name", "testFunction"), - attribute.String("faas.version", "$LATEST")), + attribute.String("faas.version", "$LATEST"), + attribute.String("faas.instance", "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc"), + attribute.Int("faas.max_memory", 128)), InstrumentationLibrary: instrumentation.Library{Name: "go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-lambda-go/otellambda", Version: otellambda.SemVersion()}, } ) diff --git a/instrumentation/github.com/aws/aws-lambda-go/otellambda/xrayconfig/xrayconfig_test.go b/instrumentation/github.com/aws/aws-lambda-go/otellambda/xrayconfig/xrayconfig_test.go index df27ea6516a..89c03dcea85 100644 --- a/instrumentation/github.com/aws/aws-lambda-go/otellambda/xrayconfig/xrayconfig_test.go +++ b/instrumentation/github.com/aws/aws-lambda-go/otellambda/xrayconfig/xrayconfig_test.go @@ -67,6 +67,8 @@ func setEnvVars() { _ = os.Setenv("AWS_LAMBDA_FUNCTION_NAME", "testFunction") _ = os.Setenv("AWS_REGION", "us-texas-1") _ = os.Setenv("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST") + _ = os.Setenv("AWS_LAMBDA_LOG_STREAM_NAME", "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc") + _ = os.Setenv("AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "128") _ = os.Setenv("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1") // fix issue: "The requested service provider could not be loaded or initialized." @@ -116,6 +118,8 @@ var ( expectedSpanResource = v1resource.Resource{ Attributes: []*v1common.KeyValue{{Key: "cloud.provider", Value: &v1common.AnyValue{Value: &v1common.AnyValue_StringValue{StringValue: "aws"}}}, {Key: "cloud.region", Value: &v1common.AnyValue{Value: &v1common.AnyValue_StringValue{StringValue: "us-texas-1"}}}, + {Key: "faas.instance", Value: &v1common.AnyValue{Value: &v1common.AnyValue_StringValue{StringValue: "2023/01/01/[$LATEST]5d1edb9e525d486696cf01a3503487bc"}}}, + {Key: "faas.max_memory", Value: &v1common.AnyValue{Value: &v1common.AnyValue_IntValue{IntValue: 128}}}, {Key: "faas.name", Value: &v1common.AnyValue{Value: &v1common.AnyValue_StringValue{StringValue: "testFunction"}}}, {Key: "faas.version", Value: &v1common.AnyValue{Value: &v1common.AnyValue_StringValue{StringValue: "$LATEST"}}}}, DroppedAttributesCount: 0, @@ -129,11 +133,13 @@ var ( ) func assertResourceEquals(t *testing.T, expected *v1resource.Resource, actual *v1resource.Resource) { - assert.Len(t, actual.Attributes, 4) + assert.Len(t, actual.Attributes, 6) assert.Equal(t, expected.Attributes[0].String(), actual.Attributes[0].String()) assert.Equal(t, expected.Attributes[1].String(), actual.Attributes[1].String()) assert.Equal(t, expected.Attributes[2].String(), actual.Attributes[2].String()) assert.Equal(t, expected.Attributes[3].String(), actual.Attributes[3].String()) + assert.Equal(t, expected.Attributes[4].String(), actual.Attributes[4].String()) + assert.Equal(t, expected.Attributes[5].String(), actual.Attributes[5].String()) assert.Equal(t, expected.DroppedAttributesCount, actual.DroppedAttributesCount) }