资源描述
Cacti插件开发介绍
福州中心支行
第一部分 插件架构介绍 2
一、什么是插件架构 2
二、如何使用插件 2
1.配置插件管理权限 2
2.安装插件 3
3.添加插件使用权限 4
4.卸载插件 5
第二部分 插件开发入门 6
一、什么是“钩子” 6
二、插件的基本结构 7
1.目录结构 7
2.基本函数 7
3.注册API函数 8
三、插件功能开发 8
1.添加安装方法(setup.php) 9
2.设计配置页(setup.php) 9
3.添加插件菜单入口(setup.php) 10
4.添加导航条(setup.php) 11
5.数据库表修改(setup.php) 12
6.增强信息表单设置(setup.php) 14
7.保存增强信息(setup.php) 15
8.在host状态图页面展示数据(setup.php) 16
9.增强信息列表页面(cbEnhancedInfo_listInformatio.php) 18
10增强信息添加页面(cbEnhancedInfo_addInformation.php) 21
四、插件开发总结 24
第三部分 附录 24
第一部分 插件架构介绍
Cacti做为流行的网络监控系统,提供有自己的一套插件体系,叫做插件架构(Plugin Architecture,简称PIA)。基于该插件架构,通过安装开发新插件,可以按照定制需要,增强cacti的功能。
一、什么是插件架构
插件架构提供了一个开源平台,使得开发者可以在不触及Cacti核心代码的前提下,调用Cacti提供的方法,接入Cacti数据,完成开发者想要实现的Cacti不具备的功能。由于插件不涉及Cacti内核,所以Cacti的核心升级,并不会影响到已开发的插件。
Cacti插件可以实现以下五个方面的功能:
1.增强用户交互界面
2.访问Cacti数据库
3.管理RRD文件数据
4.提高Cacti性能,使Cacti适用于大规模应用部署
5.添加新功能,如门限控制,系统日志等。
目前,Cacti论坛(
1. MAC Track plugin
该插件通过IP和MAC地址,来协助定位网络攻击源,如定位病毒来源。插件细节说明参见:
2. Network WeatherMap
该插件用于创建网络拓扑图,可以展现数据中心的网络架构并展示网络性能和优化效果。该插件细节说明参见:
3.Thold
Thold用于添加门限控制及门限告警。所有的RRD文件数据都能设置固定或动态计算的门限值。通过配置Thold参数,可以使用Email告警通知,该告警邮件可发给多个收件人。插件细节说明参见:
其他插件说明可参见:
二、如何使用插件
从0.8.8版本开始,Cacti安装包中已经自带PIA,所以可免去PIA安装。要安装插件,首先需要有一个可以管理插件的账户。
1.配置插件管理权限
首先,以管理员身份登陆Cacti,进入“Utility”下的“User Management”;
然后,选择需要授权的账户,在“Real Permission”标签页下,能够看到以下内容:
点选“Plugin Management”,点击“Save”,配置完成。
之后用刚刚授权的账户登录Cacti,可以看到“Confguraton”项目中增加了“Plugin Management”菜单项,点击该菜单项,即进入插件管理页。如果未安装插件,页面会提示如下:
2.安装插件
此部分以Setting插件的安装举例说明。Setting插件是用于发送邮件和查找DNS的。
首先,登陆到Cacti所在机器,进入插件目录:
cd /var/www/html/cacti/plugins
第二,下载Setting插件:
wget -O settings-v0.7-1.tgz
plugin%3Asettings&cache=cache
第三,解压压缩包:
tar -xzvf settings-v0.7-1.tgz
第四,使用以授权插件管理的账户登陆Cacti页面,进入“Confguraton”的“Plugin Management”页面。此时能看到如下列表:
第五,点击蓝色箭头图标,安装插件,可看到蓝色箭头图标消失,变为如下两个图标:
第六,点击绿色箭头图标,运行插件,图标变为如下情况:
第七,进入“Confguraton”的“Setting”页面,可以看到一个新的选项卡“Mail / DNS”,这是Setting插件的设置选项标签。
第八,设置配置参数,即完成Setting插件的安装。
3.添加插件使用权限
首先,以管理员身份登陆Cacti,进入“Utility”下的“User Management”;
然后,选择需要授权的账户,在“Real Permission”标签页下,能够看到以下内容:
点选“Send Test Email”,保存,即完成插件使用权限配置。
4.卸载插件
还是以Setting插件为例。
首先,以插件管理账户登录Cacti,进入“Confguraton”的“Plugin Management”页面。此时能看到如下列表:
第二,点击红色开关按钮,停止Setting插件,图标变化为如下情况:
第三,点击紫色向上箭头图标,卸载插件,图标变化为如下情况:
第四,登陆Cacti所在机器,进入插件目录:
cd /var/www/html/cacti/plugins
第五,删除Setting插件文件,完成卸载。
rm –rf settings
注意,当插件被卸载时,插件安装是创建的所有数据库表及字段都将被删除,请小心保存之前的插件数据。
第二部分 插件开发入门
本部分先介绍“钩子”的概念,再通过cbEnhancedInfo插件的编写实例,介绍Cacti插件的开发。
一、什么是“钩子”
“钩子”在Cacti的英文文档中,叫做hook,是专用于Cacti插件的接口,它提供了以下三种功能:
1.显示添加的数据
2.为Cacti内核添加功能
3.管理图和数据
钩子其实就相当于PC兼容机的各种接口,我们的插件就相当于要加载到兼容机上的硬件。比如我们给兼容机加一个光驱,至少需要两个接口,一个电源接口,一个数据接口,这就相当于需要使用cacti提供的两个钩子。光驱为了能够兼容和使用这些接口,就需要在设计时,按照接口的规则协议去实现。我们的Cacti插件也是这样,需要按照PIA设定的钩子去设计对应的钩子函数,并使用PIA提供的一些方法,以完成一个能够在Cacti上使用的插件。
正如兼容机上的接口可以分为电源接口,SATA数据接口,内存插槽接口等等,PIA的hook也按照功能来分类,此处介绍几个在后面内容会使用到的hook。
1. tree_after
该hook可以在tree view页面的尾部,添加用户自定义信息,比如在主机状态图页面增加主机信息显示等。
2. draw_navigation_text
该hook用于增加页面导航信息,可以在导航条上显示当前页面的名称和层次结构。
3. confg_arrays
该hook用于在控制台(console)菜单页面添加新的菜单入口。比如给插件添加数据管理入口等。
4. confg_settings
该hook用于创建插件的配置项页面。
5. confg_form
该hook可以给Cacti核心表单添加字段,比如给host表单添加host信息字段。
6. api_device_save
该hook可以修改设备数据库表的内容,添加自定义字段等。
7. top_header_tabs
该hook可以重写top_header.php文件。
8. top_graph_header_tabs
该hook用于在Cacti用户界面添加标签tab的入口。
更多hook功能介绍,请参见:
二、插件的基本结构
由于Cacti是基于php开发的,其提供的接口和PIA也是面向php的,所以我们以下介绍的所有设计内容都是基于php语言的。
1.目录结构
所有插件都放置在插件目录/var/www/html/cacti/plugins以下,每个插件占有/plugins下的一个唯一名称子目录,目录名称建议使用插件名称命名,插件名称只能使用小写字母和数字,比如对于名称为“cbEnhancedInfo”的插件,其目录为“/plugins/cbEnhancedInfo/”。
每个插件的根目录下,必须有“setup.php”文件,Cacti通过检测该文件,识别插件,该文件用于安装插件,文件内只能有函数,不能有非函数代码。
2.基本函数
以下介绍安装使用插件必须的基本函数,这些基本函数都位于setup.php文件内,不需要配合钩子使用。建议将函数名称中的“PLUGINNAME”替换为待开发的插件名称。
a.plugin_PLUGINNAME_install
该函数不带参数。当安装插件时,该函数会被调用,以执行其中的安装代码。一般会在其中添加注册方法和修改数据库的代码。
b. plugin_PLUGINNAME_uninstall
该函数不带参数。当卸载插件时,该函数会被调用,一般用于清理插件无法自动清除的数据。如果安装时使用API函数来创建修改表格,则当卸载时,这些变动会自动被清理还原。
c. plugin_PLUGINNAME_version
该函数不带参数,是用于查看插件版本的。举例如下:
function plugin_PLUGINNAME_version () {
return array( 'name' => 'PLUGINNAME',
'version' => '1.0',
'longname' => 'Plugin Name',
'author' => 'My Name',
'homepage' => '',
'email' => 'me@',
'url' => '
);
}
每次更新版本,只要修改array中的对应参数即可。
d. plugin_PLUGINNAME_check_config
该函数不带参数,用于检测插件是否可以启用。插件安装好后,默认是停用的。此时,只有几个必要钩子函数可以使用(比如config_settings和config_arrays)。如此,保证了用户在插件停用状态下,也能够修改插件的配置,当确认所有配置都正确了,再去启动插件。只要满足正常启动的前提条件,该函数就能返回true,否则返回false。举例如下:
function plugin_PLUGINNAME_check_config () {
if (read_config_option('PLUGINNAME_SETTING') != '') {
return true;
}
return false;
}
3.注册API函数
钩子函数在使用之前,需要先注册到指定的钩子上。钩子函数注册方法如下:
api_plugin_register_hook('PLUGINNAME', 'HOOKNAME', 'CALLBACKFUNCTION', 'FILENAME');
其四个参数依次表示插件名称,钩子名称,钩子函数名称,钩子函数所在文件名。
对于需要权限控制的模块,需要使用权限领域注册方法,将一些文件的访问注册成一个可以控制权限的领域。权限领域注册方法如下:
api_plugin_register_realm('PLUGINNAME', 'FILENAMETORESTRICT', 'DISPLAYTEXT', 1);
其四个参数依次表示插件名称,文件名称(对于多个文件可使用逗号隔开),领域名称,是否对“admin”账户自动授权(1表示true,0表示false)。
对于以上两种注册API函数,举例如下:
function plugin_PLUGINNAME_install () {
api_plugin_register_hook('PLUGINNAME', 'top_header_tabs', 'PLUGINNAME_show_tab', 'setup.php');
api_plugin_register_realm('PLUGINNAME', 'PLUGINNAME.php,', 'View PLUGINNAME', 1);
}
function PLUGINNAME_show_tab () {
global $config;
print '<a href="' . $config['url_path'] . 'plugins/PLUGINNAME/PLUGINNAME.php"><img src="' . $config['url_path'] . 'plugins/PLUGINNAME/images/tab.gif" align="absmiddle" border="0"></a>';
}
例子中,首先注册了一个top_header_tabs的方法,用于重写top_header.php文件;然后注册了一个权限领域,用于控制对PLUGINNAME.php文件的访问。
三、插件功能开发
本部分通过解析cbEnhancedInfo的代码,介绍插件的各个功能模块的设计方法。cbEnhancedInfo插件的功能是增加主机信息,并管理这些增加的信息。
从使用者角度看,cbEnhancedInfo需要满足以下要求:
a.显示主机名和IP
b.显示国家,站点,机房信息
c.显示email等联系方式
d.记录经纬度
e.可添加文本说明
从开发者角度看,cbEnhancedInfo需要添加以下功能:
a.给Cacti提供的主机信息添加扩展字段或者添加独立的信息表格,用于记录其他信息
b.能够配置cbEnhancedInfo插件,并进行权限管理。
以下用压缩的代码按开发步骤解析各个模块的设计,详细代码见附录。
1.添加安装方法(setup.php)
function plugin_cbEnhancedInfo_install () {
// 注册钩子函数
api_plugin_register_hook('cbEnhancedInfo',
'draw_navigation_text',
'cbEnhancedInfo_draw_navigation_text',
'setup.php');
/* 省略其他钩子函数注册方法 */
// 注册权限领域
api_plugin_register_realm('cbEnhancedInfo',
'cbEnhancedInfo_listInformation.php,cbEnhancedInfo_addInformation.php',
'Plugin - cbEnhancedInfo - Add Information',
2702);
/* 省略其他权限领域注册方法 */
// 数据表创建修改操作
cbEnhancedInfo_setup_table_new ();
}
该安装方法分三个部分,注册了钩子函数,权限领域,并初始化了插件启动需要的数据库表结构。
2.设计配置页(setup.php)
首先在plugin_cbEnhancedInfo_install函数中注册配置函数,即添加以下代码:
api_plugin_register_hook('cbEnhancedInfo',
'config_settings',
'cbEnhancedInfo_config_settings',
'setup.php');
然后在setup.php中添加配置函数,其内容如下:
function cbEnhancedInfo_config_settings () {
global $tabs, $settings;
$tabs["misc"] = "Misc"; // 在插件设置页面中添加本插件的设置选项卡
// 设置选项卡内容
$temp = array(
// 标题栏
"cbEnhancedInfo_header" => array(
"friendly_name" => "cbEnhancedInfo Plugin",
"method" => "spacer",
),
// 信息显示配置项
"cbEnhancedInfo_showInfo" => array(
"friendly_name" => "Display enhanced information a the tree view",
"description" => "This will display enhanced information after the tree view graph.",
"method" => "checkbox",
"max_length" => "255"
),
);
// 添加选项卡
if (isset($settings["misc"]))
$settings["misc"] = array_merge($settings["misc"], $temp);
else
$settings["misc"] = $temp;
}
该函数使用了两个全局变量,$tabs和$settings。$tabs用于添加选项卡,$settings用于保存当前配置数据。该函数会在“Configuration”下的“Setting”配置页中,添加名为“Misc”的选项卡,该选项卡用于配置cbEnhancedInfo插件。 “Misc”选项卡如下:
从上图可以直观看出,cbEnhancedInfo_config_settings在该选项卡上添加了名为“cbEnhancedInfo Plugin”的标题,并添加了一个是否显示增强信息的复选框,这些添加内容对应了函数中部的array数组。函数最后的添加选项卡代码,检测是否存在misc选项卡,如果存在,则将新旧选项卡合并。Cacti需要保证配置选项卡名字的唯一性,如果之前已有插件使用了名为“Misc”的配置选项,那么请修改为其他名称,如“Misc_En”等。
3.添加插件菜单入口(setup.php)
首先在plugin_cbEnhancedInfo_install函数中注册入口函数,即添加以下代码:
api_plugin_register_hook('cbEnhancedInfo',
'config_arrays',
'cbEnhancedInfo_config_arrays',
'setup.php');
然后在setup.php中添加入口函数,其内容如下:
function cbEnhancedInfo_config_arrays () {
global $menu;
// 菜单内容
$temp = array(
"plugins/cbEnhancedInfo/cbEnhancedInfo_listInformation.php" => "Enhanced Info"
);
// 添加菜单
if (isset($menu["cbPlugins"]))
$menu["cbPlugins"] = array_merge($temp, $menu["cbPlugins"]);
else
$menu["cbPlugins"] = $temp;
}
该函数使用了全局变量$menu,其保存了菜单信息。该函数以array为单位添加入口链接对,函数中检查了cbPlugins菜单是否存在,如存在,则合并新旧cbPlugins菜单,如不存在,则添加新菜单。添加后的菜单如下:
4.添加导航条(setup.php)
首先在plugin_cbEnhancedInfo_install函数中注册导航条绘制函数,即添加以下代码:
api_plugin_register_hook('cbEnhancedInfo',
'draw_navigation_text',
'cbEnhancedInfo_draw_navigation_text',
'setup.php');
然后在setup.php中添加导航条绘制函数,其内容如下:
function cbEnhancedInfo_draw_navigation_text ( $nav ) {
// 展示信息的导航内容
$nav["cbEnhancedInfo_listInformation.php:"] = array(
"title" => "Enhanced Information List",
"mapping" => "index.php:",
"url" => "cbEnhancedInfo_listInformation.php",
"level" => "1"
);
// 添加信息的导航内容
$nav["cbEnhancedInfo_addInformation.php:add"] = array(
"title" => "(Add)",
"mapping" => "index.php:,?",
"url" => "cbEnhancedInfo_addInformation",
"level" => "2"
);
// 修改信息的导航内容
$nav["cbEnhancedInfo_addInformation.php:update"] = array(
"title" => "(Edit)",
"mapping" => "index.php:,?",
"url" => "cbEnhancedInfo_addInformation.php",
"level" => "2"
);
return $nav;
}
函数中,三次使用了$nav变量。第一次用于添加展示信息入口,另外两次用于添加修改信息的入口。每组入口array中最重要的信息是title和level。title表示在导航条上显示的内容,level表示显示的内容的级别位置。如下便是各级别显示位置:
Home | Level 1 | Level 2 | Level 3
5.数据库表修改(setup.php)
数据库表修改函数是在install函数中调用的,其内容如下:
function cbEnhancedInfo_setup_table_new () {
global $config, $database_default;
include_once($config["library_path"] . "/database.php");
// 用于检测即将添加的cbEnhancedInfo 表是否已经存在
$s_sql = 'show tables from `' . $database_default . '`';
$result = db_fetch_assoc( $s_sql ) or die ( mysql_error() );
$a_tables = array();
// 获得所有表格名称
foreach($result as $index => $array) {
foreach($array as $table) {
$a_tables[] = $table;
}
}
// 给系统自带的host表添加字段
api_plugin_db_add_column ('cbEnhancedInfo',
'host',
array('name' => 'ebEnhancedInfo_country',
'type' => 'varchar(1024)',
'NULL' => true,
'default' => ''
)
);
/* ebEnhancedInfo_site和ebEnhancedInfo_room字段略 */
if (!in_array('plugin_cbEnhancedInfo_dataTable', $a_tables)) {
// 创建plugin_cbEnhancedInfo_dataTabl表
$data = array();
$data['columns'][] = array('name' => 'Id',
'type' => 'mediumint(25)',
'unsigned' => 'unsigned',
'NULL' => false,
'auto_increment' => true);
$data['columns'][] = array('name' => 'hostId',
'type' => 'mediumint(25)',
'unsigned' => 'unsigned',
'NULL' => false,
'default' => '0');
$data['columns'][] = array('name' => 'longitude',
'type' => 'varchar(1024)',
'NULL' => false);
$data['columns'][] = array('name' => 'latitude',
'type' => 'varchar(1024)',
'NULL' => false);
$data['columns'][] = array('name' => 'contactAddress',
'type' => 'varchar(1024)',
'NULL' => false);
$data['columns'][] = array('name' => 'additionalInformation',
'type' => 'text',
'NULL' => true);
$data['primary'] = 'Id';
$data['keys'][] = array('name' => 'hostId', 'columns' => 'hostId');
$data['type'] = 'MyISAM';
$data['comment'] = 'cbEnhancedInfo Data Table';
// 创建表格
api_plugin_db_table_create ('cbEnhancedInfo', 'plugin_cbEnhancedInfo_dataTable', $data);
}
}
该函数使用了API函数api_plugin_db_add_column来添加数据表字段,使用api_plugin_db_table_create来添加新数据库表。函数先是获取数据库中的所有数据表名称,然后为host表添加新字段,之后判断plugin_cbEnhancedInfo_dataTable表是否存在,如果不存在,则创建新表。
6.增强信息表单设置(setup.php)
首先在plugin_cbEnhancedInfo_install函数中注册表单设置函数,即添加以下代码:
api_plugin_register_hook('cbEnhancedInfo',
'config_form',
'cbEnhancedInfo_config_form',
'setup.php');
然后在setup.php中添加表单设置函数,其内容如下:
function cbEnhancedInfo_config_form() {
global $fields_tree_edit,$fields_host_edit;
$fields_host_edit2 = $fields_host_edit;
$fields_host_edit3 = array();
foreach ($fields_host_edit2 as $f => $a) {
$fields_host_edit3[$f] = $a;
// 找到”disabled”所在位置,在其后添加国家,站点和机房信息
if ($f == 'disabled') {
$fields_host_edit3["ebEnhancedInfo_country"] = array(
"method" => "textbox",
"friendly_name" => "Host Country",
"description" => "The country where this host is situated at.",
"value" => "|arg1:ebEnhancedInfo_country|",
"max_length" => "255",
"form_id" => false
);
$fields_host_edit3["ebEnhancedInfo_site"] = array(
"method" => "textbox",
"friendly_name" => "Host Site",
"description" => "The site where this host is situated at.",
"value" => "|arg1:ebEnhancedInfo_site|",
"max_length" => "255",
"form_id" => false
);
$fields_host_edit3["ebEnhancedInfo_room"] = array(
"method" => "textbox",
"friendly_name" => "Host Room",
"description" => "The room where this host is situated at.",
"value" => "|arg1:ebEnhancedInfo_room|",
"max_length" => "255",
"form_id" => false
);
}
}
$fields_host_edit = $fields_host_edit3;
}
该函数使用了全局变量$fields_host_edit,表示系统自带的host表单的内容。该函数在“Disabled Host”字段之后添加了增加信息,添加后表单内容如下:
7.保存增强信息(setup.php)
本步骤将上一步添加的表单数据保存到系统自带的host数据库表的新字段中。首先在plugin_cbEnhancedInfo_install函数中注册保存设备数据函数,即添加以下代码:
api_plugin_register_hook('cbEnhancedInfo',
'api_device_save',
'cbEnhancedInfo_api_device_save',
'setup.php');
然后在setup.php中添加保存设备数据函数,其内容如下:
function cbEnhancedInfo_api_device_save ($save) {
// 检查是否传递了国家字段
if (isset($_POST['ebEnhancedInfo_country'])) {
// 通过form_input_validate保证数据的有效性
$save["ebEnhancedInfo_country"] = form_input_validate($_POST['ebEnhancedInfo_country'], "ebEnhancedInfo_country", "", true, 255);
} else {
$save['ebEnhancedInfo_country'] = form_input_validate('', "ebEnhancedInfo_country", "", true, 3);
}
/* ebEnhancedInfo_site略 */
/* ebEnhancedInfo_room略 */
return $save;
}
该函数将新增的host字段保存在Cacti自带的数据库表中,即将post的内容经过数据验证,保存在save变量中,之后的数据库保存操作由系统进行。
8.
展开阅读全文