You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

307 lines
9.8 KiB

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using Sog;
using Google.Protobuf.WellKnownTypes;
using FileTransDataObject;
namespace SMCenter
{
public class CheckAgentCmdProc : BaseCmdProc
{
private long LastCheckTimeoutSecond;
public override void ClearData()
{
m_nowCmd = null;
}
public override int DoCmd(out string msg)
{
if (m_nowCmd.CmdParams.Count < 1 || string.IsNullOrEmpty(m_nowCmd.CmdParams[0]))
{
msg = "invalid cmd param";
return -1;
}
if (CmdUtils.CheckValidServerId(m_nowCmd.CmdParams[0], out string fixSvrId) == false)
{
msg = "invalid server id";
return -1;
}
if (fixSvrId != null)
{
m_nowCmd.CmdParams[0] = fixSvrId;
}
SMProcAppMgr.Instance.GetAllMatchingProc(m_nowCmd.CmdParams[0], m_nowCmd.m_procs);
m_nowCmd.m_procs = m_nowCmd.m_procs.OrderBy(o => o.Value.SMApp.HostName).ToDictionary(p => p.Key, o => o.Value);
msg = "";
int ret = 0;
var fileList = new List<FileData>();
switch (m_nowCmd.CMD)
{
case "checkagent":
ret = GetAgentFile(fileList, out msg);
break;
case "checkpushfile":
ret = GetPushFile(fileList, out msg);
break;
}
if (ret != 0)
{
return -1;
}
// 上面算完文件列表后再对procs去重, 否则会少算文件
CmdProcInfoDistinct();
SendCmdToHost(fileList);
return 0;
}
// 检测agent运行目录下的dll和pdb
private int GetAgentFile(List<FileData> fileList, out string msg)
{
// center和agent的部署层级是一样的, center的运行目录就是agent的运行目录
string dllPath = Path.Combine(SMCenterUtils.Config.centerPush, "SMAgent.dll");
var dll = FileUtils.CreateFileData(dllPath, false);
if (dll == null)
{
msg = string.Format("{0} not exist", dllPath);
return -1;
}
string pdbPath = Path.Combine(SMCenterUtils.Config.centerPush, "SMAgent.pdb");
var pdb = FileUtils.CreateFileData(pdbPath, false);
if (pdb == null)
{
msg = string.Format("{0} not exist", pdbPath);
return -1;
}
dll.writeFilePath = Path.GetFullPath("../bin");
fileList.Add(dll);
pdb.writeFilePath = Path.GetFullPath("../bin");
fileList.Add(pdb);
msg = "";
return 0;
}
//主要检测服务器运行需要的 cfg文件和bin 文件
private int GetPushFile(List<FileData> fileList, out string msg)
{
int ret = CmdUtils.GetPushBinFile(m_nowCmd, fileList, false);
if (ret == -1)
{
msg = "GetPushBinFile fail";
return -1;
}
ret = CmdUtils.GetPushCfgFile(m_nowCmd, fileList, false);
if (ret == -1)
{
msg = "GetPushCfgFile fail";
return -1;
}
msg = "";
return 0;
}
public override int UpdateCmd(long tMs)
{
if (m_nowCmd.m_procs.Count == 0)
{
return 0;
}
if (IsAllProcCmdAcked())
{
return 0;
}
CheckProcTimeout(tMs);
return 1;
}
private void SendCmdToHost(List<FileData> fileList)
{
var req = new SMAgentDoCommandReq();
req.Command = m_nowCmd.CMD;
req.SeqNum = m_nowCmd.SeqNum;
foreach (FileData file in fileList)
{
var attr = new FileAttr
{
FileMd5 = file.fileMd5,
FileName = file.fileName,
FileSize = file.FileSize,
FilePath = file.writeFilePath,
FileTime = file.fileWriteTime.ToFileTimeUtc()
};
req.FileList.Add(attr);
}
foreach (var cmdInfo in m_nowCmd.m_procs.Values)
{
if (cmdInfo.SendCmdToHostTime == 0)
{
req.ServerId = cmdInfo.SMApp.AppId;
cmdInfo.SendCmdToHostTime = SMCenterUtils.GetTimeSecond();
ClientInfo client = SMCenterNet.Instance.GetClientInfoByName(cmdInfo.SMApp.HostName);
if (client != null)
{
client.SendMsg(req, SMMsgID.AgentDoCommandReq);
}
}
}
}
public override void OnAgentDoCommandRes(ClientInfo client, SMAgentDoCommandRes res)
{
if (m_nowCmd.SeqNum != res.SeqNum)
{
TraceLog.Error("CheckAgentCmdProc.OnAgentDoCommandRes CMD {0} svrId {1} seq not same, local {2} res {3}"
, res.Command, res.ServerId, m_nowCmd.SeqNum, res.SeqNum);
return;
}
if (m_nowCmd.m_procs.ContainsKey(res.ServerId) == false)
{
TraceLog.Error("CheckAgentCmdProc.OnAgentDoCommandRes CMD {0} serverId {1} not in m_procs, skip"
, res.Command, res.ServerId);
return;
}
CmdProcInfo proc = m_nowCmd.m_procs[res.ServerId];
proc.AckResultCode = res.ResultCode;
proc.AckMessage = res.Result;
proc.AckAddInfo = res.AddInfo;
if (IsAllProcCmdAcked())
{
AckConsoleCmdResult();
}
TraceLog.Trace("CommCmdProc.OnAgentDoCommandRes CMD {0} agent {1}, result {2}"
, res.Command, res.HostName, res.Result);
}
private void CheckProcTimeout(long tMs)
{
long nowSecond = tMs / 1000;
if (nowSecond - LastCheckTimeoutSecond < 2)
{
return;
}
LastCheckTimeoutSecond = nowSecond;
foreach (var cmdInfo in m_nowCmd.m_procs.Values)
{
if (cmdInfo.SendCmdToHostTime > 0 && cmdInfo.AckResultCode == ResResultCode.NoRes)
{
int timeoutSecond = 15;
if (nowSecond - cmdInfo.SendCmdToHostTime > timeoutSecond)
{
TraceLog.Error("CheckAgentCmdProc.CheckProcTimeout cmd {0} serverid {1} timeout"
, m_nowCmd.CMD, cmdInfo.SMApp.ServerIDStr);
cmdInfo.AckResultCode = ResResultCode.TimeOut;
if (IsAllProcCmdAcked())
{
AckConsoleCmdResult();
}
}
}
}
}
private bool IsAllProcCmdAcked()
{
foreach (var proc in m_nowCmd.m_procs)
{
if (proc.Value.AckResultCode == ResResultCode.NoRes)
{
return false;
}
}
return true;
}
private void AckConsoleCmdResult()
{
SMConsoleCommandRes res = new SMConsoleCommandRes();
res.Command = m_nowCmd.ConsoleInput;
res.Message = "";
List<string> hostName = new List<string>();
foreach (var procInfo in m_nowCmd.m_procs)
{
string procResult = "";
if (! hostName.Contains(procInfo.Value.SMApp.HostName))
{
procResult += string.Format("\n--------------- HostName:{0} ---------------", procInfo.Value.SMApp.HostName);
hostName.Add(procInfo.Value.SMApp.HostName);
}
procResult += "\n " + procInfo.Value.SMApp.HostName + "\t";
switch (procInfo.Value.AckResultCode)
{
case ResResultCode.NoRes:
procResult += "NoRes";
break;
case ResResultCode.TimeOut:
procResult += "timeout";
break;
case ResResultCode.Success:
procResult += "success";
break;
case ResResultCode.Fail:
procResult += "Fail";
break;
case ResResultCode.Exception:
procResult += "Exception";
break;
case ResResultCode.Running:
procResult += "Running";
break;
case ResResultCode.NotRunning:
procResult += "Not Running";
break;
default:
break;
}
//不会空的情况下定义为错误信息
if (string.IsNullOrEmpty(procInfo.Value.AckMessage) == false)
{
procResult += "\n" + procInfo.Value.AckMessage;
}
if (string.IsNullOrEmpty(procInfo.Value.AckAddInfo) == false)
{
procResult += "\n" + procInfo.Value.AckAddInfo;
}
res.Message += procResult;
}
SMCenterNet.Instance.SendMsg(m_nowCmd.SessionId, SMMsgID.ConsoleCommandRes, res, m_nowCmd.HttpId);
}
}
}