Skip to content

Commit

Permalink
[Extensions.AWSXray] Replace Newtonsoft.Json with System.Text.Json (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
wjrogers authored Mar 24, 2023
1 parent b908088 commit 1e47f1c
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 41 deletions.
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
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

0 comments on commit 1e47f1c

Please sign in to comment.