Skip to content

Commit 56ed0e8

Browse files
authored
[Continuous Profile] profiler.frame.type attribute for all locations (open-telemetry#3919)
1 parent 71df4e2 commit 56ed0e8

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

test/IntegrationTests/ContinuousProfilerTests.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#if NET
55

66
using IntegrationTests.Helpers;
7+
using OpenTelemetry.Proto.Collector.Profiles.V1Development;
78
using OpenTelemetry.Proto.Profiles.V1Development;
89
using Xunit.Abstractions;
910

@@ -43,17 +44,39 @@ public void ExportThreadSamples()
4344
SetExporter(collector);
4445
SetEnvironmentVariable("OTEL_DOTNET_AUTO_PLUGINS", "TestApplication.ContinuousProfiler.ThreadPlugin, TestApplication.ContinuousProfiler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
4546
SetEnvironmentVariable("OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES", "TestApplication.ContinuousProfiler");
46-
RunTestApplication();
47-
4847
var expectedStackTrace = string.Join("\n", CreateExpectedStackTrace());
4948

49+
collector.ExpectCollected(AllLocationReferencesProfileFrameTypeAttribute, "All location should contain reference to profile.frame.type attribute");
5050
collector.Expect(profileData => profileData.ResourceProfiles.Any(resourceProfiles => resourceProfiles.ScopeProfiles.Any(scopeProfile => scopeProfile.Profiles.Any(profile => ContainStackTraceForClassHierarchy(profile, expectedStackTrace) && ContainAttributes(profile, "cpu")))));
5151
collector.ResourceExpector.Expect("todo.resource.detector.key", "todo.resource.detector.value");
5252

53+
RunTestApplication();
54+
55+
collector.AssertCollected();
5356
collector.AssertExpectations();
5457
collector.ResourceExpector.AssertExpectations();
5558
}
5659

60+
private static bool AllLocationReferencesProfileFrameTypeAttribute(ICollection<ExportProfilesServiceRequest> c)
61+
{
62+
var profiles = c.SelectMany(r => r.ResourceProfiles)
63+
.SelectMany(rp => rp.ScopeProfiles)
64+
.SelectMany(sp => sp.Profiles).ToList();
65+
66+
foreach (var profile in profiles)
67+
{
68+
var attributeTable = profile.AttributeTable;
69+
70+
var attributeIndices = profiles.SelectMany(p => p.LocationTable).Select(l => l.AttributeIndices.Single());
71+
if (!attributeIndices.All(index => attributeTable[index] is { Key: "profile.frame.type" }))
72+
{
73+
return false;
74+
}
75+
}
76+
77+
return true;
78+
}
79+
5780
private static bool ContainAttributes(Profile profileContainer, string profilingDataType)
5881
{
5982
return profileContainer.AttributeTable.Any(x => x.Key == "todo.profiling.data.type" && x.Value.StringValue == profilingDataType);

test/IntegrationTests/Helpers/MockProfilesCollector.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ private static void FailExpectations(
157157
private static void FailCollectedExpectation(string? collectedExpectationDescription, ExportProfilesServiceRequest[] collectedExportProfilesServiceRequests)
158158
{
159159
var message = new StringBuilder();
160-
message.AppendLine($"Collected logs expectation failed: {collectedExpectationDescription}");
161-
message.AppendLine("Collected logs:");
160+
message.AppendLine($"Collected profiles expectation failed: {collectedExpectationDescription}");
161+
message.AppendLine("Collected profiles:");
162162
foreach (var logRecord in collectedExportProfilesServiceRequests)
163163
{
164164
message.AppendLine($" \"{logRecord}\"");

test/test-applications/integrations/TestApplication.ContinuousProfiler/Exporter/ExtendedPprofBuilder.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ public ExtendedPprofBuilder(string profilingDataType, long timestampNanoseconds)
2525
};
2626
var stringCache = new StringCache(Profile);
2727
var functionCache = new FunctionCache(Profile, stringCache);
28-
_locationCache = new LocationCache(Profile, functionCache);
2928
_linkCache = new LinkCache(Profile);
3029
_attributeCache = new AttributeCache(Profile);
30+
var profileFrameTypeAttributeId = _attributeCache.GetOrAdd("profile.frame.type", value => value.StringValue = "dotnet");
31+
32+
_locationCache = new LocationCache(Profile, functionCache, profileFrameTypeAttributeId);
3133

3234
var profilingDataTypeAttributeId = _attributeCache.GetOrAdd("todo.profiling.data.type", value => value.StringValue = profilingDataType);
3335
Profile.AttributeIndices.Add(profilingDataTypeAttributeId);
@@ -119,17 +121,20 @@ private class LocationCache
119121
{
120122
private readonly Profile _profile;
121123
private readonly FunctionCache _functionCache;
124+
private readonly int _profileFrameTypeAttributeId;
122125
private int _index;
123126

124-
public LocationCache(Profile profile, FunctionCache functionCache)
127+
public LocationCache(Profile profile, FunctionCache functionCache, int profileFrameTypeAttributeId)
125128
{
126129
_profile = profile;
127130
_functionCache = functionCache;
131+
_profileFrameTypeAttributeId = profileFrameTypeAttributeId;
128132
}
129133

130134
public int Add(string function)
131135
{
132136
var location = new Location();
137+
location.AttributeIndices.Add(_profileFrameTypeAttributeId);
133138
location.Line.Add(new Line { FunctionIndex = _functionCache.GetOrAdd(function), Line_ = 0, Column = 0 }); // for now, we don't support line nor column number
134139

135140
_profile.LocationTable.Add(location);

0 commit comments

Comments
 (0)