🔷 📊 Performance Monitoring - TuskLang for C# - "Monitoring Mastery"

C# Documentation

📊 Performance Monitoring - TuskLang for C# - "Monitoring Mastery"

Master performance monitoring with TuskLang in your C# applications!

Performance monitoring is essential for maintaining application health and optimizing performance. This guide covers metrics collection, performance profiling, monitoring dashboards, and real-world monitoring scenarios for TuskLang in C# environments.

📈 Monitoring Philosophy

"We Don't Bow to Any King"

- Monitor everything - Track all performance metrics - Real-time alerts - Get notified of issues immediately - Historical analysis - Understand performance trends - Proactive optimization - Optimize before problems occur - Business metrics - Monitor what matters to users

📊 Metrics Collection

Example: Metrics Collection Service

// MetricsCollectionService.cs
using System.Diagnostics;

public class MetricsCollectionService { private readonly TuskLang _parser; private readonly ILogger<MetricsCollectionService> _logger; private readonly Dictionary<string, Metric> _metrics; private readonly Timer _collectionTimer; public MetricsCollectionService(ILogger<MetricsCollectionService> logger) { _parser = new TuskLang(); _logger = logger; _metrics = new Dictionary<string, Metric>(); LoadMetricsConfiguration(); _collectionTimer = new Timer(CollectMetrics, null, TimeSpan.Zero, TimeSpan.FromSeconds(30)); } private void LoadMetricsConfiguration() { var config = _parser.ParseFile("config/metrics.tsk"); var metricDefinitions = config["metrics"] as Dictionary<string, object>; foreach (var metric in metricDefinitions ?? new Dictionary<string, object>()) { var metricName = metric.Key; var metricConfig = metric.Value as Dictionary<string, object>; if (metricConfig != null) { _metrics[metricName] = new Metric { Name = metricName, Type = metricConfig["type"].ToString(), Description = metricConfig["description"].ToString(), Unit = metricConfig["unit"].ToString() }; } } _logger.LogInformation("Loaded {Count} metric definitions", _metrics.Count); } private void CollectMetrics(object? state) { try { // Collect system metrics CollectSystemMetrics(); // Collect application metrics CollectApplicationMetrics(); // Collect custom metrics CollectCustomMetrics(); _logger.LogDebug("Metrics collection completed"); } catch (Exception ex) { _logger.LogError(ex, "Error during metrics collection"); } } private void CollectSystemMetrics() { var process = Process.GetCurrentProcess(); RecordMetric("cpu_usage_percent", process.TotalProcessorTime.TotalMilliseconds / Environment.ProcessorCount); RecordMetric("memory_usage_mb", process.WorkingSet64 / 1024 / 1024); RecordMetric("thread_count", process.Threads.Count); RecordMetric("handle_count", process.HandleCount); } private void CollectApplicationMetrics() { var gc = GC.GetGCMemoryInfo(); RecordMetric("heap_size_mb", gc.HeapSizeBytes / 1024 / 1024); RecordMetric("gc_collections", GC.CollectionCount(0) + GC.CollectionCount(1) + GC.CollectionCount(2)); RecordMetric("active_connections", GetActiveConnections()); RecordMetric("request_queue_length", GetRequestQueueLength()); } private void CollectCustomMetrics() { // Collect business-specific metrics RecordMetric("active_users", GetActiveUserCount()); RecordMetric("database_connections", GetDatabaseConnectionCount()); RecordMetric("cache_hit_rate", GetCacheHitRate()); } public void RecordMetric(string name, double value) { if (_metrics.ContainsKey(name)) { var metric = _metrics[name]; metric.AddValue(value); _logger.LogDebug("Recorded metric {MetricName}: {Value} {Unit}", name, value, metric.Unit); } } public async Task<Dictionary<string, object>> GetMetricsSnapshotAsync() { var snapshot = new Dictionary<string, object>(); foreach (var metric in _metrics) { snapshot[metric.Key] = new Dictionary<string, object> { ["current_value"] = metric.Value.CurrentValue, ["average_value"] = metric.Value.AverageValue, ["min_value"] = metric.Value.MinValue, ["max_value"] = metric.Value.MaxValue, ["unit"] = metric.Value.Unit, ["description"] = metric.Value.Description, ["last_updated"] = metric.Value.LastUpdated.ToString("yyyy-MM-dd HH:mm:ss") }; } return snapshot; } // Placeholder methods for metric collection private int GetActiveConnections() => 42; private int GetRequestQueueLength() => 15; private int GetActiveUserCount() => 1250; private int GetDatabaseConnectionCount() => 8; private double GetCacheHitRate() => 0.85; }

public class Metric { public string Name { get; set; } = string.Empty; public string Type { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string Unit { get; set; } = string.Empty; public double CurrentValue { get; private set; } public double AverageValue { get; private set; } public double MinValue { get; private set; } = double.MaxValue; public double MaxValue { get; private set; } = double.MinValue; public int SampleCount { get; private set; } public DateTime LastUpdated { get; private set; } public void AddValue(double value) { CurrentValue = value; MinValue = Math.Min(MinValue, value); MaxValue = Math.Max(MaxValue, value); if (SampleCount == 0) { AverageValue = value; } else { AverageValue = ((AverageValue * SampleCount) + value) / (SampleCount + 1); } SampleCount++; LastUpdated = DateTime.UtcNow; } }

🔍 Performance Profiling

Example: Performance Profiling Service

// PerformanceProfilingService.cs
public class PerformanceProfilingService
{
    private readonly TuskLang _parser;
    private readonly ILogger<PerformanceProfilingService> _logger;
    private readonly Dictionary<string, PerformanceProfile> _profiles;
    
    public PerformanceProfilingService(ILogger<PerformanceProfilingService> logger)
    {
        _parser = new TuskLang();
        _logger = logger;
        _profiles = new Dictionary<string, PerformanceProfile>();
        
        LoadProfilingConfiguration();
    }
    
    private void LoadProfilingConfiguration()
    {
        var config = _parser.ParseFile("config/profiling.tsk");
        var profilingRules = config["profiling_rules"] as Dictionary<string, object>;
        
        foreach (var rule in profilingRules ?? new Dictionary<string, object>())
        {
            var ruleName = rule.Key;
            var ruleConfig = rule.Value as Dictionary<string, object>;
            
            if (ruleConfig != null)
            {
                _profiles[ruleName] = new PerformanceProfile
                {
                    Name = ruleName,
                    ThresholdMs = int.Parse(ruleConfig["threshold_ms"].ToString()),
                    Enabled = bool.Parse(ruleConfig["enabled"].ToString())
                };
            }
        }
        
        _logger.LogInformation("Loaded {Count} profiling rules", _profiles.Count);
    }
    
    public IDisposable CreateProfile(string operationName)
    {
        return new PerformanceScope(operationName, this);
    }
    
    public void RecordOperation(string operationName, long durationMs, Dictionary<string, object>? metadata = null)
    {
        if (!_profiles.ContainsKey(operationName))
        {
            return;
        }
        
        var profile = _profiles[operationName];
        profile.RecordOperation(durationMs, metadata);
        
        if (durationMs > profile.ThresholdMs)
        {
            _logger.LogWarning("Performance threshold exceeded for {OperationName}: {DurationMs}ms > {ThresholdMs}ms", 
                operationName, durationMs, profile.ThresholdMs);
        }
    }
    
    public async Task<Dictionary<string, object>> GetPerformanceReportAsync()
    {
        var report = new Dictionary<string, object>();
        
        foreach (var profile in _profiles)
        {
            report[profile.Key] = new Dictionary<string, object>
            {
                ["total_operations"] = profile.Value.TotalOperations,
                ["average_duration_ms"] = profile.Value.AverageDuration,
                ["min_duration_ms"] = profile.Value.MinDuration,
                ["max_duration_ms"] = profile.Value.MaxDuration,
                ["threshold_exceeded_count"] = profile.Value.ThresholdExceededCount,
                ["threshold_ms"] = profile.Value.ThresholdMs,
                ["enabled"] = profile.Value.Enabled
            };
        }
        
        return report;
    }
}

public class PerformanceScope : IDisposable { private readonly string _operationName; private readonly PerformanceProfilingService _profilingService; private readonly Stopwatch _stopwatch; private readonly Dictionary<string, object> _metadata; public PerformanceScope(string operationName, PerformanceProfilingService profilingService) { _operationName = operationName; _profilingService = profilingService; _stopwatch = Stopwatch.StartNew(); _metadata = new Dictionary<string, object>(); } public void AddMetadata(string key, object value) { _metadata[key] = value; } public void Dispose() { _stopwatch.Stop(); _profilingService.RecordOperation(_operationName, _stopwatch.ElapsedMilliseconds, _metadata); } }

public class PerformanceProfile { public string Name { get; set; } = string.Empty; public long ThresholdMs { get; set; } public bool Enabled { get; set; } public int TotalOperations { get; private set; } public double AverageDuration { get; private set; } public long MinDuration { get; private set; } = long.MaxValue; public long MaxDuration { get; private set; } public int ThresholdExceededCount { get; private set; } public void RecordOperation(long durationMs, Dictionary<string, object>? metadata = null) { if (!Enabled) return; TotalOperations++; MinDuration = Math.Min(MinDuration, durationMs); MaxDuration = Math.Max(MaxDuration, durationMs); if (TotalOperations == 1) { AverageDuration = durationMs; } else { AverageDuration = ((AverageDuration * (TotalOperations - 1)) + durationMs) / TotalOperations; } if (durationMs > ThresholdMs) { ThresholdExceededCount++; } } }

📊 Monitoring Dashboard

Example: Monitoring Dashboard Service

// MonitoringDashboardService.cs
public class MonitoringDashboardService
{
    private readonly MetricsCollectionService _metricsService;
    private readonly PerformanceProfilingService _profilingService;
    private readonly TuskLang _parser;
    private readonly ILogger<MonitoringDashboardService> _logger;
    
    public MonitoringDashboardService(
        MetricsCollectionService metricsService,
        PerformanceProfilingService profilingService,
        ILogger<MonitoringDashboardService> logger)
    {
        _metricsService = metricsService;
        _profilingService = profilingService;
        _parser = new TuskLang();
        _logger = logger;
    }
    
    public async Task<Dictionary<string, object>> GetDashboardDataAsync()
    {
        var dashboard = new Dictionary<string, object>();
        
        // System health
        dashboard["system_health"] = await GetSystemHealthAsync();
        
        // Performance metrics
        dashboard["performance_metrics"] = await GetPerformanceMetricsAsync();
        
        // Application metrics
        dashboard["application_metrics"] = await GetApplicationMetricsAsync();
        
        // Alerts
        dashboard["alerts"] = await GetActiveAlertsAsync();
        
        return dashboard;
    }
    
    private async Task<Dictionary<string, object>> GetSystemHealthAsync()
    {
        var health = new Dictionary<string, object>();
        
        var metrics = await _metricsService.GetMetricsSnapshotAsync();
        
        // CPU health
        var cpuUsage = Convert.ToDouble(metrics["cpu_usage_percent"]);
        health["cpu_health"] = new Dictionary<string, object>
        {
            ["status"] = cpuUsage > 80 ? "Critical" : cpuUsage > 60 ? "Warning" : "Healthy",
            ["value"] = cpuUsage,
            ["threshold"] = 80
        };
        
        // Memory health
        var memoryUsage = Convert.ToDouble(metrics["memory_usage_mb"]);
        health["memory_health"] = new Dictionary<string, object>
        {
            ["status"] = memoryUsage > 1000 ? "Critical" : memoryUsage > 500 ? "Warning" : "Healthy",
            ["value"] = memoryUsage,
            ["threshold"] = 1000
        };
        
        return health;
    }
    
    private async Task<Dictionary<string, object>> GetPerformanceMetricsAsync()
    {
        var performance = new Dictionary<string, object>();
        
        var profilingReport = await _profilingService.GetPerformanceReportAsync();
        
        foreach (var profile in profilingReport)
        {
            var profileData = profile.Value as Dictionary<string, object>;
            if (profileData != null)
            {
                var avgDuration = Convert.ToDouble(profileData["average_duration_ms"]);
                var threshold = Convert.ToInt64(profileData["threshold_ms"]);
                
                performance[profile.Key] = new Dictionary<string, object>
                {
                    ["average_duration_ms"] = avgDuration,
                    ["threshold_ms"] = threshold,
                    ["status"] = avgDuration > threshold ? "Slow" : "Normal",
                    ["total_operations"] = profileData["total_operations"]
                };
            }
        }
        
        return performance;
    }
    
    private async Task<Dictionary<string, object>> GetApplicationMetricsAsync()
    {
        var metrics = await _metricsService.GetMetricsSnapshotAsync();
        var application = new Dictionary<string, object>();
        
        // Active users
        application["active_users"] = new Dictionary<string, object>
        {
            ["current"] = Convert.ToInt32(metrics["active_users"]),
            ["trend"] = "increasing"
        };
        
        // Cache performance
        var cacheHitRate = Convert.ToDouble(metrics["cache_hit_rate"]);
        application["cache_performance"] = new Dictionary<string, object>
        {
            ["hit_rate"] = cacheHitRate,
            ["status"] = cacheHitRate > 0.8 ? "Good" : cacheHitRate > 0.6 ? "Fair" : "Poor"
        };
        
        return application;
    }
    
    private async Task<List<Dictionary<string, object>>> GetActiveAlertsAsync()
    {
        var alerts = new List<Dictionary<string, object>>();
        var metrics = await _metricsService.GetMetricsSnapshotAsync();
        
        // Check for critical alerts
        var cpuUsage = Convert.ToDouble(metrics["cpu_usage_percent"]);
        if (cpuUsage > 90)
        {
            alerts.Add(new Dictionary<string, object>
            {
                ["level"] = "Critical",
                ["message"] = $"CPU usage is critically high: {cpuUsage:F1}%",
                ["timestamp"] = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")
            });
        }
        
        var memoryUsage = Convert.ToDouble(metrics["memory_usage_mb"]);
        if (memoryUsage > 1500)
        {
            alerts.Add(new Dictionary<string, object>
            {
                ["level"] = "Warning",
                ["message"] = $"Memory usage is high: {memoryUsage:F0}MB",
                ["timestamp"] = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")
            });
        }
        
        return alerts;
    }
}

🛠️ Real-World Monitoring Scenarios

- API performance: Monitor response times and throughput - Database performance: Monitor query performance and connection usage - Memory usage: Monitor memory consumption and garbage collection - Business metrics: Monitor user activity and business KPIs

🧩 Best Practices

- Collect metrics at appropriate intervals - Set meaningful thresholds for alerts - Use correlation IDs for tracing - Monitor both technical and business metrics - Implement automated alerting

🏁 You're Ready!

You can now: - Implement comprehensive metrics collection - Profile application performance - Create monitoring dashboards - Set up automated alerting

Next: Deployment Strategies

---

"We don't bow to any king" - Your monitoring mastery, your performance excellence, your observability power.

Monitor everything. Optimize continuously. 📊