告警系统.NET Core:异常通知
在.NET Core应用开发中,异常处理和实时告警是保障系统稳定性的关键环节。当生产环境中出现未捕获异常或性能问题时,及时的告警通知能帮助开发团队快速响应并解决问题,减少业务损失。本文将介绍如何基于.NET Core构建轻量级异常告警系统,涵盖异常捕获、通知渠道集成和最佳实践。
异常捕获机制
全局异常处理中间件
ASP.NET Core提供了全局异常处理中间件,可统一捕获Web请求过程中抛出的异常。通过自定义中间件,可实现异常日志记录和告警触发。
public class ExceptionAlertMiddleware
{
private readonly RequestDelegate _next;
private readonly IAlertService _alertService;
public ExceptionAlertMiddleware(RequestDelegate next, IAlertService alertService)
{
_next = next;
_alertService = alertService;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
// 记录异常详情
var exceptionDetails = new ExceptionDetails
{
Message = ex.Message,
StackTrace = ex.StackTrace,
Path = context.Request.Path,
Timestamp = DateTime.UtcNow
};
// 触发告警
await _alertService.SendAlertAsync(exceptionDetails);
throw; // 继续抛出异常以返回500响应
}
}
}
// 在Program.cs中注册
app.UseMiddleware<ExceptionAlertMiddleware>();
非Web应用异常捕获
对于控制台应用或Windows服务,可通过AppDomain.CurrentDomain.UnhandledException事件捕获未处理异常:
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
var exception = args.ExceptionObject as Exception;
if (exception != null)
{
// 处理异常并发送告警
_alertService.SendAlertAsync(new ExceptionDetails
{
Message = exception.Message,
StackTrace = exception.StackTrace,
Timestamp = DateTime.UtcNow
}).Wait();
}
};
告警通知渠道
邮件通知
通过SmtpClient或第三方邮件服务(如SendGrid)发送异常详情邮件:
public class EmailAlertService : IAlertService
{
private readonly string _smtpServer;
private readonly int _smtpPort;
private readonly string _username;
private readonly string _password;
public async Task SendAlertAsync(ExceptionDetails details)
{
using (var client = new SmtpClient(_smtpServer, _smtpPort))
{
client.Credentials = new NetworkCredential(_username, _password);
client.EnableSsl = true;
var message = new MailMessage(
from: "alerts@example.com",
to: "dev-team@example.com",
subject: $"[ERROR] {details.Message}",
body: $"<h3>Exception Details</h3><p>Path: {details.Path}</p><p>Time: {details.Timestamp}</p><pre>{details.StackTrace}</pre>"
);
message.IsBodyHtml = true;
await client.SendMailAsync(message);
}
}
}
企业微信/钉钉机器人
集成企业微信或钉钉机器人Webhook,实现即时消息告警:
public class WeChatAlertService : IAlertService
{
private readonly HttpClient _httpClient;
private readonly string _webhookUrl;
public async Task SendAlertAsync(ExceptionDetails details)
{
var payload = new
{
msgtype = "markdown",
markdown = new
{
content = $"## 系统异常告警\n" +
$"**时间**: {details.Timestamp}\n" +
$"**消息**: {details.Message}\n" +
$"**路径**: {details.Path}\n" +
$"**堆栈**: \n```\n{details.StackTrace}\n```"
}
};
await _httpClient.PostAsJsonAsync(_webhookUrl, payload);
}
}
告警系统最佳实践
异常聚合与限流
频繁重复的异常可能导致告警风暴,可通过滑动窗口算法实现告警限流:
public class ThrottlingAlertService : IAlertService
{
private readonly IAlertService _innerService;
private readonly ConcurrentDictionary<string, Queue<DateTime>> _alertTimestamps = new();
public async Task SendAlertAsync(ExceptionDetails details)
{
var key = $"{details.Message}:{details.Path}";
var now = DateTime.UtcNow;
var window = TimeSpan.FromMinutes(5);
var maxCount = 3;
// 清理过期记录
_alertTimestamps.TryGetValue(key, out var timestamps);
timestamps?.RemoveAll(t => now - t > window);
// 检查是否超过阈值
if (timestamps?.Count < maxCount)
{
timestamps ??= new Queue<DateTime>();
timestamps.Enqueue(now);
_alertTimestamps[key] = timestamps;
await _innerService.SendAlertAsync(details);
}
}
}
结合日志系统
将告警系统与日志框架(如Serilog、NLog)集成,通过日志级别触发告警:
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.File("logs/app.log")
.WriteTo.Sink(new AlertSink(alertService)) // 自定义告警Sink
.CreateLogger();
// 自定义日志Sink
public class AlertSink : ILogEventSink
{
private readonly IAlertService _alertService;
public void Emit(LogEvent logEvent)
{
if (logEvent.Level >= LogEventLevel.Error)
{
_alertService.SendAlertAsync(new ExceptionDetails
{
Message = logEvent.MessageTemplate.Render(logEvent.Properties),
StackTrace = logEvent.Exception?.StackTrace,
Timestamp = logEvent.Timestamp.UtcDateTime
}).Wait();
}
}
}
参考资源
- .NET官方异常处理文档:Exception handling in .NET
- ASP.NET Core中间件开发:ASP.NET Core middleware
- .NET 8已知异常及解决方案:release-notes/8.0/known-issues.md
通过以上方案,可构建一个灵活可靠的异常告警系统,帮助开发团队及时发现并解决.NET Core应用中的问题。实际部署时,建议根据业务需求选择合适的通知渠道,并结合监控系统(如Prometheus、Grafana)实现更全面的系统观测。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



