@@ -7,7 +7,7 @@ Parsing HTTP User Agents with .NET
77| NuGet |
88| -|
99| [ ![ MyCSharp.HttpUserAgentParser] ( https://img.shields.io/nuget/v/MyCSharp.HttpUserAgentParser.svg?logo=nuget&label=MyCSharp.HttpUserAgentParser )] ( https://www.nuget.org/packages/MyCSharp.HttpUserAgentParser ) |
10- | [ ![ MyCSharp.HttpUserAgentParser] ( https://img.shields.io/nuget/v/MyCSharp.HttpUserAgentParser.MemoryCache.svg?logo=nuget&label=MyCSharp.HttpUserAgentParser.MemoryCache )] ( https://www.nuget.org/packages/MyCSharp.HttpUserAgentParser.MemoryCache ) | ` dotnet add package MyCSharp.HttpUserAgentParser.MemoryCach. MemoryCache ` |
10+ | [ ![ MyCSharp.HttpUserAgentParser] ( https://img.shields.io/nuget/v/MyCSharp.HttpUserAgentParser.MemoryCache.svg?logo=nuget&label=MyCSharp.HttpUserAgentParser.MemoryCache )] ( https://www.nuget.org/packages/MyCSharp.HttpUserAgentParser.MemoryCache ) | ` dotnet add package MyCSharp.HttpUserAgentParser.MemoryCache ` |
1111| [ ![ MyCSharp.HttpUserAgentParser.AspNetCore] ( https://img.shields.io/nuget/v/MyCSharp.HttpUserAgentParser.AspNetCore.svg?logo=nuget&label=MyCSharp.HttpUserAgentParser.AspNetCore )] ( https://www.nuget.org/packages/MyCSharp.HttpUserAgentParser.AspNetCore ) | ` dotnet add package MyCSharp.HttpUserAgentParser.AspNetCore ` |
1212
1313
@@ -110,6 +110,183 @@ public void MyMethod(IHttpUserAgentParserAccessor parserAccessor)
110110}
111111```
112112
113+ ## Telemetry (EventCounters)
114+
115+ Telemetry is ** opt-in** and ** modular per package** .
116+
117+ - Opt-in: no telemetry overhead unless you explicitly enable it.
118+ - Modular: each package has its own ` EventSource ` name, so you can monitor only what you use.
119+
120+ ### Enable telemetry (Fluent API)
121+
122+ Core parser telemetry:
123+
124+ ``` csharp
125+ public void ConfigureServices (IServiceCollection services )
126+ {
127+ services
128+ .AddHttpUserAgentParser ()
129+ .WithTelemetry ();
130+ }
131+ ```
132+
133+ MemoryCache telemetry (in addition to core, optional):
134+
135+ ``` csharp
136+ public void ConfigureServices (IServiceCollection services )
137+ {
138+ services
139+ .AddHttpUserAgentMemoryCachedParser ()
140+ .WithTelemetry () // core counters (optional)
141+ .WithMemoryCacheTelemetry ();
142+ }
143+ ```
144+
145+ ASP.NET Core telemetry (header present/missing):
146+
147+ ``` csharp
148+ public void ConfigureServices (IServiceCollection services )
149+ {
150+ services
151+ .AddHttpUserAgentMemoryCachedParser ()
152+ .AddHttpUserAgentParserAccessor ()
153+ .WithAspNetCoreTelemetry ();
154+ }
155+ ```
156+
157+ ### EventSource names and counters
158+
159+ Core (` MyCSharp.HttpUserAgentParser ` )
160+
161+ - ` parse-requests `
162+ - ` parse-duration ` (ms)
163+ - ` cache-concurrentdictionary-hit `
164+ - ` cache-concurrentdictionary-miss `
165+ - ` cache-concurrentdictionary-size `
166+
167+ MemoryCache (` MyCSharp.HttpUserAgentParser.MemoryCache ` )
168+
169+ - ` cache-hit `
170+ - ` cache-miss `
171+ - ` cache-size `
172+
173+ ASP.NET Core (` MyCSharp.HttpUserAgentParser.AspNetCore ` )
174+
175+ - ` useragent-present `
176+ - ` useragent-missing `
177+
178+ ### Monitor counters
179+
180+ Using ` dotnet-counters ` :
181+
182+ ``` bash
183+ dotnet-counters monitor --process-id < pid> MyCSharp.HttpUserAgentParser
184+ dotnet-counters monitor --process-id < pid> MyCSharp.HttpUserAgentParser.MemoryCache
185+ dotnet-counters monitor --process-id < pid> MyCSharp.HttpUserAgentParser.AspNetCore
186+ ```
187+
188+ ### Export to OpenTelemetry
189+
190+ You can collect these EventCounters via OpenTelemetry metrics.
191+
192+ Packages you typically need:
193+
194+ - ` OpenTelemetry `
195+ - ` OpenTelemetry.Instrumentation.EventCounters `
196+ - an exporter (e.g. ` OpenTelemetry.Exporter.OpenTelemetryProtocol ` )
197+
198+ Example (minimal):
199+
200+ ``` csharp
201+ using OpenTelemetry .Metrics ;
202+ using MyCSharp .HttpUserAgentParser .Telemetry ;
203+ using MyCSharp .HttpUserAgentParser .MemoryCache .Telemetry ;
204+ using MyCSharp .HttpUserAgentParser .AspNetCore .Telemetry ;
205+
206+ builder .Services .AddOpenTelemetry ()
207+ .WithMetrics (metrics =>
208+ {
209+ metrics
210+ .AddEventCountersInstrumentation (options =>
211+ {
212+ options .AddEventSources (
213+ HttpUserAgentParserEventSource .EventSourceName ,
214+ HttpUserAgentParserMemoryCacheEventSource .EventSourceName ,
215+ HttpUserAgentParserAspNetCoreEventSource .EventSourceName );
216+ })
217+ .AddOtlpExporter ();
218+ });
219+ ```
220+
221+ ### Export to Application Insights
222+
223+ Two common approaches:
224+
225+ 1 ) OpenTelemetry → Application Insights (recommended)
226+ - Collect counters with OpenTelemetry (see above)
227+ - Export using an Azure Monitor / Application Insights exporter (API varies by package/version)
228+
229+ 2 ) Custom ` EventListener ` → ` TelemetryClient `
230+ - Attach an ` EventListener `
231+ - Parse the ` EventCounters ` payload
232+ - Forward values as custom metrics
233+
234+ ### OpenTelemetry listener (recommended)
235+
236+ You can collect EventCounters as OpenTelemetry metrics.
237+
238+ Typical packages:
239+
240+ - ` OpenTelemetry `
241+ - ` OpenTelemetry.Instrumentation.EventCounters `
242+ - An exporter, e.g. ` OpenTelemetry.Exporter.OpenTelemetryProtocol `
243+
244+ Example:
245+
246+ ``` csharp
247+ using OpenTelemetry .Metrics ;
248+
249+ builder .Services .AddOpenTelemetry ()
250+ .WithMetrics (metrics =>
251+ {
252+ metrics
253+ .AddEventCountersInstrumentation (options =>
254+ {
255+ options .AddEventSources (
256+ HttpUserAgentParserEventSource .EventSourceName ,
257+ HttpUserAgentParserMemoryCacheEventSource .EventSourceName ,
258+ HttpUserAgentParserAspNetCoreEventSource .EventSourceName );
259+ })
260+ .AddOtlpExporter ();
261+ });
262+ ```
263+
264+ From there you can route metrics to:
265+
266+ - OpenTelemetry Collector
267+ - Prometheus
268+ - Azure Monitor / Application Insights (via an Azure Monitor exporter)
269+
270+ ### Application Insights listener (custom)
271+
272+ If you want a direct listener, you can attach an ` EventListener ` and forward counter values into Application Insights custom metrics.
273+
274+ High-level steps:
275+
276+ 1 ) Enable telemetry via ` .WithTelemetry() ` / ` .WithMemoryCacheTelemetry() ` / ` .WithAspNetCoreTelemetry() `
277+ 2 ) Register an ` EventListener ` that enables the corresponding EventSources
278+ 3 ) On ` EventCounters ` payload, forward values to ` TelemetryClient.GetMetric(...).TrackValue(...) `
279+
280+ Notes:
281+
282+ - This is best-effort telemetry.
283+ - Prefer longer polling intervals (e.g. 10s) to reduce noise.
284+
285+ > Notes
286+ >
287+ > - Counters are only emitted when telemetry is enabled and a listener is attached.
288+ > - Values are best-effort and may include cache races.
289+
113290## Benchmark
114291
115292``` shell
0 commit comments