Skip to content

Commit 00b3496

Browse files
feat: Implement DependencyFilterTelemetryProcessor to reduce telemetry volume for successful dependency calls
1 parent aa5b96d commit 00b3496

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using System.Linq;
3+
using Microsoft.ApplicationInsights.Channel;
4+
using Microsoft.ApplicationInsights.DataContracts;
5+
using Microsoft.ApplicationInsights.Extensibility;
6+
using Microsoft.Extensions.Configuration;
7+
8+
namespace XtremeIdiots.Portal.Web;
9+
10+
/// <summary>
11+
/// Filters out successful, fast dependency calls for configured dependency types
12+
/// to reduce telemetry volume. Failed calls and calls exceeding the duration
13+
/// threshold are always retained.
14+
/// </summary>
15+
public sealed class DependencyFilterTelemetryProcessor : ITelemetryProcessor
16+
{
17+
private readonly ITelemetryProcessor next;
18+
private readonly IConfiguration configuration;
19+
20+
public DependencyFilterTelemetryProcessor(ITelemetryProcessor next, IConfiguration configuration)
21+
{
22+
ArgumentNullException.ThrowIfNull(next);
23+
ArgumentNullException.ThrowIfNull(configuration);
24+
25+
this.next = next;
26+
this.configuration = configuration;
27+
}
28+
29+
public void Process(ITelemetry item)
30+
{
31+
if (item is DependencyTelemetry dependency && ShouldFilter(dependency))
32+
return;
33+
34+
next.Process(item);
35+
}
36+
37+
private bool ShouldFilter(DependencyTelemetry dependency)
38+
{
39+
if (string.IsNullOrEmpty(dependency.Type))
40+
return false;
41+
42+
var excludedTypes = configuration["ApplicationInsights:DependencyFilter:ExcludedTypes"]?
43+
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
44+
var excludedPrefixes = configuration["ApplicationInsights:DependencyFilter:ExcludedTypePrefixes"]?
45+
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
46+
47+
var typeMatches =
48+
(excludedTypes?.Any(t => string.Equals(dependency.Type, t, StringComparison.OrdinalIgnoreCase)) == true) ||
49+
(excludedPrefixes?.Any(p => dependency.Type.StartsWith(p, StringComparison.OrdinalIgnoreCase)) == true);
50+
51+
if (!typeMatches)
52+
return false;
53+
54+
if (dependency.Success != true)
55+
return false;
56+
57+
var thresholdMs = double.TryParse(
58+
configuration["ApplicationInsights:DependencyFilter:DurationThresholdMs"], out var t) ? t : 1000;
59+
if (dependency.Duration.TotalMilliseconds > thresholdMs)
60+
return false;
61+
62+
return true;
63+
}
64+
}

src/XtremeIdiots.Portal.Web/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
.Select("GameTracker:*", environmentLabel)
4949
.Select("Google:*", environmentLabel)
5050
.Select("FeatureManagement:*", environmentLabel)
51+
.Select("ApplicationInsights:*", environmentLabel)
5152
.ConfigureRefresh(refresh =>
5253
refresh.Register("Sentinel", environmentLabel, refreshAll: true)
5354
.SetRefreshInterval(TimeSpan.FromMinutes(5)));
@@ -80,6 +81,7 @@
8081
builder.Services.Configure<TelemetryConfiguration>(telemetryConfiguration =>
8182
{
8283
var telemetryProcessorChainBuilder = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
84+
telemetryProcessorChainBuilder.Use(next => new DependencyFilterTelemetryProcessor(next, builder.Configuration));
8385
telemetryProcessorChainBuilder.UseAdaptiveSampling(
8486
settings: samplingSettings,
8587
callback: null,

0 commit comments

Comments
 (0)