using System; using System.Collections.Generic; using System.Threading; using System.Diagnostics; using System.Linq; using Sog; using Sog.IO; using Google.Protobuf.WellKnownTypes; namespace SMAgent { public enum ProcType { ProcType_NotRunning = 0, //初始是未启动的,只有从 running 到 notrunning 才需要短信通知 ProcType_Running = 1, } public class CheckServerStat { public uint serverId; public ProcType procType = ProcType.ProcType_NotRunning; } public class SMAgentCheckProcStat : Singleton { private Thread m_workThread; // 当前正在监控的server app private List m_serverProc = new List(); // 需要添加监控的server app private object m_serverProcAsyncLocker = new object(); private List m_serverProcAsyncAdd = new List(); private string m_workPath; private void CheckStart() { if (m_workThread == null) { m_workThread = new Thread(WorkThreadFun); m_workThread.Start(); } } private void UpdateServerProcList() { lock (m_serverProcAsyncLocker) { if (m_serverProcAsyncAdd.Count > 0) { List temp = new List(); foreach (uint serverId in m_serverProcAsyncAdd) { CheckServerStat proc = m_serverProc.FirstOrDefault(p => p.serverId == serverId); if (proc != null) { temp.Add(proc); } else { temp.Add(new CheckServerStat { serverId = serverId }); } } m_serverProcAsyncAdd.Clear(); m_serverProc = temp; } } } private void WorkThreadFun() { while(true) { if (m_serverProcAsyncAdd.Count > 0) { UpdateServerProcList(); } foreach (var proc in m_serverProc) { if (CheckSogLoaderIsRunning(proc.serverId)) { proc.procType = ProcType.ProcType_Running; } else if (proc.procType == ProcType.ProcType_Running) { // todo 进程停止时, 如果不是执行stop命令, 发送告警短信, 要不要自动拉起? proc.procType = ProcType.ProcType_NotRunning; } } Thread.Sleep(1000); } } public void OnClientRegRes(SMClientRegRes regRes) { lock (m_serverProcAsyncLocker) { // 每次注册成功刷新监控列表 m_serverProcAsyncAdd.Clear(); m_serverProcAsyncAdd.AddRange(regRes.ServerId); } m_workPath = regRes.Workpath; //开启工作线程 CheckStart(); } /// /// 检测下服务器的状态 /// /// /// private bool CheckSogLoaderIsRunning(uint serverId) { ShareMemoryCommand shareCommand = null; try { shareCommand = new ShareMemoryCommand(m_workPath, serverId); bool attachSuccess = shareCommand.Attach(); if (attachSuccess == false) { return false; } int procId = shareCommand.ReadProcessId(); if(procId <= 0) { return false; } using (Process proc = Process.GetProcesses().FirstOrDefault(p => p.Id == procId)) { if (proc == null || proc.HasExited || proc.ProcessName != "SogLoader") { return false; } return true; } } catch(Exception ex) { TraceLog.Exception(ex); return false; } finally { shareCommand?.Close(); } } } }