using AutoNotificatPhone.Controllers; using Common; using System.Threading; using NLog; using System.Diagnostics; namespace AutoNotificatPhone.Models { public class TimerClass : BackgroundService { // 日志记录器 public static Logger logger = LogManager.GetCurrentClassLogger(); // 通知接收手机号码 private static readonly string Mobile1 = "13509214696"; private static readonly string Mobile2 = "16620970520"; // 记录已执行任务的时间点 private Dictionary _executedTasks = []; // 消息控制器实例 private readonly CallAndMsgController _callAndMsgController = new(); /// /// 后台服务主执行方法 /// protected override async Task ExecuteAsync(CancellationToken cancellationToken) { await Task.Factory.StartNew(async () => { while (!cancellationToken.IsCancellationRequested) { try { // 计算下次执行时间(每分钟的30秒) var now = DateTime.UtcNow; var nextRunTime = CalculateNextRunTime(now); var delayTime = nextRunTime - now; // 等待到下一个执行点 await Task.Delay(delayTime, cancellationToken); // 检查电话机状态并记录日志 LogPhoneStatus(CheckPhoneIsOnline()); // 执行定时任务 await RegularlySendActiverecords(); // 执行系统检查任务 await CheckCpuThresholdAsync(); await CheckRcuOnlineAsync(); await CheckTotalSendPackageAsync(); await CheckTotalRecvPackageAsync(); } catch (TaskCanceledException) { // 任务被取消时的处理 logger.Error("任务被取消"); break; } catch (Exception ex) { // 异常处理 logger.Error($"主循环发生错误: {ex.Message}"); await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken); } } }, TaskCreationOptions.LongRunning); } /// /// 计算下次执行时间(每分钟的30秒) /// private DateTime CalculateNextRunTime(DateTime now) { var nextRunTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 30); return now.Second >= 30 ? nextRunTime.AddMinutes(1) : nextRunTime; } /// /// 记录电话机状态日志 /// private void LogPhoneStatus(bool isOnline) { logger.Error(isOnline ? "电话机在线,开始判断!+++++str+++++" : "电话机不在线,下面内容可能不会执行!+++++err+++++"); } /// /// 检查电话机进程是否在线 /// private bool CheckPhoneIsOnline() { try { // 通过进程名检查电话机是否运行 return Process.GetProcessesByName("Telephone").Length > 0; } catch (Exception ex) { logger.Error($"电话机进程检查失败: {ex.Message}"); return false; } } /// /// 定时发送活动记录(整点任务) /// private async Task RegularlySendActiverecords() { // 转换为北京时间 var beijingTime = DateTime.UtcNow.AddHours(8); //logger.Error($"每日任务检查 - 当前北京时间: {beijingTime:yyyy-MM-dd HH:mm:ss}"); // 检查是否整点 if (beijingTime.Minute != 0) { //logger.Error($"不满足整点任务触发条件 - 当前时间: {beijingTime:HH:mm}"); return; } // 创建整点时间键 var hourlyKey = new DateTime(beijingTime.Year, beijingTime.Month, beijingTime.Day, beijingTime.Hour, 0, 0); // 检查任务是否已执行 if (_executedTasks.ContainsKey(hourlyKey)) { //logger.Error($"跳过已执行的整点任务 - 时间点: {hourlyKey:yyyy-MM-dd HH:mm}"); return; } logger.Error($"准备执行整点短信任务 - 时间点: {hourlyKey:yyyy-MM-dd HH:mm}"); // 判断执行每日任务还是整点短信 if (beijingTime.Hour is 10 or 15 or 22) { await ExecuteDailyTask(beijingTime); } else { await SendHourlySms(beijingTime); } // 标记任务已执行 _executedTasks[hourlyKey] = true; // 清理过期任务记录 CleanupOldTasks(beijingTime); //logger.Error($"整点任务执行完成 - 时间点: {hourlyKey:yyyy-MM-dd HH:mm}"); } /// /// 清理过期任务记录 /// private void CleanupOldTasks(DateTime currentTime) { // 找出所有过期的任务键 var keysToRemove = _executedTasks.Keys.Where(k => k.Date < currentTime.Date).ToList(); foreach (var key in keysToRemove) { _executedTasks.Remove(key); //logger.Error($"清理过期任务记录: {key:yyyy-MM-dd HH:mm}"); } } /// /// 发送整点短信 /// private async Task SendHourlySms(DateTime beijingTime) { try { // 准备短信内容 long currentTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); string dateTimeStr = $"{beijingTime.Month}月{beijingTime.Day}日{beijingTime.Hour}点"; string smsContent = $"[BLV运维提示] 整点系统状态报告。当前时间:{dateTimeStr}"; // 创建短信请求 var request = CreateSmsRequest( type: "2", deadline: currentTimestamp + 1800, phone: Mobile1, caller: "整点报告", content: smsContent ); // 发送短信并记录结果 var result = _callAndMsgController.SendToPhone(request); /*logger.Error(result.isok ? $"整点短信已发送:{dateTimeStr}" : $"发送整点短信失败:{result.message}");*/ } catch (Exception ex) { logger.Error($"发送整点短信时出错:{ex.Message}"); } await Task.CompletedTask; } /// /// 执行每日定时任务(10点、15点、22点) /// private async Task ExecuteDailyTask(DateTime beijingTime) { try { // 准备消息内容 long currentTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); string dateTimeStr = $"{beijingTime.Month}月{beijingTime.Day}日{beijingTime.Hour}点"; string smsContent = $"[BLV运维提示] 每日定时通知。当前时间为:{dateTimeStr}"; string callContent = $"BLV运维提示 每日定时通知 当前时间为 {dateTimeStr}"; // 创建短信和电话请求 var smsRequest1 = CreateSmsRequest("2", currentTimestamp + 1800, Mobile1, "每日定时通知", smsContent); var smsRequest2 = CreateSmsRequest("2", currentTimestamp + 1800, Mobile2, "每日定时通知", smsContent); var callRequest = CreateSmsRequest("1", currentTimestamp + 900, Mobile1, "每日定时通知", callContent); // 发送通知 var smsResult1 = _callAndMsgController.SendToPhone(smsRequest1); var smsResult2 = _callAndMsgController.SendToPhone(smsRequest2); var callResult = _callAndMsgController.SendToPhone(callRequest); // 记录发送结果 if (smsResult1.isok && smsResult2.isok && callResult.isok) { //logger.Error($"每日定时通知已发送:{dateTimeStr}"); } else { logger.Error($"发送每日定时通知失败:短信1={smsResult1.message} 短信2={smsResult2.message} 电话={callResult.message}"); } } catch (Exception ex) { logger.Error($"执行每日任务时出错:{ex.Message}"); } await Task.CompletedTask; } /// /// 检查CPU使用率阈值 /// private async Task CheckCpuThresholdAsync() { try { // 检查监控程序是否在线 string detectTimeString = CSRedisCacheHelper.redis1.Get("UDPPackage_DetectTime"); if (!string.IsNullOrEmpty(detectTimeString) && DateTime.TryParse(detectTimeString, out DateTime detectTime) && (DateTime.UtcNow - detectTime).TotalMinutes > 10) { // 监控程序无法访问警报 ExecuteMonitorUnavailableAlert(detectTime); return; } // 获取CPU使用率数据 string cpuMax = CSRedisCacheHelper.redis1.Get("UDPPackage_CPUMax"); string cpuAvg = CSRedisCacheHelper.redis1.Get("UDPPackage_CPUAvg"); List cpuMaxValues = ParseCpuValues(cpuMax); List cpuAvgValues = ParseCpuValues(cpuAvg); // 记录CPU使用率 //logger.Error($"RCU服务器的CPU使用率-AVG:{cpuAvg},MAX:{cpuMax}"); // 检查是否超过阈值 if (CheckThreshold(cpuAvgValues, 70, 6))//(CheckThreshold(cpuMaxValues, 90, 6) || CheckThreshold(cpuAvgValues, 85, 6)) { // 触发CPU警报 ExecuteCpuAlert(cpuMaxValues, ParseCpuValues(CSRedisCacheHelper.redis1.Get("UDPPackage_CPUMin")), cpuAvgValues); } } catch (Exception ex) { logger.Error($"CPU阈值检查错误: {ex.Message}"); } await Task.CompletedTask; } /// /// 检查RCU在线数量 /// private async Task CheckRcuOnlineAsync() { await CheckRedisValueAsync("RCUOnLine", 8, 0.8, ExecuteRcuOnlineAlert, "RCU主机的在线数量"); } /// /// 检查总发送包数量 /// private async Task CheckTotalSendPackageAsync() { await CheckRedisValueAsync("UDPPackage_TotalSendPackage", 8, 0.6, ExecuteTotalSendPackageAlert, "RCU主机的通讯数量"); } /// /// 检查总接收包数量 /// private async Task CheckTotalRecvPackageAsync() { try { // 从Redis获取值 string valueString = CSRedisCacheHelper.redis1.Get("UDPPackage_TotalRecvPackage"); if (string.IsNullOrEmpty(valueString)) return; // 解析值 List values = ParseCpuValues(valueString); if (values == null || values.Count < 10) return; // 检查最后3个值是否都小于70000 if (values.Count >= 3 && values[^3] < 70000 && values[^2] < 70000 && values[^1] < 70000) { // 触发警报 ExecuteTotalRecvPackageAlert([values[^3], values[^2], values[^1]]); } else { // 原有的阈值检查逻辑 await CheckRedisValueAsync("UDPPackage_TotalRecvPackage", 8, 0.75, ExecuteTotalRecvPackageAlert, "RCU主机的通讯数量"); } } catch (Exception ex) { logger.Error($"总接收包数量检查错误: {ex.Message}"); } await Task.CompletedTask; } /// /// 通用Redis值检查方法 /// private async Task CheckRedisValueAsync(string redisKey, int baselineCount, double thresholdRatio, Action> alertAction, string logPrefix) { try { // 从Redis获取值 string valueString = CSRedisCacheHelper.redis1.Get(redisKey); if (string.IsNullOrEmpty(valueString)) return; // 解析值 List values = ParseCpuValues(valueString); if (values == null || values.Count < 10) return; // 计算平均值和阈值 double average = values.Take(baselineCount).Average(); double threshold = average * thresholdRatio; //logger.Error($"{logPrefix}-AVG:{average},ALL:{valueString}"); // 检查最后两个值是否低于阈值 if (values[baselineCount] < threshold && values[baselineCount + 1] < threshold) { // 触发警报 alertAction(values); } } catch (Exception ex) { logger.Error($"{logPrefix}检查错误: {ex.Message}"); } await Task.CompletedTask; } /// /// 执行RCU在线数量警报 /// private void ExecuteRcuOnlineAlert(List values) { SendAlert( smsContent: $"[BLV运维提示] RCU主机在线数量低于正常值,请立即检查。数据:{string.Join(",", values)}", callContent: "BLV运维提示 RCU主机在线数量低于正常值 请立即检查", alertType: "RCU-在线数量警报" ); } /// /// 执行总发送包数量警报 /// private void ExecuteTotalSendPackageAlert(List values) { SendAlert( smsContent: $"[BLV运维提示] RCU发送数量低于预期值,请立即检查。数据:{string.Join(",", values)}", callContent: "BLV运维提示 RCU发送数量低于预期值 请立即检查", alertType: "RCU-通讯数量警报" ); } /// /// 执行总接收包数量警报 /// private void ExecuteTotalRecvPackageAlert(List values) { SendAlert( smsContent: $"[BLV运维提示] RCU接收数量低于预期值,请立即检查。数据:{string.Join(",", values)}", callContent: "BLV运维提示 RCU接收数量低于预期值 请立即检查", alertType: "RCU-通讯数量警报" ); } /// /// 执行CPU使用率警报 /// private void ExecuteCpuAlert(List cpuMax, List cpuMin, List cpuAvg) { string dataString = $"AVG:{string.Join(",", cpuAvg)},MAX:{string.Join(",", cpuMax)},MIN:{string.Join(",", cpuMin)}"; SendAlert( smsContent: $"[BLV运维提示] RCU服务器的CPU使用率告警。{dataString}", callContent: "BLV运维提示 RCU服务器的CPU使用率告警 请立即检查", alertType: "RCU-CPU警报" ); } /// /// 执行监控程序无法访问警报 /// private void ExecuteMonitorUnavailableAlert(DateTime detectTime) { SendAlert( smsContent: "[BLV运维提示] RCU服务器的监控程序无法访问,请立即检查。", callContent: "BLV运维提示 RCU服务器的监控程序无法访问 请立即检查", alertType: "RCU-监控程序警报", extendedDeadline: true ); } /// /// 解析CPU值字符串为整数列表 /// private List ParseCpuValues(string valueString) { return string.IsNullOrEmpty(valueString) ? new List() : valueString.Split(',').Select(v => int.TryParse(v, out int result) ? result : 0).ToList(); } /// /// 检查值列表是否超过阈值 /// private bool CheckThreshold(List values, int threshold, int requiredCount) { return values != null && values.Count >= requiredCount && values.Count(v => v >= threshold) >= requiredCount; } /// /// 通用警报发送方法 /// private void SendAlert(string smsContent, string callContent, string alertType, bool extendedDeadline = false) { // 设置过期时间 long currentTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); long smsDeadline = extendedDeadline ? currentTimestamp + 3600 : currentTimestamp + 1800; long callDeadline = extendedDeadline ? currentTimestamp + 1800 : currentTimestamp + 900; // 创建请求 var smsRequest = CreateSmsRequest("2", smsDeadline, Mobile1, alertType, smsContent); var smsRequest2 = CreateSmsRequest("2", smsDeadline, Mobile2, alertType, smsContent); var callRequest = CreateSmsRequest("1", callDeadline, Mobile1, alertType, callContent); // 发送警报 var smsResult = _callAndMsgController.SendToPhone(smsRequest); var smsResult2 = _callAndMsgController.SendToPhone(smsRequest2); var callResult = _callAndMsgController.SendToPhone(callRequest); // 记录结果 if (smsResult.isok && callResult.isok) { //logger.Error($"{alertType}警告已发送"); } else { logger.Error($"发送{alertType}通知失败: 短信={smsResult.message} 电话={callResult.message}"); } } /// /// 创建短信/电话请求对象 /// private SmsRequest CreateSmsRequest(string type, long deadline, string phone, string caller, string content) { return new SmsRequest { Type = type, DeadLine = deadline, StartingPoint = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), PhoneNumber = phone, CallerName = caller, Content = content }; } } }