Skip to content

Commit 9286f56

Browse files
committed
app insights telemetry debugging
1 parent 38a5bcb commit 9286f56

File tree

2 files changed

+121
-3
lines changed

2 files changed

+121
-3
lines changed

src/PerfProblemSimulator/Controllers/AdminController.cs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.ApplicationInsights;
12
using Microsoft.AspNetCore.Http.Timeouts;
23
using Microsoft.AspNetCore.Mvc;
34
using PerfProblemSimulator.Services;
@@ -30,16 +31,22 @@ public class AdminController : ControllerBase
3031
{
3132
private readonly ISimulationTracker _simulationTracker;
3233
private readonly IMemoryPressureService _memoryPressureService;
34+
private readonly TelemetryClient? _telemetryClient;
35+
private readonly ILogger<AdminController> _logger;
3336

3437
/// <summary>
3538
/// Initializes a new instance of the <see cref="AdminController"/> class.
3639
/// </summary>
3740
public AdminController(
3841
ISimulationTracker simulationTracker,
39-
IMemoryPressureService memoryPressureService)
42+
IMemoryPressureService memoryPressureService,
43+
ILogger<AdminController> logger,
44+
TelemetryClient? telemetryClient = null)
4045
{
4146
_simulationTracker = simulationTracker ?? throw new ArgumentNullException(nameof(simulationTracker));
4247
_memoryPressureService = memoryPressureService ?? throw new ArgumentNullException(nameof(memoryPressureService));
48+
_logger = logger;
49+
_telemetryClient = telemetryClient;
4350
}
4451

4552
/// <summary>
@@ -89,6 +96,57 @@ public IActionResult GetStats()
8996
}
9097
});
9198
}
99+
100+
/// <summary>
101+
/// Tests Application Insights telemetry by sending a test event and trace.
102+
/// Use this endpoint to verify Application Insights is configured correctly.
103+
/// </summary>
104+
/// <returns>Diagnostic information about Application Insights configuration.</returns>
105+
/// <response code="200">Returns telemetry diagnostic information.</response>
106+
[HttpGet("test-appinsights")]
107+
[ProducesResponseType(StatusCodes.Status200OK)]
108+
public IActionResult TestAppInsights()
109+
{
110+
var testId = Guid.NewGuid();
111+
var diagnostics = new AppInsightsDiagnostics
112+
{
113+
TestId = testId,
114+
TelemetryClientResolved = _telemetryClient != null,
115+
TelemetryClientEnabled = _telemetryClient?.IsEnabled() ?? false,
116+
ConnectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING") is { } cs
117+
? (cs.Length > 20 ? cs[..20] + "..." : cs) // Truncate for security
118+
: null
119+
};
120+
121+
// Log a test trace via ILogger
122+
_logger.LogWarning("🧪 TEST TRACE via ILogger - TestId: {TestId} - If you see this in AppTraces, ILogger works!", testId);
123+
124+
// Send a test event via TelemetryClient
125+
if (_telemetryClient != null && _telemetryClient.IsEnabled())
126+
{
127+
_telemetryClient.TrackEvent("TestEvent", new Dictionary<string, string>
128+
{
129+
["TestId"] = testId.ToString(),
130+
["Source"] = "AdminController.TestAppInsights"
131+
});
132+
_telemetryClient.Flush();
133+
Thread.Sleep(500); // Give time for flush
134+
135+
diagnostics.TestEventSent = true;
136+
137+
_logger.LogWarning("🧪 TEST EVENT sent via TelemetryClient - TestId: {TestId} - If you see this in AppEvents, TrackEvent works!", testId);
138+
}
139+
else
140+
{
141+
diagnostics.TestEventSent = false;
142+
_logger.LogWarning("⚠️ TelemetryClient not available or disabled - cannot send test event");
143+
}
144+
145+
diagnostics.KqlQueryForTrace = $@"AppTraces | where TimeGenerated > ago(5m) | where Message contains ""{testId}"" | project TimeGenerated, Message";
146+
diagnostics.KqlQueryForEvent = $@"AppEvents | where TimeGenerated > ago(5m) | where Name == ""TestEvent"" | where Properties.TestId == ""{testId}"" | project TimeGenerated, Name, Properties";
147+
148+
return Ok(diagnostics);
149+
}
92150
}
93151

94152
/// <summary>
@@ -214,3 +272,44 @@ public class ProcessStats
214272
/// </summary>
215273
public string? ComputerName { get; init; }
216274
}
275+
276+
/// <summary>
277+
/// Diagnostic information about Application Insights configuration.
278+
/// </summary>
279+
public class AppInsightsDiagnostics
280+
{
281+
/// <summary>
282+
/// Unique identifier for this test run.
283+
/// </summary>
284+
public Guid TestId { get; init; }
285+
286+
/// <summary>
287+
/// Whether TelemetryClient was resolved from DI.
288+
/// </summary>
289+
public bool TelemetryClientResolved { get; init; }
290+
291+
/// <summary>
292+
/// Whether TelemetryClient.IsEnabled() returns true.
293+
/// </summary>
294+
public bool TelemetryClientEnabled { get; init; }
295+
296+
/// <summary>
297+
/// Truncated connection string (for verification).
298+
/// </summary>
299+
public string? ConnectionString { get; init; }
300+
301+
/// <summary>
302+
/// Whether a test event was sent.
303+
/// </summary>
304+
public bool TestEventSent { get; set; }
305+
306+
/// <summary>
307+
/// KQL query to find the test trace in AppTraces.
308+
/// </summary>
309+
public string? KqlQueryForTrace { get; set; }
310+
311+
/// <summary>
312+
/// KQL query to find the test event in AppEvents.
313+
/// </summary>
314+
public string? KqlQueryForEvent { get; set; }
315+
}

src/PerfProblemSimulator/Program.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Microsoft.ApplicationInsights;
12
using PerfProblemSimulator.Hubs;
23
using PerfProblemSimulator.Models;
34
using PerfProblemSimulator.Services;
@@ -254,12 +255,30 @@
254255
// or the ApplicationInsights:ConnectionString configuration setting.
255256
// Educational Note: Application Insights v3 uses OpenTelemetry under the hood.
256257
// Request tracking, dependency tracking, exception logging are automatic.
257-
builder.Services.AddApplicationInsightsTelemetry();
258+
// ILogger integration is also automatic - no separate AddApplicationInsights() call needed.
259+
builder.Services.AddApplicationInsightsTelemetry(options =>
260+
{
261+
// Enable automatic tracking of ILogger logs
262+
options.EnableQuickPulseMetricStream = true;
263+
});
258264

259265
// SimulationContext - Singleton service for tracking current simulation context
260266
// Educational Note: This uses AsyncLocal<T> to flow the simulation ID across async calls.
261267
// The context also uses TelemetryClient to track simulation events with the ID attached.
262-
builder.Services.AddSingleton<ISimulationContext, SimulationContext>();
268+
// The TelemetryClient is resolved from DI after Application Insights is configured.
269+
builder.Services.AddSingleton<ISimulationContext>(sp =>
270+
{
271+
var logger = sp.GetRequiredService<ILogger<SimulationContext>>();
272+
var telemetryClient = sp.GetService<TelemetryClient>();
273+
274+
// Log the telemetry configuration status at startup
275+
logger.LogWarning(
276+
"🔧 Resolving SimulationContext from DI. TelemetryClient resolved: {Resolved}, IsEnabled: {IsEnabled}",
277+
telemetryClient != null,
278+
telemetryClient?.IsEnabled() ?? false);
279+
280+
return new SimulationContext(logger, telemetryClient);
281+
});
263282

264283
// -----------------------------------------------------------------------------
265284
// Request Timeouts (Kestrel)

0 commit comments

Comments
 (0)