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

Features and bug fixes #15

Merged
merged 10 commits into from
Sep 19, 2023
Merged
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
37 changes: 0 additions & 37 deletions Autometrics Samples.sln

This file was deleted.

33 changes: 33 additions & 0 deletions Autometrics-CS.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,57 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autometrics.Instrumentation.Tests", "src\Autometrics.Instrumentation.Tests\Autometrics.Instrumentation.Tests.csproj", "{93EAE891-CAB6-47D4-80A8-B151A423FDA6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{12A476A7-0753-4A7E-BFA9-6D2701B34E89}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autometrics.Samples.ConsoleApp", "examples\Autometrics.Samples.ConsoleApp\Autometrics.Samples.ConsoleApp.csproj", "{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autometrics.Samples.Library", "examples\Autometrics.Samples.Library\Autometrics.Samples.Library.csproj", "{8EDA190B-A429-4BB9-949F-4507870F3275}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autometrics.Samples.WebApp", "examples\Autometrics.Samples.WebApp\Autometrics.Samples.WebApp.csproj", "{99E9E740-B530-4B7F-9598-C044E669F56E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Local Release|Any CPU = Local Release|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A220D3AC-D7FC-4CCA-BC38-F209691851C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A220D3AC-D7FC-4CCA-BC38-F209691851C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A220D3AC-D7FC-4CCA-BC38-F209691851C2}.Local Release|Any CPU.ActiveCfg = Local Release|Any CPU
{A220D3AC-D7FC-4CCA-BC38-F209691851C2}.Local Release|Any CPU.Build.0 = Local Release|Any CPU
{A220D3AC-D7FC-4CCA-BC38-F209691851C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A220D3AC-D7FC-4CCA-BC38-F209691851C2}.Release|Any CPU.Build.0 = Release|Any CPU
{93EAE891-CAB6-47D4-80A8-B151A423FDA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93EAE891-CAB6-47D4-80A8-B151A423FDA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93EAE891-CAB6-47D4-80A8-B151A423FDA6}.Local Release|Any CPU.ActiveCfg = Local Release|Any CPU
{93EAE891-CAB6-47D4-80A8-B151A423FDA6}.Local Release|Any CPU.Build.0 = Local Release|Any CPU
{93EAE891-CAB6-47D4-80A8-B151A423FDA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93EAE891-CAB6-47D4-80A8-B151A423FDA6}.Release|Any CPU.Build.0 = Release|Any CPU
{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC}.Local Release|Any CPU.ActiveCfg = Local Release|Any CPU
{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC}.Local Release|Any CPU.Build.0 = Local Release|Any CPU
{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EDA190B-A429-4BB9-949F-4507870F3275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EDA190B-A429-4BB9-949F-4507870F3275}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EDA190B-A429-4BB9-949F-4507870F3275}.Local Release|Any CPU.ActiveCfg = Local Release|Any CPU
{8EDA190B-A429-4BB9-949F-4507870F3275}.Local Release|Any CPU.Build.0 = Local Release|Any CPU
{8EDA190B-A429-4BB9-949F-4507870F3275}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99E9E740-B530-4B7F-9598-C044E669F56E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99E9E740-B530-4B7F-9598-C044E669F56E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99E9E740-B530-4B7F-9598-C044E669F56E}.Local Release|Any CPU.ActiveCfg = Local Release|Any CPU
{99E9E740-B530-4B7F-9598-C044E669F56E}.Local Release|Any CPU.Build.0 = Local Release|Any CPU
{99E9E740-B530-4B7F-9598-C044E669F56E}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{488AB5DF-36E4-4992-B9A7-8C2E6D188CDC} = {12A476A7-0753-4A7E-BFA9-6D2701B34E89}
{8EDA190B-A429-4BB9-949F-4507870F3275} = {12A476A7-0753-4A7E-BFA9-6D2701B34E89}
{99E9E740-B530-4B7F-9598-C044E669F56E} = {12A476A7-0753-4A7E-BFA9-6D2701B34E89}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {422C978E-1479-4996-B5D7-B494E97E3B45}
EndGlobalSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<AssemblyVersion>1.0.2.1</AssemblyVersion>
<Version></Version>
<FileVersion></FileVersion>
<Configurations>Debug;Release;Local Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand All @@ -18,7 +19,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Autometrics.Instrumentation\Autometrics.Instrumentation.csproj" />
<ProjectReference Include="..\..\src\Autometrics.Instrumentation\Autometrics.Instrumentation.csproj" />
<ProjectReference Include="..\Autometrics.Samples.Library\Autometrics.Samples.Library.csproj" />
</ItemGroup>

Expand Down
3 changes: 3 additions & 0 deletions examples/Autometrics.Samples.ConsoleApp/ConsoleMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ public static void GenerateActivity()
// Create a meter provider with the console exporter connected to the Autometrics.Instrumentation meter
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("Autometrics.Instrumentation")
.AddView(
instrumentName: "function.calls.duration",
new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 } })
.AddConsoleExporter()
.Build();

Expand Down
3 changes: 3 additions & 0 deletions examples/Autometrics.Samples.ConsoleApp/OtelCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ public static void GenerateActivity()
// Create a meter provider with the Otlp exporter connected to the Autometrics.Instrumentation
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("Autometrics.Instrumentation")
.AddView(
instrumentName: "function.calls.duration",
new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 } })
.AddOtlpExporter()
.Build();

Expand Down
3 changes: 3 additions & 0 deletions examples/Autometrics.Samples.ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ private static void Main(string[] args)
Console.WriteLine("6. Exit");
Console.Write("Enter the option number: ");

//set the environment variable for the service name, yuo can also use OTEL_SERVICE_NAME
System.Environment.SetEnvironmentVariable("AUTOMETRICS_SERVICE_NAME", "Console Simulator!");

if (int.TryParse(Console.ReadLine(), out int option))
{
switch (option)
Expand Down
5 changes: 4 additions & 1 deletion examples/Autometrics.Samples.ConsoleApp/ScrapableMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ public static void GenerateActivity()
// Create a meter provider with the console exporter connected to the Autometrics.Instrumentation meter
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("Autometrics.Instrumentation")
.AddView(
instrumentName: "function.calls.duration",
new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 } })
.AddPrometheusHttpListener(
options =>
{
options.UriPrefixes = new string[] { "http://localhost:9090/" };
options.UriPrefixes = new string[] { "http://localhost:9091/" };
})
.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Configurations>Debug;Release;Local Release</Configurations>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Autometrics.Instrumentation\Autometrics.Instrumentation.csproj" />
<ProjectReference Include="..\..\src\Autometrics.Instrumentation\Autometrics.Instrumentation.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Configurations>Debug;Release;Local Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand All @@ -12,7 +13,8 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Autometrics.Instrumentation\Autometrics.Instrumentation.csproj" />
<ProjectReference Include="..\..\src\Autometrics.Instrumentation\Autometrics.Instrumentation.csproj" />
<ProjectReference Include="..\Autometrics.Samples.Library\Autometrics.Samples.Library.csproj" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions examples/Autometrics.Samples.WebApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
// Additional configuration or other exporters can be added here
builder.AddOtlpExporter();
builder.AddMeter("Autometrics.Instrumentation");
builder.AddView(
instrumentName: "function.calls.duration",
new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 } }
);
});

var app = builder.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<Configurations>Debug;Release;Local Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public MetricReading(string metricName, T reading, KeyValuePair<string, object?>
case "result":
Result = tag.Value?.ToString();
break;
case "caller":
case "caller.function":
Caller = tag.Value?.ToString();
break;
case "objectiveName":
Expand Down
59 changes: 7 additions & 52 deletions src/Autometrics.Instrumentation/Aspects/AutometricsAspect.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using AspectInjector.Broker;
using Autometrics.Instrumentation.Attributes;
using Autometrics.Instrumentation.SLO;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace Autometrics.Instrumentation.Aspects
Expand All @@ -18,10 +15,6 @@ namespace Autometrics.Instrumentation.Aspects
[Aspect(Scope.Global)]
public class AutometricsAspect
{
// Aspect Injection renames methods, if we get a renamed one it will look like this: __a$_around_SaferMethod_100663303_o
// We need a regex to identify these methods
private static readonly string renamedMethodRegex = @"^__a\$_around_(?<originalMethodName>.*)_\d{5,10}_o$";

/// <summary>
/// This is the method that will be injected into the target method, it will wrap the target method in a try/catch block and record the duration of the method call
/// If any exceptions are thrown, they will be rethrown after the duration is recorded and a result of error tagged on the metric
Expand All @@ -40,18 +33,21 @@ public object HandleMethod(
[Argument(Source.Triggers)] Attribute[] triggers)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
bool success = false;

// We'll start with our objective as null, but if the trigger has one we'll use it
Objective? slo = null;
string? serviceName = null;
if (triggers.Length > 0 && triggers[0] is AutometricsAttribute attribute)
{
slo = attribute.SLO;
serviceName = attribute.GetServiceName();
}

try
{
// start the stopwatch, call the method, stop the stopwatch to record the duration
stopwatch.Start();
object result = method(arguments);
success = true;
return result;
Expand All @@ -64,50 +60,9 @@ public object HandleMethod(
finally
{
stopwatch.Stop();
MetricCounters.RecordFunctionCall(stopwatch.Elapsed.TotalSeconds, methodName, success, metadata.DeclaringType.FullName, GetCallingMethodName(metadata), slo);
CallingMethod caller = new CallingMethod(metadata);
MetricCounters.RecordFunctionCall(stopwatch.Elapsed.TotalSeconds, methodName, success, metadata.DeclaringType.FullName, caller, serviceName, slo);
}
}

/// <summary>
/// This resolves the name of the calling method, and if the calling method was renamed by AspectInjector, it will attempt to return the original name via regex
/// </summary>
/// <param name="method">The metadata from AspectInjector</param>
/// <returns></returns>
private static string? GetCallingMethodName(MethodBase method)
{
var stackTrace = new StackTrace();
var stackFrames = stackTrace.GetFrames();
MethodBase callingMethod = null;

if (stackFrames == null)
{
return null;
}

for (int i = 0; i < stackFrames.Length; i++)
{
if (stackFrames[i].GetMethod() == method)
{
// The calling method is the one before the current method in the stack
callingMethod = i + 1 < stackFrames.Length ? stackFrames[i + 1].GetMethod() : null;
}
}

// If the calling method isn't null, match it to our regex to see if it's a renamed method, then return the original name
if (callingMethod != null)
{
var match = Regex.Match(callingMethod.Name, renamedMethodRegex, RegexOptions.Compiled);
if (match.Success)
{
return match.Groups["originalMethodName"].Value;
}
else
{
return callingMethod.Name;
}
}

return null;
}
}
}
}
18 changes: 18 additions & 0 deletions src/Autometrics.Instrumentation/Attributes/AutometricsAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,38 @@ public class AutometricsAttribute : Attribute
/// <see href="https://github.com/autometrics-dev/autometrics-shared/blob/main/SPEC.md#service-level-objectives-slos">Service-Level Objectives (SLOs) Spec</see>
/// </summary>
public Objective? SLO { get; }
public string EntryAssemblyName { get; private set; }

public AutometricsAttribute()
{
SLO = null;
EntryAssemblyName = GetAssemblyName();
}

public AutometricsAttribute(string objectiveName, ObjectivePercentile objectivePercentile, ObjectiveLatency objectiveLatencyThreshold, ObjectiveType objectiveType = ObjectiveType.SuccessAndLatency)
{
SLO = new Objective(objectiveName, objectivePercentile, objectiveLatencyThreshold, objectiveType);
EntryAssemblyName = GetAssemblyName();
}

public AutometricsAttribute(string objectiveName, ObjectivePercentile objectivePercentile)
{
SLO = new Objective(objectiveName, objectivePercentile);
EntryAssemblyName = GetAssemblyName();
}

private string GetAssemblyName()
{
return Assembly.GetEntryAssembly()?.GetName().Name ?? "Unknown";
}

/// <summary>
/// Gets the ServiceName, starting at the Attribule level, then the Environment Variable, then the EntryAssemblyName
/// </summary>
/// <returns></returns>
public string GetServiceName()
{
return Environment.GetEnvironmentVariable("AUTOMETRICS_SERVICE_NAME") ?? Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME") ?? EntryAssemblyName;
}

}
Expand Down
Loading
Loading