Skip to content

chore: Add missing PTENV to user agent #927

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

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
62 changes: 0 additions & 62 deletions libraries/src/AWS.Lambda.Powertools.Common/Core/ISystemWrapper.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Text;

namespace AWS.Lambda.Powertools.Common;
Expand All @@ -11,6 +12,16 @@
/// </summary>
private static IPowertoolsEnvironment _instance;

/// <summary>
/// Cached runtime environment string
/// </summary>
private static readonly string CachedRuntimeEnvironment = $"PTENV/AWS_LAMBDA_DOTNET{Environment.Version.Major}";

/// <summary>
/// Cache for parsed assembly names to avoid repeated string operations
/// </summary>
private static readonly ConcurrentDictionary<string, string> ParsedAssemblyNameCache = new();

/// <summary>
/// Gets the instance.
/// </summary>
Expand All @@ -20,7 +31,7 @@
/// <inheritdoc />
public string GetEnvironmentVariable(string variableName)
{
return Environment.GetEnvironmentVariable(variableName);

Check warning on line 34 in libraries/src/AWS.Lambda.Powertools.Common/Core/PowertoolsEnvironment.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.
}

/// <inheritdoc />
Expand All @@ -32,41 +43,72 @@
/// <inheritdoc />
public string GetAssemblyName<T>(T type)
{
if (type is Type typeObject)
{
return typeObject.Assembly.GetName().Name;
}

return type.GetType().Assembly.GetName().Name;
}

/// <inheritdoc />
public string GetAssemblyVersion<T>(T type)
{
var version = type.GetType().Assembly.GetName().Version;
Version version;

if (type is Type typeObject)
{
version = typeObject.Assembly.GetName().Version;
}
else
{
version = type.GetType().Assembly.GetName().Version;
}

return version != null ? $"{version.Major}.{version.Minor}.{version.Build}" : string.Empty;
}

/// <inheritdoc />
public void SetExecutionEnvironment<T>(T type)
{
const string envName = Constants.AwsExecutionEnvironmentVariableName;
var envValue = new StringBuilder();
var currentEnvValue = GetEnvironmentVariable(envName);
var assemblyName = ParseAssemblyName(GetAssemblyName(type));

// If there is an existing execution environment variable add the annotations package as a suffix.
if (!string.IsNullOrEmpty(currentEnvValue))
// Check for duplication early
if (!string.IsNullOrEmpty(currentEnvValue) && currentEnvValue.Contains(assemblyName))
{
// Avoid duplication - should not happen since the calling Instances are Singletons - defensive purposes
if (currentEnvValue.Contains(assemblyName))
{
return;
}

envValue.Append($"{currentEnvValue} ");
return;
}

var assemblyVersion = GetAssemblyVersion(type);
var newEntry = $"{assemblyName}/{assemblyVersion}";

string finalValue;

if (string.IsNullOrEmpty(currentEnvValue))
{
// First entry: "PT/Assembly/1.0.0 PTENV/AWS_LAMBDA_DOTNET8"
finalValue = $"{newEntry} {CachedRuntimeEnvironment}";
}
else
{
// Check if PTENV already exists in one pass
var containsPtenv = currentEnvValue.Contains("PTENV/");

if (containsPtenv)
{
// Just append the new entry: "existing PT/Assembly/1.0.0"
finalValue = $"{currentEnvValue} {newEntry}";
}
else
{
// Append new entry + PTENV: "existing PT/Assembly/1.0.0 PTENV/AWS_LAMBDA_DOTNET8"
finalValue = $"{currentEnvValue} {newEntry} {CachedRuntimeEnvironment}";
}
}

envValue.Append($"{assemblyName}/{assemblyVersion}");

SetEnvironmentVariable(envName, envValue.ToString());
SetEnvironmentVariable(envName, finalValue);
}

/// <summary>
Expand All @@ -75,18 +117,26 @@
/// </summary>
/// <param name="assemblyName"></param>
/// <returns></returns>
private string ParseAssemblyName(string assemblyName)
internal static string ParseAssemblyName(string assemblyName)
{
// Use cache to avoid repeated string operations
try
{
var parsedName = assemblyName.Substring(assemblyName.LastIndexOf(".", StringComparison.Ordinal) + 1);
return $"{Constants.FeatureContextIdentifier}/{parsedName}";
return ParsedAssemblyNameCache.GetOrAdd(assemblyName, name =>
{
var lastDotIndex = name.LastIndexOf('.');
if (lastDotIndex >= 0 && lastDotIndex < name.Length - 1)
{
var parsedName = name.Substring(lastDotIndex + 1);
return $"{Constants.FeatureContextIdentifier}/{parsedName}";
}

return $"{Constants.FeatureContextIdentifier}/{name}";
});
}
catch
{
//NOOP
return string.Empty;
}

return $"{Constants.FeatureContextIdentifier}/{assemblyName}";
}
}
}
Loading
Loading