Comonitor - COM+ 监视器






4.50/5 (7投票s)
2005年12月7日
2分钟阅读

55170

1376
一个 COM+ 监控应用程序。
引言
本文为系统管理员提供了一个以托管方式监控 COM+ 应用程序(远程和本地)的工具。
背景
作为一名系统管理员,我每天都会使用 COM+ MMC 来查找死锁或未释放的组件。 在网上搜索了很长时间后,我找到了一小段 C# 代码,帮助我构建了这个监控应用程序。(这段代码来自 Egil Hogholt 的博客,Mark 以评论的形式添加了 C# 版本。)
Comonitor 架构
该应用程序的核心是 "COMSVCSLib.TrackerServer
" 对象,它仅返回本地服务器的信息。 为了克服这个问题,我决定将核心代码(使用 TrackerServer
对象)封装在一个 WebService 中,该 WebService 将安装在我的每个服务器上。 我的客户端应用程序使用 SOAP 调用远程服务器上的 WebService(远程服务器名称作为运行时参数提供)。
理解 ComonitorService
ComonitorService 只有一个 WebMethod ("GetErrors
"),它从客户端获取两个 uint
参数
- "
ResponseTimeLimit
" -uint
,表示客户端认为死锁的响应时间(毫秒)。 - "
ObjectsLimit
" -uint
,表示客户端认为错误的未释放组件数量。
[WebMethod]
[XmlInclude(typeof(Comonitor.OverLimitObject))]
public ArrayList GetErrors(uint ResponseTimeLimit,
uint ObjectsLimit)
"GetErrors
" 返回一个包含所有有问题组件的 ComonitorService.OverLimitObject
的 ArrayList
。
public class OverLimitObject
{
public string PackageName;
public string ComponentName;
public uint PID;
public uint ResponseTime;
public uint Objects;
}
"OverLimitObject
" 包含从 "COMSVCSLib.TrackerServer
" 对象接收到的所有必要信息。
使用 "COMSVCSLib.TrackerServer"
以下代码是 Comonitor 应用程序的核心。 它使用 "COMSVCSLib.TrackerServer
" 对象查询 COM 目录以获取(仅)正在运行的组件。 对于与给定限制参数对应的每个组件,我们创建一个 "ComonitorService.OverLimitObject
",其中包含来自组件统计信息的相关数据。
ArrayList retVal = new ArrayList();
IntPtr clsIDDataPtr = IntPtr.Zero;
IntPtr appDataPtr = IntPtr.Zero;
COMSVCSLib.IGetAppData getAppData = null;
// Get an instance of the internal com+ tracker objet
COMSVCSLib.TrackerServer comPlusTrackerType;
comPlusTrackerType = new COMSVCSLib.TrackerServerClass();
getAppData = (COMSVCSLib.IGetAppData)comPlusTrackerType;
// Get a list of running application
uint appCount;
unsafe
{
getAppData.GetApps(out appCount, new IntPtr(&appDataPtr));
}
// Step through the list of running application
int appDataSize = Marshal.SizeOf(typeof(COMSVCSLib.appData));
for(int appIndex=0; appIndex<appCount; appIndex++)
{
COMSVCSLib.appData appData =
(COMSVCSLib.appData)Marshal.PtrToStructure(new
IntPtr(appDataPtr.ToInt32() + (appIndex * appDataSize)),
typeof(COMSVCSLib.appData));
// Get information about running application
uint nClsIDCount;
appDataPtr = new IntPtr();
unsafe
{
getAppData.GetAppData(appData.m_idApp, out nClsIDCount,
new IntPtr(&clsIDDataPtr));
}
// Step through the information
int clsIDDataSize = Marshal.SizeOf(typeof(COMSVCSLib.CLSIDDATA));
for(int clsIDIndex=0; clsIDIndex<nClsIDCount; clsIDIndex++)
{
COMSVCSLib.CLSIDDATA clsIDData =
(COMSVCSLib.CLSIDDATA)Marshal.PtrToStructure(new
IntPtr(clsIDDataPtr.ToInt32() + (clsIDIndex * clsIDDataSize)),
typeof(COMSVCSLib.CLSIDDATA));
// Checks if any parameter is over the limit
// (which was provided by the user)
if ((clsIDData.m_cBound >= ObjectsLimit) ||
(clsIDData.m_dwRespTime >= ResponseTimeLimit))
{
//Creates Over Limit Objects and adds it to retVal
OverLimitObject objOL = new
OverLimitObject(GetPackageNameByPID(appData.m_dwAppProcessId),
GetComponentNameByCLSID(clsIDData.m_clsid.ToString()),
appData.m_dwAppProcessId, clsIDData.m_dwRespTime,
clsIDData.m_cBound);
retVal.Add(objOL);
}
}
}
return retVal;
客户端
在本文中,我还包含了一个 Windows 客户端应用程序,它使用 "ComonitorService
"。 示例客户端应用程序每隔给定的时间段(可选)调用指定计算机上的 WebService,并为系统管理员提供关闭指定服务器上存在问题的包的能力。 如果有您不想检查的 COM+ 包,例如:系统应用程序、IIS 实用程序等,您可以将包名称添加到客户端的 App.config 文件中的 "NonErrorPackages
" 键中。
<add key="NonErrorPackages" value="System Application,IIS Utilities" />