|
23 | 23 | import static org.mockito.Mockito.when; |
24 | 24 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_AGENT_ID; |
25 | 25 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_BUCKET_NAME; |
| 26 | +import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER; |
26 | 27 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_DATA_SOURCE_ID; |
27 | 28 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_GUARDRAIL_ID; |
28 | 29 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_KNOWLEDGE_BASE_ID; |
| 30 | +import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LAMBDA_ARN; |
29 | 31 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LAMBDA_NAME; |
30 | 32 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LAMBDA_RESOURCE_ID; |
31 | 33 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LOCAL_OPERATION; |
32 | 34 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_LOCAL_SERVICE; |
33 | 35 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_QUEUE_NAME; |
34 | 36 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_QUEUE_URL; |
35 | 37 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_DB_USER; |
| 38 | +import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_ENVIRONMENT; |
36 | 39 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_OPERATION; |
37 | 40 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_RESOURCE_IDENTIFIER; |
38 | 41 | import static software.amazon.opentelemetry.javaagent.providers.AwsAttributeKeys.AWS_REMOTE_RESOURCE_TYPE; |
@@ -751,6 +754,86 @@ public void testPeerServiceDoesNotOverrideAwsRemoteService() { |
751 | 754 | assertThat(actualAttributes.get(AWS_REMOTE_SERVICE)).isEqualTo("TestString"); |
752 | 755 | } |
753 | 756 |
|
| 757 | + @Test |
| 758 | + public void testLambdaInvokeSpanWithRemoteServiceAttributes() { |
| 759 | + mockAttribute(RPC_SYSTEM, "aws-api"); |
| 760 | + mockAttribute(RPC_METHOD, "Invoke"); |
| 761 | + mockAttribute(AWS_LAMBDA_NAME, "myLambdaFunction"); |
| 762 | + |
| 763 | + when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT); |
| 764 | + Attributes actualAttributes = |
| 765 | + GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC); |
| 766 | + |
| 767 | + // When RPC_METHOD is "Invoke", Lambda should be treated as a service |
| 768 | + assertThat(actualAttributes.get(AWS_REMOTE_SERVICE)).isEqualTo("myLambdaFunction"); |
| 769 | + assertThat(actualAttributes.get(AWS_REMOTE_ENVIRONMENT)).isEqualTo("lambda:default"); |
| 770 | + // Should not set resource attributes when treated as a service |
| 771 | + assertThat(actualAttributes.get(AWS_REMOTE_RESOURCE_TYPE)).isNull(); |
| 772 | + assertThat(actualAttributes.get(AWS_REMOTE_RESOURCE_IDENTIFIER)).isNull(); |
| 773 | + |
| 774 | + mockAttribute(RPC_METHOD, null); |
| 775 | + mockAttribute(AWS_LAMBDA_NAME, null); |
| 776 | + } |
| 777 | + |
| 778 | + @Test |
| 779 | + public void testLambdaInvokeSpanWithLambdaArnInsteadOfName() { |
| 780 | + mockAttribute(RPC_SYSTEM, "aws-api"); |
| 781 | + mockAttribute(RPC_METHOD, "Invoke"); |
| 782 | + mockAttribute( |
| 783 | + AWS_LAMBDA_NAME, "arn:aws:lambda:us-east-1:123456789012:function:myLambdaFunction"); |
| 784 | + |
| 785 | + when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT); |
| 786 | + Attributes actualAttributes = |
| 787 | + GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC); |
| 788 | + |
| 789 | + // Should extract function name from ARN |
| 790 | + assertThat(actualAttributes.get(AWS_REMOTE_SERVICE)).isEqualTo("myLambdaFunction"); |
| 791 | + assertThat(actualAttributes.get(AWS_REMOTE_ENVIRONMENT)).isEqualTo("lambda:default"); |
| 792 | + |
| 793 | + mockAttribute(RPC_METHOD, null); |
| 794 | + mockAttribute(AWS_LAMBDA_NAME, null); |
| 795 | + } |
| 796 | + |
| 797 | + @Test |
| 798 | + public void testLambdaNonInvokeSpanWithRemoteResourceAttributes() { |
| 799 | + mockAttribute(RPC_SYSTEM, "aws-api"); |
| 800 | + mockAttribute(RPC_METHOD, "GetFunction"); |
| 801 | + mockAttribute(AWS_LAMBDA_NAME, "myLambdaFunction"); |
| 802 | + mockAttribute( |
| 803 | + AWS_LAMBDA_ARN, "arn:aws:lambda:us-east-1:123456789012:function:myLambdaFunction"); |
| 804 | + |
| 805 | + // When RPC_METHOD is not "Invoke", Lambda should be treated as a resource |
| 806 | + validateRemoteResourceAttributes("AWS::Lambda::Function", "myLambdaFunction"); |
| 807 | + |
| 808 | + // Also verify cloudformation primary identifier is set to ARN |
| 809 | + when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT); |
| 810 | + Attributes actualAttributes = |
| 811 | + GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC); |
| 812 | + assertThat(actualAttributes.get(AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER)) |
| 813 | + .isEqualTo("arn:aws:lambda:us-east-1:123456789012:function:myLambdaFunction"); |
| 814 | + |
| 815 | + mockAttribute(RPC_METHOD, null); |
| 816 | + mockAttribute(AWS_LAMBDA_NAME, null); |
| 817 | + mockAttribute(AWS_LAMBDA_ARN, null); |
| 818 | + } |
| 819 | + |
| 820 | + @Test |
| 821 | + public void testLambdaNonInvokeSpanWithLambdaArnInsteadOfName() { |
| 822 | + mockAttribute(RPC_SYSTEM, "aws-api"); |
| 823 | + mockAttribute(RPC_METHOD, "ListFunctions"); |
| 824 | + mockAttribute( |
| 825 | + AWS_LAMBDA_NAME, "arn:aws:lambda:us-east-1:123456789012:function:myLambdaFunction"); |
| 826 | + mockAttribute( |
| 827 | + AWS_LAMBDA_ARN, "arn:aws:lambda:us-east-1:123456789012:function:myLambdaFunction"); |
| 828 | + |
| 829 | + // Should extract function name from ARN |
| 830 | + validateRemoteResourceAttributes("AWS::Lambda::Function", "myLambdaFunction"); |
| 831 | + |
| 832 | + mockAttribute(RPC_METHOD, null); |
| 833 | + mockAttribute(AWS_LAMBDA_NAME, null); |
| 834 | + mockAttribute(AWS_LAMBDA_ARN, null); |
| 835 | + } |
| 836 | + |
754 | 837 | @Test |
755 | 838 | public void testSdkClientSpanWithRemoteResourceAttributes() { |
756 | 839 | mockAttribute(RPC_SYSTEM, "aws-api"); |
@@ -881,6 +964,20 @@ public void testSdkClientSpanWithRemoteResourceAttributes() { |
881 | 964 | validateRemoteResourceAttributes("AWS::Lambda::Function", "testLambdaName"); |
882 | 965 | mockAttribute(AWS_LAMBDA_NAME, null); |
883 | 966 |
|
| 967 | + // Validate that Lambda Invoke does NOT set resource attributes |
| 968 | + mockAttribute(RPC_METHOD, "Invoke"); |
| 969 | + mockAttribute(AWS_LAMBDA_NAME, "testLambdaName"); |
| 970 | + when(spanDataMock.getKind()).thenReturn(SpanKind.CLIENT); |
| 971 | + Attributes actualAttributes = |
| 972 | + GENERATOR.generateMetricAttributeMapFromSpan(spanDataMock, resource).get(DEPENDENCY_METRIC); |
| 973 | + // Lambda Invoke should be treated as a service, not a resource |
| 974 | + assertThat(actualAttributes.get(AWS_REMOTE_SERVICE)).isEqualTo("testLambdaName"); |
| 975 | + assertThat(actualAttributes.get(AWS_REMOTE_RESOURCE_TYPE)).isNull(); |
| 976 | + assertThat(actualAttributes.get(AWS_REMOTE_RESOURCE_IDENTIFIER)).isNull(); |
| 977 | + assertThat(actualAttributes.get(AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER)).isNull(); |
| 978 | + mockAttribute(RPC_METHOD, null); |
| 979 | + mockAttribute(AWS_LAMBDA_NAME, null); |
| 980 | + |
884 | 981 | // Validate behaviour of AWS_LAMBDA_RESOURCE_ID |
885 | 982 | mockAttribute(AWS_LAMBDA_RESOURCE_ID, "eventSourceId"); |
886 | 983 | validateRemoteResourceAttributes("AWS::Lambda::EventSourceMapping", "eventSourceId"); |
|
0 commit comments