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

[Extensions.AWSXray] Replace Newtonsoft.Json with System.Text.Json #1092

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380))
* Raised minimum .NET version to `net462`
([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875))
* Replaced Newtonsoft.Json dependency with System.Text.Json
([#1092](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1092))
* Updated OTel SDK package version to 1.3.1
([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875))
* Enhancement - AWSECSResourceDetector - Implement `aws.{ecs.*,log.*}` resource
Expand Down
Kielek marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="OpenTelemetry" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
Expand All @@ -21,6 +20,10 @@
<Compile Remove="Resources\Http\ServerCertificateValidationProvider.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' Or '$(TargetFramework)' == '$(NetFrameworkMinimumSupportedVersion)'">
<PackageReference Include="System.Text.Json" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Internal\Guard.cs" Link="Includes\Guard.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Text.RegularExpressions;

using Newtonsoft.Json.Linq;

using OpenTelemetry.Resources;

namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources;
Expand Down Expand Up @@ -88,18 +87,18 @@ internal static List<KeyValuePair<string, object>> ExtractMetadataV4ResourceAttr
var metadataV4ContainerResponse = ResourceDetectorUtils.SendOutRequest(metadataV4Url, "GET", null, httpClientHandler).Result;
var metadataV4TaskResponse = ResourceDetectorUtils.SendOutRequest($"{metadataV4Url.TrimEnd('/')}/task", "GET", null, httpClientHandler).Result;

var containerResponse = JObject.Parse(metadataV4ContainerResponse);
var taskResponse = JObject.Parse(metadataV4TaskResponse);
using var containerResponse = JsonDocument.Parse(metadataV4ContainerResponse);
using var taskResponse = JsonDocument.Parse(metadataV4TaskResponse);

var containerArn = containerResponse.Value<string>("ContainerARN");
if (containerArn == null)
if (!containerResponse.RootElement.TryGetProperty("ContainerARN", out var containerArnElement)
|| containerArnElement.GetString() is not string containerArn)
{
AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field"));
return new List<KeyValuePair<string, object>>();
}

var clusterArn = taskResponse.Value<string>("Cluster");
if (clusterArn == null)
if (!taskResponse.RootElement.TryGetProperty("Cluster", out var clusterArnElement)
|| clusterArnElement.GetString() is not string clusterArn)
{
AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field"));
return new List<KeyValuePair<string, object>>();
Expand All @@ -117,10 +116,15 @@ internal static List<KeyValuePair<string, object>> ExtractMetadataV4ResourceAttr
new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn),
};

var launchType = taskResponse.Value<string>("LaunchType") switch
if (!taskResponse.RootElement.TryGetProperty("LaunchType", out var launchTypeElement))
{
launchTypeElement = default;
}

var launchType = launchTypeElement switch
{
string type when string.Equals("ec2", type, StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeEc2,
string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeFargate,
{ ValueKind: JsonValueKind.String } when string.Equals("ec2", launchTypeElement.GetString(), StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeEc2,
{ ValueKind: JsonValueKind.String } when string.Equals("fargate", launchTypeElement.GetString(), StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeFargate,
_ => null,
};

Expand All @@ -130,31 +134,29 @@ string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCa
}
else
{
AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{taskResponse["LaunchType"]}'"));
AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{launchTypeElement}'"));
}

var taskArn = taskResponse.Value<string>("TaskARN");
if (taskArn != null)
if (taskResponse.RootElement.TryGetProperty("TaskARN", out var taskArnElement) && taskArnElement.ValueKind == JsonValueKind.String)
{
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsTaskArn, taskArn));
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsTaskArn, taskArnElement.GetString()!));
}

var family = taskResponse.Value<string>("Family");
if (family != null)
if (taskResponse.RootElement.TryGetProperty("Family", out var familyElement) && familyElement.ValueKind == JsonValueKind.String)
{
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsTaskFamily, family));
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsTaskFamily, familyElement.GetString()!));
}

var revision = taskResponse.Value<string>("Revision");
if (revision != null)
if (taskResponse.RootElement.TryGetProperty("Revision", out var revisionElement) && revisionElement.ValueKind == JsonValueKind.String)
{
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsTaskRevision, revision));
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeEcsTaskRevision, revisionElement.GetString()!));
}

if (string.Equals("awslogs", containerResponse.Value<string>("LogDriver"), StringComparison.Ordinal))
if (containerResponse.RootElement.TryGetProperty("LogDriver", out var logDriverElement)
&& logDriverElement.ValueKind == JsonValueKind.String
&& logDriverElement.ValueEquals("awslogs"))
{
JObject? logOptions = containerResponse.Value<JObject>("LogOptions");
if (logOptions != null)
if (containerResponse.RootElement.TryGetProperty("LogOptions", out var logOptionsElement))
{
var regex = new Regex(@"arn:aws:ecs:([^:]+):([^:]+):.*");
var match = regex.Match(containerArn);
Expand All @@ -167,15 +169,15 @@ string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCa
var logsRegion = match.Groups[1];
var logsAccount = match.Groups[2];

var logGroupName = logOptions.Value<string>("awslogs-group");
if (logGroupName != null)
if (logOptionsElement.TryGetProperty("awslogs-group", out var logGroupElement) && logGroupElement.ValueKind == JsonValueKind.String)
{
var logGroupName = logGroupElement.GetString()!;
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeLogGroupNames, new string[] { logGroupName }));
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeLogGroupArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:*" }));

var logStreamName = logOptions.Value<string>("awslogs-stream");
if (logStreamName != null)
if (logOptionsElement.TryGetProperty("awslogs-stream", out var logStreamElement) && logStreamElement.ValueKind == JsonValueKind.String)
{
var logStreamName = logStreamElement.GetString()!;
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeLogStreamNames, new string[] { logStreamName }));
resourceAttributes.Add(new KeyValuePair<string, object>(AWSSemanticConventions.AttributeLogStreamArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:log-stream:{logStreamName}" }));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
// limitations under the License.
// </copyright>

using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models;

internal class AWSEBSMetadataModel
{
[JsonProperty(PropertyName = "deployment_id")]
[JsonPropertyName("deployment_id")]
public string? DeploymentId { get; set; }

[JsonProperty(PropertyName = "environment_name")]
[JsonPropertyName("environment_name")]
public string? EnvironmentName { get; set; }

[JsonProperty(PropertyName = "version_label")]
[JsonPropertyName("version_label")]
public string? VersionLabel { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
// limitations under the License.
// </copyright>

using Newtonsoft.Json;
using System.Text.Json.Serialization;

namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models;

internal class AWSEKSClusterDataModel
{
[JsonProperty(PropertyName = "cluster.name")]
[JsonPropertyName("cluster.name")]
public string? ClusterName { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources;

Expand All @@ -31,6 +31,8 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources;
public class ResourceDetectorUtils
#pragma warning restore CA1052
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

internal static async Task<string> SendOutRequest(string url, string method, KeyValuePair<string, string>? header, HttpClientHandler? handler = null)
{
using (var httpRequestMessage = new HttpRequestMessage())
Expand All @@ -55,21 +57,25 @@ internal static async Task<string> SendOutRequest(string url, string method, Key

internal static T? DeserializeFromFile<T>(string filePath)
{
using (var streamReader = GetStreamReader(filePath))
using (var stream = GetStream(filePath))
{
JsonSerializer serializer = new JsonSerializer();
return (T?)serializer.Deserialize(streamReader, typeof(T));
return (T?)JsonSerializer.Deserialize(stream, typeof(T), JsonSerializerOptions);
}
}

internal static T? DeserializeFromString<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
return JsonSerializer.Deserialize<T>(json, JsonSerializerOptions);
}

internal static Stream GetStream(string filePath)
{
return new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}

internal static StreamReader GetStreamReader(string filePath)
{
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var fileStream = GetStream(filePath);
var streamReader = new StreamReader(fileStream, Encoding.UTF8);
return streamReader;
}
Expand Down