跳至主要內容

插件开发指南


iMonitor核心概念介绍

IMessage

表示一个事件,通过IMessage可以获取该事件的各个基本字段的内容。

interface IMessage
{
	virtual ULONG			GetType				(void) = 0;
	virtual ULONG			GetIndex			(void) = 0;
	virtual ULONG			GetSeqId			(void) = 0;
	virtual ULONG			GetStatus			(void) = 0;
	virtual ULONG			GetCurrentProcessId	(void) = 0;
	virtual ULONG			GetCurrentThreadId	(void) = 0;
	virtual ULONGLONG		GetTime				(void) = 0;

	virtual String			GetTypeName			(void) = 0;
	virtual ULONG			GetFieldCount		(void) = 0;
	virtual DataType		GetFieldType		(ULONG Index) = 0;
	virtual String			GetFieldName		(ULONG Index) = 0;
	virtual ULONG			GetFieldIndex		(ConstString Name) = 0;

	virtual ULONG			GetULONG			(ULONG Index) = 0;
	virtual ULONGLONG		GetULONGLONG		(ULONG Index) = 0;
	virtual String			GetString			(ULONG Index) = 0;
	virtual Binary			GetBinary			(ULONG Index) = 0;

	virtual IMessageProcess* GetProcess			(void) = 0;
	virtual IMessageCallstack* GetCallstack		(void) = 0;

	inline ULONG			GetGroupType		(void)							{ return MSG_GET_GROUP(GetType()); }
	inline String			GetPath				(void)							{ return GetString(emMSGFieldPath); }
};

IMessageColumn

表示事件的一个可以显示的列,通过注册一个新的列,可以自定义需要显示的内容。

interface IMessageColumn
{
	virtual String			GetName				(void) = 0;
	virtual String			GetDescription		(void) = 0;
	virtual ULONG			GetWidth			(void)							{ return 100; }
	virtual ULONG			GetAlign			(void)							{ return emAlignDefault; }
	virtual ULONG			GetMessageType		(void)							{ return 0; }

	virtual DataType		GetDataType			(IMessage* Message) = 0;
	virtual ULONG			GetULONG			(IMessage* Message) = 0;
	virtual ULONGLONG		GetULONGLONG		(IMessage* Message) = 0;
	virtual String			GetString			(IMessage* Message) = 0;
	virtual Binary			GetBinary			(IMessage* Message) = 0;

	virtual	Color			GetBackgroundColor	(IMessage* Message)				{ return IMONITOR_DEFAULT_COLOR; }
	virtual Color			GetTextColor		(IMessage* Message)				{ return IMONITOR_DEFAULT_COLOR; }
	virtual String			GetToolTips			(IMessage* Message)				{ return String(); }
	virtual Icon			GetIcon				(IMessage* Message)				{ return Icon(); }
};

IMessageMatcher

自定义的匹配器,在简单的规则无法满足过滤需求的时候,可以通过注册自定义的匹配器来实现复杂条件的过滤。

interface IMessageMatcher
{
	virtual String			GetName				(void) = 0;
	virtual String			GetDescription		(void) = 0;

	virtual bool			IsMatch				(IMessage* Message) = 0;
};

iMonitor插件开发

iMonitor提供简单的方式方便使用者可以自己开发插件来扩展能力,从而可以满足不同的使用需要。

其中核心的能力是添加新的显示列、添加自定义的匹配规则。同时也支持添加右键菜单、其他界面交互等(需要引入Qt的依赖)。

对于高级开发者,还支持推送其他监控到的消息,然后通过iMonitor来显示。

插件接口说明

开发者只要实现IPlugin接口,就可以完成插件开发。

struct PluginContext
{
	IMessageColumnManager*	ColumnManager		= nullptr;
	IMessageFilterManager*	FilterManager		= nullptr;
	IMessageProcessManager*	ProcessManager		= nullptr;
	IMessageSymbolManager*	SymbolManager		= nullptr;
	IConfigManager*			ConfigManager		= nullptr;
	IResourceManager*		ResourceManager		= nullptr;
	IPluginManager*			PluginManager		= nullptr;

	IUIManager*				UIManager			= nullptr;
};

interface IPlugin
{
	enum emPluginEvent {
		emEventLanguageChange = 1,
	};

	typedef LANGID EventContextLanguageChange;

	virtual String			GetName				(void) = 0;
	virtual	String			GetDescription		(void) = 0;
	virtual String			GetAuthor			(void) = 0;

	virtual void			Initialize			(PluginContext* Context) = 0;
	virtual void			Release				(void) = 0;

	virtual void			OnEvent				(emPluginEvent Event, PVOID Context)	{}
	virtual IConfigurable*	GetConfigurable		(void)							{ return nullptr; }

	virtual ULONG			GetColumnCount		(void)							{ return 0; }
	virtual IMessageColumn*	GetColumn			(ULONG Index)					{ return nullptr; }
	virtual ULONG			GetMatcherCount		(void)							{ return 0; }
	virtual IMessageMatcher* GetMatcher			(ULONG Index)					{ return nullptr; }
	virtual ULONG			GetRequireEventCount(void)							{ return 0; }
	virtual ULONG			GetRequireEvent		(ULONG Index)					{ return 0; }

	virtual IUIExtension*	GetUIExtension		(void)							{ return nullptr; }
};

接口说明

函数说明
Initialize插件的初始化,可以获取并保存PluginContext,用于后续获取各种能力
OnEvent事件通知:目前只有一个语言切换的事件,后续根据需要会添加更多的事件通知。
GetColumnCount提供扩展列的个数
GetColumn获取提供扩展列的接口
GetMatcherCount提供自定义匹配规则的个数
GetMatcher获取提供自定义匹配规则的接口
GetRequireEventCount需要订阅的事件个数(为了优化性能,按需订阅)
GetRequireEvent获取需要订阅的事件
GetUIExtension获取提供UI扩展接口

插件示例一(添加IP地址归属地信息)

cxMessageColumnRemoteIPRegion::cxMessageColumnRemoteIPRegion(void)
	: cxMessageColumnBase(_T("RemoteIPRegion"), _T("Parse socket remote ip address region"), 200)
{
}

String cxMessageColumnRemoteIPRegion::GetString(IMessage* Message)
{
	switch (Message->GetType()) {
	case emMSGSocketPostConnect:
	case emMSGSocketSend:
	case emMSGSocketSendTo:
	case emMSGSocketPostRecv:
	case emMSGSocketPostRecvFrom:
	case emMSGSocketPostAccept:
		return g_IPRegion->GetIPRegion(Message->GetULONG(proto::SocketSend::emFieldIP));

	case emMSGHTTPRequest:
		return g_IPRegion->GetIPRegion(Message->GetULONG(proto::HTTPRequest::emFieldIP));

	default:
		break;
	}

	return String();
}

插件示例二(添加判断是否文档路径的匹配器)

bool cxMessageFileInfoDocumentMatcher::IsMatch(IMessage* Message)
{
	auto path = Message->GetPath();
	CString ext = PathFindExtension(path);
	ext.MakeLower();

	static LPCTSTR document_exts[] = {
		_T(".txt"),
		_T(".doc"),
		_T(".docx"),
		_T(".ppt"),
		_T(".pptx"),
		_T(".xls"),
		_T(".xlsx"),
		_T(".json"),
		_T(".xml"),
		_T(".db"),
	};

	for (auto& it : document_exts) {
		if (ext == it)
			return true;
	}

	return false;
}

插件示例三(添加右键菜单)

void UIExtension::OnMessageMenu(QMenu* Menu, IMessage* Message, IMessageColumn* Column)
{
	if (!Message)
		return;

	Menu->addSeparator();

	Menu->addAction(tr("New PathInfo Rule"), [Message]() {
		UIPathInfoEditView::Show(QStringFrom(Message->GetPath()));
	});
}

上面示例的全部代码可以通过 https://github.com/wecooperate/iMonitor/tree/main/src/pluginsopen in new window 获取。

插件安装

iMonitor的插件分为两类

  • 系统插件

    跟随安装包安装,在安装目录的plugins目录下面,重新安装后这个目录会被覆盖

  • 用户插件

    用户自己开发的插件,插件目录为 C:\ProgramData\iMonitor\plugins

    如果自己开发了插件,可以放到插件目录,重启后即可加载

插件市场

正在建设中