Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrumenation.AWSLambda: Drop netstandard2, lose Newtonsoft (non-)dependency #1270

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

## Unreleased

* The minimum required .NET version is now .NET Core 3.1 (previously any
netstandard2.0-compliant). As the minimum .NET version in AWS Lambda is
already 6.0, no compatibility problems are expected.
* As part of the switch to .NET Core 3.1, the package no longer uses
Newtonsoft.Json but the built-in System.Text.Json.

This resolves a warning that some dependency analyzers may produce where this
package would transitively depend on a vulnerable version of Newtonsoft.Json
through [Amazon.Lambda.APIGatewayEvents][].

This also avoids a potential issue where the instrumentation would try to call
a Newtonsoft.Json function when no other package nor the app itself depends on
Newtonsoft.Json, since the transitive dependency would be ignored unless using
application were compiled against a TargetFramework older than Core 3.1.

[Amazon.Lambda.APIGatewayEvents]: https://www.nuget.org/packages/Amazon.Lambda.APIGatewayEvents/2.4.1#dependencies-body-tab

## 1.1.0-beta.3

Released 2023-Jun-13
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using Amazon.Lambda.SNSEvents;
using Amazon.Lambda.SQSEvents;
using Newtonsoft.Json;
using OpenTelemetry.Context.Propagation;

namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation;
Expand Down Expand Up @@ -144,11 +144,11 @@ private static SNSEvent.SNSMessage GetSnsMessage(SQSEvent.SQSMessage sqsMessage)
var body = sqsMessage.Body;
if (body != null &&
body.TrimStart().StartsWith("{", StringComparison.Ordinal) &&
body.Contains(SnsMessageAttributes))
body.Contains(SnsMessageAttributes, StringComparison.Ordinal))
{
try
{
snsMessage = JsonConvert.DeserializeObject<SNSEvent.SNSMessage>(body);
snsMessage = JsonSerializer.Deserialize<SNSEvent.SNSMessage>(body);
}
catch (Exception)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change it to net6.0? netcoreapp3.1 is deprecated and might leads to issues in CI.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It already passed CI though (except for a timeout in the coverage build).

I wouldn't want to switch right to 6. If netcoreapp3.1 is a problem, I'd stay on netstandard2.0 and add a conditional dependency on System.Text.Json just like in #1092

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the minimum .NET version in AWS Lambda is already 6.0, no compatibility problems are expected.

@Oberon00 Why do you not want to target net6.0, when the minimum runtime version required by ASWLambda is net6.0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.NET 6 is not even 2 years old. And while the .NET 6 runtime is the oldest one supported by AWS, you should still be able compile your app against older versions and run them. Also, you could use a containerized runtime with an older version.

That's why I'd prefer not to use such a recent version as minimum, especially when it's only a bugfix.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created PR #1273 as an alternative to this, where I do not touch the .NET version at all, staying on netstandard2.0, adding an explicit dependency on Newtonsoft.Json instead.

Probably the .NET version upgrade should be done after the next release of the package.

Copy link
Contributor

@utpilla utpilla Jul 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.NET 6 is marked for LTS (long-term support) by .NET team and if AWS Lambda has chosen it as the minimum version, then it makes sense for its corresponding instrumentation library to do the same.

https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For AWS Lambda, is it possible for a consuming application to be targeting something lower than .NET 6? If not, then why would you be bothered by any of the lower and older targets?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@utpilla #1270 (comment):

you should still be able compile your app against older versions and run them. Also, you could use a containerized runtime with an older version.

To elaborate on the containerized runtime: https://docs.aws.amazon.com/lambda/latest/dg/images-create.html

I do think we should raise the requirement to net6 eventually, but not for a bugfix.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets do opposite.

  1. Create PR with .NET 6 bump.
  2. As a follow up, fix this issue.

Copy link
Member Author

@Oberon00 Oberon00 Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer:

  1. Merge a PR without a bump to net 6 (this or Instrumentation.AWSLambda: Upgrade & explicitly depend on Newtonsoft.Json #1273)
  2. Publish a release
  3. .NET 6 bump

<Description>AWS Lambda tracing wrapper for OpenTelemetry .NET</Description>
<PackageTags>$(PackageTags);AWS Lambda</PackageTags>
<MinVerTagPrefix>Instrumentation.AWSLambda-</MinVerTagPrefix>
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/Guard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#pragma warning disable SA1403 // File may only contain a single namespace
#pragma warning disable SA1649 // File name should match first type name

#if !NET6_0_OR_GREATER
#if !NETCOREAPP3_0_OR_GREATER
namespace System.Runtime.CompilerServices
{
/// <summary>Allows capturing of the expressions passed to a method.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,47 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF
Assert.Equal(2, links.Count());
}

[Fact]
public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetFromSnsMessage()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this test, while generally IMHO useful, did not catch the error about the broken Newtonsoft dependency, because the MS test framework itself pulls in a Newtonsoft.Json assembly. Probably a integration test would be needed to see the issue, but since I never added one and wouldn't know how to do it, I skipped on that.

{
AWSMessagingUtils.SetParentFromMessageBatch = true;
var sqsEvent = new SQSEvent
{
Records = new List<SQSMessage>
{
new SQSMessage
{
MessageAttributes = new(),

#pragma warning disable format // dotnet-format butchers the raw string & all following code (use dotnet format instead?)
Body = /*lang=json,strict*/ """
{
"Type" : "Notification",
"MessageId" : "f91f7f8e-77cc-51e7-ad08-231055044066",
"TopicArn" : "arn:aws:sqs:us-east-1:123456789012:foo-bar-test-queue",
"Subject" : "testsub",
"Message" : "{\"This JSON string\": \"is in the SNS body\"}",
"Timestamp" : "2023-03-29T11:27:04.056Z",
"SignatureVersion" : "1",
"Signature" : "base64string/redacted",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-1234567abc123def1234567890123467.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sqs:us-east-1:123456789012:foo-bar-test-queue:123abcde-1234-1abc-1234-123456abcdef",
"MessageAttributes" : {
"traceparent" : {"Type":"String","Value":"00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-00"}
}
}
""",
},
},
};

(PropagationContext parentContext, IEnumerable<ActivityLink> links) = AWSMessagingUtils.ExtractParentContext(sqsEvent);

Assert.NotEqual(default, parentContext);
Assert.Equal(SpanId1, parentContext.ActivityContext.SpanId.ToHexString());
Assert.Single(links);
}

private static SQSEvent CreateSqsEventWithMessages(string[] spans)
{
var @event = new SQSEvent { Records = new List<SQSMessage>() };
Expand Down