Skip to content

Commit

Permalink
Merge branch 'main' into resource-detectors
Browse files Browse the repository at this point in the history
  • Loading branch information
rajkumar-rangaraj authored Apr 13, 2023
2 parents 8facd9d + 0f15c72 commit 6e63924
Show file tree
Hide file tree
Showing 18 changed files with 583 additions and 25 deletions.
30 changes: 30 additions & 0 deletions build/Build.Steps.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Nodes;
using Extensions;
using Nuke.Common;
Expand Down Expand Up @@ -491,6 +493,34 @@ DotNetBuildSettings BuildTestApplication(DotNetBuildSettings x) =>
AdditionalDepsDirectory.GlobDirectories("**/runtimes").ForEach(DeleteDirectory);
});

Target PublishRuleEngineJson => _ => _
.After(PublishManagedProfiler)
.Description("Publishes a file with assembly name and version for rule engine validation.")
.Executes(() =>
{
var netPath = TracerHomeDirectory / "net";
var fileInfoList = new List<object>();
var files = Directory.GetFiles(netPath);

foreach (string file in files)
{
var fileName = Path.GetFileNameWithoutExtension(file);
var fileVersion = FileVersionInfo.GetVersionInfo(file).FileVersion;

if (fileName.StartsWith("OpenTelemetry.") && !fileName.StartsWith("OpenTelemetry.Api") && !fileName.StartsWith("OpenTelemetry.AutoInstrumentation"))
{
fileInfoList.Add(new
{
FileName = fileName,
FileVersion = fileVersion
});
}
}

string jsonContent = JsonSerializer.Serialize(fileInfoList);
File.WriteAllText(Path.Combine(netPath, "ruleEngine.json"), jsonContent);
});

Target InstallDocumentationTools => _ => _
.Description("Installs markdownlint-cli and cspell locally. npm is required")
.Executes(() =>
Expand Down
1 change: 1 addition & 0 deletions build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ void DeleteReparsePoints(string path)
.DependsOn(GenerateNetFxTransientDependencies)
.DependsOn(CompileManagedSrc)
.DependsOn(PublishManagedProfiler)
.DependsOn(PublishRuleEngineJson)
.DependsOn(GenerateNetFxAssemblyRedirectionSource)
.DependsOn(CompileNativeSrc)
.DependsOn(PublishNativeProfiler)
Expand Down
2 changes: 1 addition & 1 deletion build/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
<ItemGroup>
<PackageVersion Include="Mono.Cecil" Version="0.11.4" />
<PackageVersion Include="Nuke.Common" Version="6.3.0" />
<PackageVersion Include="Nuget.CommandLine" Version="6.4.0" />
<PackageVersion Include="Nuget.CommandLine" Version="6.5.0" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions build/LibraryVersions.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ public static class LibraryVersion
new List<string>
{
"8.0.0",
"8.0.10",
"8.1.0",
}
},
{
"TestApplication.EntityFrameworkCore",
new List<string>
{
"6.0.12",
"7.0.4",
"7.0.5",
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,91 @@
// limitations under the License.
// </copyright>

using System.Diagnostics;
using System.Reflection;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.RulesEngine;

internal class DiagnosticSourceRule : Rule
{
private static IOtelLogger logger = OtelLogging.GetLogger("StartupHook");

public DiagnosticSourceRule()
{
Name = "System.Diagnostics.DiagnosticSource Validator";
Description = "Ensure that the System.Diagnostics.DiagnosticSource version is not older than the version used by the Auto-Instrumentation";
}

// This constructor is used for test purpose.
protected DiagnosticSourceRule(IOtelLogger otelLogger)
: this()
{
logger = otelLogger;
}

internal override bool Evaluate()
{
// TODO: implement checking logic
string? olderDiagnosticSourcePackageVersion = null;

try
{
// NuGet package version is not available at runtime. AssemblyVersion is available but it only changes in major version updates.
// Thus using AssemblyFileVersion to compare whether the loaded version is older than that of auto instrumentation.
var loadedDiagnosticSourceFileVersion = GetResolvedVersion();
if (loadedDiagnosticSourceFileVersion != null)
{
var autoInstrumentationDiagnosticSourceFileVersion = GetVersionFromAutoInstrumentation();
if (loadedDiagnosticSourceFileVersion < autoInstrumentationDiagnosticSourceFileVersion)
{
olderDiagnosticSourcePackageVersion = loadedDiagnosticSourceFileVersion.ToString();
}
}
}
catch (Exception ex)
{
// Exception in evaluation should not throw or crash the process.
logger.Warning($"Rule Engine: Couldn't evaluate System.Diagnostics.DiagnosticSource version. Exception: {ex}");
return false;
}

if (olderDiagnosticSourcePackageVersion != null)
{
logger.Error($"Rule Engine: Application has direct or indirect reference to older version of System.Diagnostics.DiagnosticSource.dll {olderDiagnosticSourcePackageVersion}.");
return false;
}

logger.Information("Rule Engine: DiagnosticSourceRule evaluation success.");
return true;
}

protected virtual Version? GetResolvedVersion()
{
// Look up for type with an assembly name, will load the library.
var diagnosticSourceType = Type.GetType("System.Diagnostics.DiagnosticSource, System.Diagnostics.DiagnosticSource");
if (diagnosticSourceType != null)
{
var loadedDiagnosticSourceAssembly = Assembly.GetAssembly(diagnosticSourceType);
var loadedDiagnosticSourceAssemblyFileVersionAttribute = loadedDiagnosticSourceAssembly?.GetCustomAttribute<AssemblyFileVersionAttribute>();
var versionString = loadedDiagnosticSourceAssemblyFileVersionAttribute?.Version;
if (versionString != null)
{
return new Version(versionString);
}
}

return null;
}

protected virtual Version GetVersionFromAutoInstrumentation()
{
var autoInstrumentationDiagnosticSourceLocation = Path.Combine(StartupHook.LoaderAssemblyLocation ?? string.Empty, "System.Diagnostics.DiagnosticSource.dll");
var fileVersionInfo = FileVersionInfo.GetVersionInfo(autoInstrumentationDiagnosticSourceLocation);
var autoInstrumentationDiagnosticSourceFileVersion = new Version(
fileVersionInfo.FileMajorPart,
fileVersionInfo.FileMinorPart,
fileVersionInfo.FileBuildPart,
fileVersionInfo.FilePrivatePart);
return autoInstrumentationDiagnosticSourceFileVersion;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,77 @@
// limitations under the License.
// </copyright>

using System.Diagnostics;
using System.Reflection;
using System.Text.Json;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.RulesEngine;

internal class InstrumentationAssemblyRule : Rule
{
private static readonly IOtelLogger Logger = OtelLogging.GetLogger("StartupHook");

public InstrumentationAssemblyRule()
{
Name = "Instrumentation Assembly Validator";
Description = "Ensure that the version of the OpenTelemetry Instrumentation libraries is not older than the version used by Auto-Instrumentation.";
}

internal override bool Evaluate()
{
// TODO: implement checking logic
var result = true;

try
{
var ruleEngineFileLocation = Path.Combine(StartupHook.LoaderAssemblyLocation ?? string.Empty, "ruleEngine.json");
var ruleEngineContent = File.ReadAllText(ruleEngineFileLocation);
var ruleFileInfoList = JsonSerializer.Deserialize<List<RuleFileInfo>>(ruleEngineContent);
var entryAssembly = Assembly.GetEntryAssembly();
var referencedAssemblies = entryAssembly?.GetReferencedAssemblies();

if (referencedAssemblies == null)
{
Logger.Warning($"Rule Engine: Could not get referenced assembly (GetReferencedAssemblies()) from an application. Skipping rule evaluation.");
return result;
}

foreach (var referencedAssembly in referencedAssemblies)
{
var ruleFileInfo = ruleFileInfoList.FirstOrDefault(file => file.FileName == referencedAssembly.Name);
if (ruleFileInfo != null)
{
var autoInstrumentationFileVersion = new Version(ruleFileInfo.FileVersion);

var appInstrumentationAssembly = Assembly.Load(referencedAssembly);
var appInstrumentationFileVersionInfo = FileVersionInfo.GetVersionInfo(appInstrumentationAssembly.Location);
var appInstrumentationFileVersion = new Version(appInstrumentationFileVersionInfo.FileVersion);

if (appInstrumentationFileVersion < autoInstrumentationFileVersion)
{
result = false;
Logger.Error($"Rule Engine: Application has direct or indirect reference to older version of Instrumentation library {ruleFileInfo.FileName} - {ruleFileInfo.FileVersion}.");
}
else
{
Logger.Information($"Rule Engine: Application has reference to Instrumentation library {ruleFileInfo.FileName} and loaded successfully.");
}
}
}
}
catch (Exception ex)
{
// Exception in rule evaluation should not impact the result of the rule.
Logger.Warning($"Rule Engine:Couldn't evaluate OpenTelemetry Instrumentation Evaluation. Exception: {ex}");
}

return true;
}

private class RuleFileInfo
{
public string FileName { get; set; } = string.Empty;

public string FileVersion { get; set; } = string.Empty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,75 @@ namespace OpenTelemetry.AutoInstrumentation.RulesEngine;

internal class OpenTelemetrySdkMinimumVersionRule : Rule
{
private static readonly IOtelLogger Logger = OtelLogging.GetLogger("StartupHook");
private static IOtelLogger logger = OtelLogging.GetLogger("StartupHook");

public OpenTelemetrySdkMinimumVersionRule()
{
Name = "OpenTelemetry SDK Validator";
Description = "Ensure that the OpenTelemetry SDK version is not older than the version used by the Auto-Instrumentation";
}

// This constructor is used for test purpose.
protected OpenTelemetrySdkMinimumVersionRule(IOtelLogger otelLogger)
: this()
{
logger = otelLogger;
}

internal override bool Evaluate()
{
string? oTelPackageVersion = null;

try
{
var openTelemetryType = Type.GetType("OpenTelemetry.Sdk, OpenTelemetry");
if (openTelemetryType != null)
var loadedOTelFileVersion = GetVersionFromApp();
if (loadedOTelFileVersion != null)
{
var loadedOTelAssembly = Assembly.GetAssembly(openTelemetryType);
var loadedOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(loadedOTelAssembly?.Location);
var loadedOTelFileVersion = new Version(loadedOTelFileVersionInfo.FileVersion);

var autoInstrumentationOTelLocation = Path.Combine(StartupHook.LoaderAssemblyLocation ?? string.Empty, "OpenTelemetry.dll");
var autoInstrumentationOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(autoInstrumentationOTelLocation);
var autoInstrumentationOTelFileVersion = new Version(autoInstrumentationOTelFileVersionInfo.FileVersion);

var autoInstrumentationOTelFileVersion = GetVersionFromAutoInstrumentation();
if (loadedOTelFileVersion < autoInstrumentationOTelFileVersion)
{
oTelPackageVersion = loadedOTelFileVersionInfo.FileVersion;
oTelPackageVersion = loadedOTelFileVersion.ToString();
}
}
}
catch (Exception ex)
{
// Exception in evaluation should not throw or crash the process.
Logger.Information($"Couldn't evaluate reference to OpenTelemetry Sdk in an app. Exception: {ex}");
logger.Information($"Rule Engine: Couldn't evaluate reference to OpenTelemetry Sdk in an app. Exception: {ex}");
return true;
}

if (oTelPackageVersion != null)
{
Logger.Error($"Application has direct or indirect reference to older version of OpenTelemetry package {oTelPackageVersion}.");
logger.Error($"Rule Engine: Application has direct or indirect reference to older version of OpenTelemetry package {oTelPackageVersion}.");
return false;
}

logger.Information("Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.");
return true;
}

protected virtual Version? GetVersionFromApp()
{
var openTelemetryType = Type.GetType("OpenTelemetry.Sdk, OpenTelemetry");
if (openTelemetryType != null)
{
var loadedOTelAssembly = Assembly.GetAssembly(openTelemetryType);
var loadedOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(loadedOTelAssembly?.Location);
var loadedOTelFileVersion = new Version(loadedOTelFileVersionInfo.FileVersion);

return loadedOTelFileVersion;
}

return null;
}

protected virtual Version? GetVersionFromAutoInstrumentation()
{
var autoInstrumentationOTelLocation = Path.Combine(StartupHook.LoaderAssemblyLocation ?? string.Empty, "OpenTelemetry.dll");
var autoInstrumentationOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(autoInstrumentationOTelLocation);
var autoInstrumentationOTelFileVersion = new Version(autoInstrumentationOTelFileVersionInfo.FileVersion);

return autoInstrumentationOTelFileVersion;
}
}
4 changes: 2 additions & 2 deletions test/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\Directory.Packages.props" />
<ItemGroup>
<PackageVersion Include="BenchmarkDotNet" Version="0.13.5" />
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.0.10" />
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.1.0" />
<PackageVersion Include="FluentAssertions" Version="6.10.0" />
<PackageVersion Include="Google.Protobuf" Version="3.22.1" />
<PackageVersion Include="GraphQL" Version="2.4.0" />
Expand All @@ -17,7 +17,7 @@
<PackageVersion Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageVersion Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.5" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
/net/System.Security.Permissions.dll,
/net/System.ServiceModel.Primitives.dll,
/net/System.ServiceModel.dll,
/net/ruleEngine.json,
/store/x64/net6.0/dnsclient/1.4.0/lib/netstandard2.1/DnsClient.dll,
/store/x64/net6.0/microsoft.extensions.configuration.abstractions/7.0.0/lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll,
/store/x64/net6.0/microsoft.extensions.configuration.binder/7.0.0/lib/net7.0/Microsoft.Extensions.Configuration.Binder.dll,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
/net/System.Security.Permissions.dll,
/net/System.ServiceModel.Primitives.dll,
/net/System.ServiceModel.dll,
/net/ruleEngine.json,
/store/x64/net6.0/dnsclient/1.4.0/lib/netstandard2.1/DnsClient.dll,
/store/x64/net6.0/microsoft.extensions.configuration.abstractions/7.0.0/lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll,
/store/x64/net6.0/microsoft.extensions.configuration.binder/7.0.0/lib/net7.0/Microsoft.Extensions.Configuration.Binder.dll,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
/net/System.Security.Permissions.dll,
/net/System.ServiceModel.Primitives.dll,
/net/System.ServiceModel.dll,
/net/ruleEngine.json,
/osx-x64/OpenTelemetry.AutoInstrumentation.Native.dylib,
/store/x64/net6.0/dnsclient/1.4.0/lib/netstandard2.1/DnsClient.dll,
/store/x64/net6.0/microsoft.extensions.configuration.abstractions/7.0.0/lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
\net\System.Security.Permissions.dll,
\net\System.ServiceModel.Primitives.dll,
\net\System.ServiceModel.dll,
\net\ruleEngine.json,
\netfx\Google.Protobuf.dll,
\netfx\Grpc.Core.Api.dll,
\netfx\Grpc.Core.dll,
Expand Down
Loading

0 comments on commit 6e63924

Please sign in to comment.