forked from open-telemetry/opentelemetry-dotnet
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Azure] Application Insights Sampler (open-telemetry#148)
- Loading branch information
1 parent
5b147dd
commit 739c6b7
Showing
6 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
src/OpenTelemetry.Contrib.Extensions.AzureMonitor/ApplicationInsightsSampler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// <copyright file="ApplicationInsightsSampler.cs" company="OpenTelemetry Authors"> | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// </copyright> | ||
using System; | ||
|
||
using OpenTelemetry.Trace; | ||
|
||
namespace OpenTelemetry.Contrib.Extensions.AzureMonitor | ||
{ | ||
/// <summary> | ||
/// Sample configurable for OpenTelemetry exporters for compatibility | ||
/// with Application Insight SDKs. | ||
/// </summary> | ||
public class ApplicationInsightsSampler : Sampler | ||
{ | ||
private readonly float samplingRatio; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ApplicationInsightsSampler"/> class. | ||
/// </summary> | ||
/// <param name="samplingRatio">Ratio of telemetry that should be sampled.</param> | ||
public ApplicationInsightsSampler(float samplingRatio) | ||
{ | ||
// Ensure passed ratio is between 0 and 1, inclusive | ||
if (samplingRatio < 0 || samplingRatio > 1) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(samplingRatio), "Ratio must be between 0 and 1, inclusive."); | ||
} | ||
|
||
this.samplingRatio = samplingRatio; | ||
this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; | ||
} | ||
|
||
/// <summary> | ||
/// Computational method using the DJB2 Hash algorithm to decide whether to sample | ||
/// a given telemetry item, based on its Trace Id. | ||
/// </summary> | ||
/// <param name="samplingParameters">Parameters of telemetry item used to make sampling decision.</param> | ||
/// <returns>Returns whether or not we should sample telemetry in the form of a <see cref="SamplingResult"/> class.</returns> | ||
public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) | ||
{ | ||
double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToLowerInvariant()); | ||
return new SamplingResult(sampleScore < this.samplingRatio); | ||
} | ||
|
||
private static double DJB2SampleScore(string traceIdHex) | ||
{ | ||
// Calculate DJB2 hash code from hex-converted TraceId | ||
int hash = 5381; | ||
|
||
for (int i = 0; i < traceIdHex.Length; i++) | ||
{ | ||
hash = ((hash << 5) + hash) + (int)traceIdHex[i]; | ||
} | ||
|
||
// Take the absolute value of the hash | ||
if (hash == int.MinValue) | ||
{ | ||
hash = int.MaxValue; | ||
} | ||
else | ||
{ | ||
hash = Math.Abs(hash); | ||
} | ||
|
||
// Divide by MaxValue for value between 0 and 1 for sampling score | ||
double samplingScore = (double)hash / int.MaxValue; | ||
return samplingScore; | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...etry.Contrib.Extensions.AzureMonitor/OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>net461;net5.0</TargetFrameworks> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="OpenTelemetry" Version="[1.0.1,2.0.0)" /> | ||
</ItemGroup> | ||
|
||
</Project> |
15 changes: 15 additions & 0 deletions
15
src/OpenTelemetry.Contrib.Extensions.AzureMonitor/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Application Insights Sampler for OpenTelemetry .NET | ||
|
||
The ```Application Insights Sampler``` should be utilized when | ||
compatibility with Application Insights SDKs is desired, as it | ||
implements the same hash algorithm when deciding to sample telemetry. | ||
|
||
## Installation | ||
|
||
```shell | ||
dotnet add package OpenTelemetry.Contrib.Extensions.AzureMonitor | ||
``` | ||
|
||
## References | ||
|
||
* [OpenTelemetry Project](https://opentelemetry.io/) |
93 changes: 93 additions & 0 deletions
93
test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// <copyright file="ApplicationInsightsSamplerTests.cs" company="OpenTelemetry Authors"> | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// </copyright> | ||
|
||
using System; | ||
using System.Diagnostics; | ||
|
||
using OpenTelemetry.Trace; | ||
using Xunit; | ||
|
||
namespace OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests | ||
{ | ||
public class ApplicationInsightsSamplerTests | ||
{ | ||
[Fact] | ||
public void VerifyHashAlgorithmCorrectness() | ||
{ | ||
byte[] testBytes = new byte[] | ||
{ | ||
0x8F, 0xFF, 0xFF, 0xFF, | ||
0xFF, 0xFF, 0xFF, 0xFF, | ||
0, 0, 0, 0, 0, 0, 0, 0, | ||
}; | ||
byte[] testBytes2 = new byte[] | ||
{ | ||
0x0F, 0x1F, 0x2F, 0x3F, | ||
0x4F, 0x5F, 0x6F, 0x7F, | ||
0x8F, 0x9F, 0xAF, 0xBF, | ||
0xCF, 0xDF, 0xEF, 0xFF, | ||
}; | ||
ActivityTraceId testId = ActivityTraceId.CreateFromBytes(testBytes); | ||
ActivityTraceId testId2 = ActivityTraceId.CreateFromBytes(testBytes2); | ||
|
||
ActivityContext parentContext = default(ActivityContext); | ||
SamplingParameters testParams = new SamplingParameters(parentContext, testId, "TestActivity", ActivityKind.Internal); | ||
SamplingParameters testParams2 = new SamplingParameters(parentContext, testId2, "TestActivity", ActivityKind.Internal); | ||
|
||
var zeroSampler = new ApplicationInsightsSampler(0); | ||
ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1); | ||
|
||
// 0.86 is below the sample score for testId1, but strict enough to drop testId2 | ||
ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(0.86f); | ||
|
||
Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams).Decision); | ||
Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams2).Decision); | ||
|
||
Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams).Decision); | ||
Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams2).Decision); | ||
|
||
Assert.Equal(SamplingDecision.Drop, ratioSampler.ShouldSample(testParams).Decision); | ||
Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); | ||
} | ||
|
||
[Fact] | ||
public void ApplicationInsightsSamplerGoodArgs() | ||
{ | ||
ApplicationInsightsSampler pointFiveSampler = new ApplicationInsightsSampler(0.5f); | ||
Assert.NotNull(pointFiveSampler); | ||
|
||
ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(0f); | ||
Assert.NotNull(zeroSampler); | ||
|
||
ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1f); | ||
Assert.NotNull(oneSampler); | ||
} | ||
|
||
[Fact] | ||
public void ApplicationInsightsSamplerBadArgs() | ||
{ | ||
Assert.Throws<ArgumentOutOfRangeException>(() => new ApplicationInsightsSampler(-2f)); | ||
Assert.Throws<ArgumentOutOfRangeException>(() => new ApplicationInsightsSampler(2f)); | ||
} | ||
|
||
[Fact] | ||
public void GetDescriptionMatchesSpec() | ||
{ | ||
var expectedDescription = "ApplicationInsightsSampler{0.5}"; | ||
Assert.Equal(expectedDescription, new ApplicationInsightsSampler(0.5f).Description); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
....Extensions.AzureMonitor.Tests/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net5.0</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> | ||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" /> | ||
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" /> | ||
<PackageReference Include="coverlet.collector" Version="1.3.0" /> | ||
<PackageReference Include="OpenTelemetry" Version="[1.0.1,2.0.0)" /> | ||
<PackageReference Include="xunit" Version="2.4.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\OpenTelemetry.Contrib.Extensions.AzureMonitor\OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |