如果一个服务被部署到了几十台机器上,我们往往需要每天花费很多的时间去查看每台机器上的服务的运行状 况,虽然微软有MOM(Microsoft Operations Manager)和SMS(Systems Management Server),但处于成本上及其它方面的考虑,好多时候我们还用不上这些东西,其实微软公开了好多管理和监控方面的API和工具,比如WMIC, System.Managerment等,把这些零散的API和工具集中起来,便可以开发一些满足自定义需求的小软件。
我们要实现以下任务
1、确认指定的进程已启动
2、获取指定机器,指定进程的CPU、内存、线程使用情况
3、确认指定机器的指定端口在监听
4、获取指定机器指定计数器的情况
5、获取指定机器上的系统日志/应用日志
6、获取指定服务相关trace
7、确认指定服务的功能拨测能通过
8、抓取指定机器指定进程的dump
9、在指定机器上进行网络抓包
10、重启指定机器上的某服务,某应用程序进程池等
下面来一一考虑一下
1、确认指定的进程已启动
可以用WMI接口来获取远程机器的进程列表,然后遍历这个列表,确认指定服务的进程名字是否在这个列表里,核心代码(来自网络)如下:
{
// The second way of constructing a query
string queryString =
"Select Name, ProcessId, Caption, ExecutablePath" +
" FROM Win32_Process";
SelectQuery query = new SelectQuery(queryString);
ConnectionOptions options = new ConnectionOptions();
options.Username = @"administrator";
options.Password = "";
ManagementScope scope = new System.Management.ManagementScope(@"//./root/CIMV2");
scope.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection processes = searcher.Get();
DataTable result = new DataTable();
result.Columns.Add("Name", Type.GetType("System.String"));
result.Columns.Add("ProcessId", Type.GetType("System.Int32"));
result.Columns.Add("Caption", Type.GetType("System.String"));
result.Columns.Add("Path", Type.GetType("System.String"));
foreach (ManagementObject mo in processes)
{
DataRow row = result.NewRow();
row["Name"] = mo["Name"].ToString();
row["ProcessId"] = Convert.ToInt32(mo["ProcessId"]);
if (mo["Caption"] != null)
row["Caption"] = mo["Caption"].ToString();
if (mo["ExecutablePath"] != null)
row["Path"] = mo["ExecutablePath"].ToString();
result.Rows.Add(row);
}
return result;
}
2、获取指定机器,指定进程的CPU、内存、线程使用情况
这几样数据,我们用计数器来获取,具体表格如下
某进程的CPU使用量:process类别下的% Processor Time,实例名是你服务的进程名字(不加后缀名)
某进程的内存使用量:process类别下的Private Bytes,实例名是你服务的进程名字(不加后缀名)
某进程的内存使用量:process类别下的Thread Count,实例名是你服务的进程名字(不加后缀名)
其它的计数器的说明请打开perfmon工具一个一个看每个计数器的说明文字
关于获取某机器某计数器数值的代码大约如下
{
public PerfCounter(string categoryName,
string counterName,
string instanceName,
string machineName
)
{
this.categoryName = categoryName;
this.counterName = counterName;
this.instanceName = instanceName;
this.machineName = machineName;
}
public string categoryName;