C# 应用程序监控:高级指标与告警
\n\n在现代 C# (.NET) 开发中,仅仅“能运行”的应用程序已不再是足够的质量标准。生产系统需要持续监控:您需要了解服务消耗了多少内存、请求处理速度有多快、消息代理中的队列是否在增长。没有监控和告警系统,您可能只有在用户反馈时才能发现问题。在本文中,我们将深入探讨使用 Prometheus、Grafana 和 OpenTelemetry 等现代工具,为 C# 应用程序收集指标、可视化数据以及配置告警的高级技术。
\n\n为什么需要高级监控?
\n基础监控(CPU、内存、磁盘)无法提供完整视图。对于 C# 应用程序,一些特定指标至关重要:垃圾回收 (GC) 次数、线程阻塞时间、数据库连接池大小。针对这些指标的告警使您能够在故障发生前做出响应。高级方法包含三个层次:
\n- \n
- 基础设施层 — 服务器标准指标。 \n
- 应用层 — 业务逻辑指标(延迟、错误、调用频率)。 \n
- 业务层 — 与领域相关的指标(订单数量、转化率)。 \n
我们将重点关注对 C# 开发者最有效的应用层。
\n\n使用 OpenTelemetry 和 Prometheus 收集指标
\nOpenTelemetry (OTel) 是 .NET 应用程序检测的事实标准。它允许通过统一的 API 收集指标、追踪和日志。我们来看一个与 Prometheus 集成的示例。
\n\n安装 NuGet 包:
\ndotnet add package OpenTelemetry.Extensions.Hosting\ndotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore\ndotnet add package OpenTelemetry.Instrumentation.AspNetCore\n\n在 Program.cs 中进行配置:
using OpenTelemetry.Metrics;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddOpenTelemetry()\n .WithMetrics(metrics => metrics\n .AddAspNetCoreInstrumentation()\n .AddRuntimeInstrumentation()\n .AddPrometheusExporter());\n\nvar app = builder.Build();\n\napp.MapPrometheusScrapingEndpoint(); // Prometheus 端点\n\napp.Run();\n\n现在,您的服务将在 /metrics 路径以 Prometheus 格式提供指标。其中包括 HTTP 请求数量、处理时间、GC 和内存指标。
自定义指标
\n对于业务指标,请使用 Meter 和 Counter:
using System.Diagnostics.Metrics;\n\npublic class OrderMetrics\n{\n private readonly Counter<int> _ordersCreated;\n\n public OrderMetrics(IMeterFactory meterFactory)\n {\n var meter = meterFactory.Create("MyApp.Orders");\n _ordersCreated = meter.CreateCounter<int>("orders.created.count");\n }\n\n public void OrderCreated() => _ordersCreated.Add(1);\n}\n\n// 在 DI 中注册:\nbuilder.Services.AddSingleton<OrderMetrics>();\n\n这些指标将自动进入 Prometheus,并可用于在 Grafana 中构建仪表板。
\n\n配置告警:从简单规则到多层次系统
\n没有告警,指标本身毫无用处。在 Prometheus 中,告警通过 Alertmanager 进行配置。我们来看一个高级场景:针对 API 响应时间异常的告警。
Prometheus 规则 (alert.rules.yml)
\ngroups:\n - name: csharp_app_alerts\n rules:\n - alert: HighRequestLatency\n expr: |\n histogram_quantile(0.95, \n rate(http_server_duration_seconds_bucket[5m])\n ) > 2\n for: 2m\n labels:\n severity: critical\n annotations:\n summary: "请求延迟过高 ({{ $value }}s)"\n descr