Skip to content

Commit f99ab89

Browse files
committed
Vendor the EventSource Name of the ILRepacked MetricsEventSource.
1 parent 5938845 commit f99ab89

6 files changed

Lines changed: 192 additions & 0 deletions

File tree

FullAgent.sln

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
44
VisualStudioVersion = 18.0.11205.157 d18.0
55
MinimumVisualStudioVersion = 15.0.26228.04
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "src\Agent\NewRelic\Agent\Core\Core.csproj", "{D6E22195-EE69-4320-B08B-E68229FB69AB}"
7+
ProjectSection(ProjectDependencies) = postProject
8+
{36C4B766-2A2F-CACB-CB91-0FC5C2E69773} = {36C4B766-2A2F-CACB-CB91-0FC5C2E69773}
9+
EndProjectSection
710
EndProject
811
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewRelic.Api.Agent", "src\Agent\NewRelic.Api.Agent\NewRelic.Api.Agent.csproj", "{64C7F267-5185-4AB7-9EB5-0183D8BB0171}"
912
EndProject
@@ -231,6 +234,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureServiceBus", "src\Agen
231234
EndProject
232235
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HybridHttpContext", "src\Agent\NewRelic\Agent\Extensions\Providers\Storage\HybridHttpContext\HybridHttpContext.csproj", "{CE9B992B-A2A7-20F9-9EEB-AE699C6D77CC}"
233236
EndProject
237+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssemblyModifier", "src\Agent\NewRelic\AssemblyModifier\AssemblyModifier.csproj", "{36C4B766-2A2F-CACB-CB91-0FC5C2E69773}"
238+
EndProject
234239
Global
235240
GlobalSection(SolutionConfigurationPlatforms) = preSolution
236241
Debug|Any CPU = Debug|Any CPU
@@ -485,6 +490,10 @@ Global
485490
{CE9B992B-A2A7-20F9-9EEB-AE699C6D77CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
486491
{CE9B992B-A2A7-20F9-9EEB-AE699C6D77CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
487492
{CE9B992B-A2A7-20F9-9EEB-AE699C6D77CC}.Release|Any CPU.Build.0 = Release|Any CPU
493+
{36C4B766-2A2F-CACB-CB91-0FC5C2E69773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
494+
{36C4B766-2A2F-CACB-CB91-0FC5C2E69773}.Debug|Any CPU.Build.0 = Debug|Any CPU
495+
{36C4B766-2A2F-CACB-CB91-0FC5C2E69773}.Release|Any CPU.ActiveCfg = Release|Any CPU
496+
{36C4B766-2A2F-CACB-CB91-0FC5C2E69773}.Release|Any CPU.Build.0 = Release|Any CPU
488497
EndGlobalSection
489498
GlobalSection(SolutionProperties) = preSolution
490499
HideSolutionNode = FALSE
@@ -558,6 +567,7 @@ Global
558567
{A0F784BB-D66D-47E0-80F4-66CF8DAF697C} = {5E86E10A-C38F-48CB-ADE9-67B22BB2F50A}
559568
{4078E594-E738-48F7-A7ED-B208ADD04900} = {5E86E10A-C38F-48CB-ADE9-67B22BB2F50A}
560569
{CE9B992B-A2A7-20F9-9EEB-AE699C6D77CC} = {2D194040-0192-4A87-A076-2B640C7FA82F}
570+
{36C4B766-2A2F-CACB-CB91-0FC5C2E69773} = {E3DAC9C6-AE41-4B37-A253-C621E568590E}
561571
EndGlobalSection
562572
GlobalSection(ExtensibilityGlobals) = postSolution
563573
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.2\lib\NET35

src/Agent/NewRelic/Agent/Core/Core.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@
188188

189189
<Message Importance="High" Text="Executing ILRepack.exe for $(TargetFramework) build: $(ILRepackCommand)" />
190190
<Exec Command="$(ILRepackCommand)" />
191+
192+
<PropertyGroup>
193+
<AssemblyModifierCommand>&quot;$(SolutionDir)src\Agent\NewRelic\AssemblyModifier\bin\$(Configuration)\AssemblyModifier.exe&quot;</AssemblyModifierCommand>
194+
<AssemblyToModify>&quot;$(OutputPath)..\$(TargetFramework)-ILRepacked\$(AssemblyName).dll&quot;</AssemblyToModify>
195+
<AssemblyDependency>&quot;$(OutputPath)..\..\NewRelic.Agent.Extensions\$(TargetFramework)-ILRepacked&quot;</AssemblyDependency>
196+
</PropertyGroup>
197+
<Message Importance="High" Text="Executing AssemblyModifier to complete the ILRepack process" />
198+
<Exec Command="$(AssemblyModifierCommand) $(AssemblyToModify) $(AssemblyDependency)" />
191199
</Target>
192200

193201
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
6+
<TargetFramework>net10.0</TargetFramework>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Mono.Cecil" Version="0.11.6" />
13+
</ItemGroup>
14+
15+
</Project>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Mono.Cecil;
5+
/// <summary>
6+
/// Defines a contract for a job that performs a modification on a module definition.
7+
/// </summary>
8+
/// <remarks>Implementations of this interface encapsulate logic to modify a given module. The result of the
9+
/// operation is indicated by the return value of the Run method.</remarks>
10+
public interface IModificationJob
11+
{
12+
/// <summary>
13+
/// Run the logic to modify the specified module.
14+
/// </summary>
15+
/// <param name="module">The module to modify</param>
16+
/// <returns>true if successful and false otherwise</returns>
17+
public bool Run(ModuleDefinition module);
18+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Mono.Cecil;
5+
/// <summary>
6+
/// Updates the name of the EventSource used to make metric data available out-of-process
7+
/// so that tools like dotnet-counters will use the application's EventSource data
8+
/// instead of the agent's EventSource data.
9+
/// </summary>
10+
public class InternalizeMetricsEventSourceName(Logger logger) : IModificationJob
11+
{
12+
public bool Run(ModuleDefinition module)
13+
{
14+
TypeDefinition? metricsEventSourceType = module.Types
15+
.FirstOrDefault(t => t.FullName == "System.Diagnostics.Metrics.MetricsEventSource");
16+
17+
if (metricsEventSourceType == null)
18+
{
19+
logger.Log("Type 'System.Diagnostics.Metrics.MetricsEventSource' not found in the assembly.");
20+
return false;
21+
}
22+
23+
CustomAttribute? eventSourceAttribute = metricsEventSourceType.CustomAttributes
24+
.FirstOrDefault(a => a.AttributeType.FullName == "System.Diagnostics.Tracing.EventSourceAttribute");
25+
26+
if (eventSourceAttribute == null)
27+
{
28+
logger.Log("EventSource attribute not found on the type.");
29+
return false;
30+
}
31+
32+
// Modify the EventSource attribute to add "Vendored." prefix
33+
var nameProperty = eventSourceAttribute.Properties.FirstOrDefault(p => p.Name == "Name");
34+
if (nameProperty.Name == null)
35+
{
36+
logger.Log("Name property not found in EventSource attribute.");
37+
return false;
38+
}
39+
40+
string currentName = nameProperty.Argument.Value?.ToString() ?? string.Empty;
41+
if (currentName.StartsWith("Vendored."))
42+
{
43+
logger.Log($"EventSource Name already has 'Vendored.' prefix: {currentName}");
44+
}
45+
46+
string newName = "Vendored." + currentName;
47+
48+
// Remove the old property
49+
eventSourceAttribute.Properties.Remove(nameProperty);
50+
51+
// Add the new property with updated value
52+
eventSourceAttribute.Properties.Add(new CustomAttributeNamedArgument(
53+
nameProperty.Name,
54+
new CustomAttributeArgument(nameProperty.Argument.Type, newName)));
55+
56+
logger.Log($"Updated EventSource Name from '{currentName}' to '{newName}'");
57+
58+
return true;
59+
}
60+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2020 New Relic, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Mono.Cecil;
5+
6+
if (args.Length == 0)
7+
{
8+
Console.WriteLine("Usage: <program> <assembly-path> <optional-search-directory>");
9+
return 1;
10+
}
11+
12+
string assemblyPath = args[0];
13+
var logger = GetLogger(assemblyPath);
14+
15+
if (!File.Exists(assemblyPath))
16+
{
17+
logger.Log($"Error: Assembly not found at '{assemblyPath}'");
18+
return 1;
19+
}
20+
21+
try
22+
{
23+
var resolver = new DefaultAssemblyResolver();
24+
25+
if (args.Length > 1 && Directory.Exists(args[1]))
26+
{
27+
resolver.AddSearchDirectory(args[1]);
28+
}
29+
30+
var parameters = new ReaderParameters
31+
{
32+
AssemblyResolver = resolver,
33+
ReadWrite = true
34+
};
35+
36+
using ModuleDefinition module = ModuleDefinition.ReadModule(assemblyPath, parameters);
37+
38+
IEnumerable<IModificationJob> jobs = [new InternalizeMetricsEventSourceName(logger)];
39+
40+
foreach (var job in jobs)
41+
{
42+
if (!job.Run(module))
43+
{
44+
logger.Log("Modification Job {0} failed.", job.GetType().Name);
45+
logger.Log("Not saving changes to the assembly.");
46+
return 2;
47+
}
48+
}
49+
50+
// Save the modified assembly
51+
module.Write();
52+
}
53+
catch (Exception ex)
54+
{
55+
logger.Log($"Error reading assembly: {ex.Message}");
56+
return 3;
57+
}
58+
59+
logger.Log("Completed all assembly modifications.");
60+
return 0;
61+
62+
static Logger GetLogger(string assemblyPath)
63+
{
64+
string context = "unknown: ";
65+
66+
var assemblyName = Path.GetFileName(assemblyPath);
67+
var directoryName = Path.GetFileName(Path.GetDirectoryName(assemblyPath));
68+
69+
if (string.IsNullOrWhiteSpace(assemblyName) || string.IsNullOrWhiteSpace(directoryName))
70+
return new Logger(context);
71+
72+
return new Logger($"{directoryName}\\{assemblyName}: ");
73+
}
74+
75+
public class Logger(string context)
76+
{
77+
public void Log(string message, params scoped ReadOnlySpan<object?> arg)
78+
{
79+
Console.WriteLine(context + message, arg);
80+
}
81+
}

0 commit comments

Comments
 (0)