无需修改Zabbix源代码,即可通过添加第三方模块或开发自定义模块来增强Zabbix前端功能。
请注意模块代码将run与Zabbix源代码相同的权限。这意味着:
请务必阅读特定模块的安装手册。 建议逐个安装新模块以便轻松捕获故障。
在安装模块前请注意:
确保从可信来源下载模块。 安装有害代码可能导致数据丢失等后果
相同模块的不同版本(相同ID)可以安装在
parallel, but only a single version can be enabled at once
模块安装步骤:
modules
文件夹内的独立目录中故障排除:
问题 | 解决方案 |
---|---|
模块未出现在列表中 | 确保Zabbix前端的modules/your-module/ 目录中存在manifest.json文件file。若存在则表示模块不兼容当前Zabbixversion。若manifest.jsonfile不存在,可能是解压到了错误目录。 |
前端崩溃 | 模块代码与当前Zabbixversion或服务器配置不兼容。请delete模块文件并重新加载前端。您将看到某些模块缺失的提示。访问模块再次点击扫描目录以从数据库中移除不存在的模块。 |
出现关于重复命名空间、ID或操作的错误消息 | 新模块尝试注册的命名空间、ID或操作已被其他启用模块占用。根据错误提示先禁用冲突模块再启用新模块。 |
出现技术错误消息 | 将错误报告给模块开发者。 |
模块采用PHP语言编写。推荐使用模型-视图-控制器(MVC)软件设计模式,这与Zabbix前端架构一致,能简化开发流程。虽然不强制要求,但建议启用PHP严格类型模式。
请注意,通过模块可以轻松为Zabbix前端添加新菜单监控项及对应的视图和操作。但目前无法通过模块注册新的API或create新的数据库表。
每个模块都是一个目录(位于modules
目录内), 其中包含控制器、视图及其他代码的子目录:
example_module_directory/ (required)
manifest.json (required) Metadata and action definition.
Module.php Module initialization and event handling.
actions/ Action controller files.
SomethingView.php
SomethingCreate.php
SomethingDelete.php
data_export/
ExportAsXml.php
ExportAsExcel.php
views/ View files.
example.something.view.php
example.something.delete.php
js/ JavaScript files used in views.
example.something.view.js.php
partials/ View partial files.
example.something.reusable.php
js/ JavaScript files used in partials.
example.something.reusable.js.php
如你所见,自定义模块目录中唯一必需的file是 manifest.json
。若缺少此file,模块将无法注册。 Module.php
负责注册菜单监控项并处理诸如'onBeforeAction' 和'onTerminate'等事件。actions、views及partials目录包含 模块操作所需的PHP和JavaScript代码。
在create模块之前,必须就不同模块监控项(如目录和文件)的命名规范达成一致,以便保持组织有序。您也可以在模块结构章节中找到相关示例。
监控项 | 命名规则 | 示例 |
---|---|---|
模块目录 | 小写字母[a-z]、下划线和数字 | example_v2 |
操作子目录 | 小写字母[a-z]和下划线字符 | data_export |
操作文件 | 驼峰命名法,以操作类型结尾 | SomethingView.php |
视图和局部文件 | 小写字母[a-z] 单词间用点号分隔 以 module. 前缀开头后接模块名称以操作类型和.phpfile扩展名结尾 |
module.example.something.view.php |
Javascript文件 | 适用与视图和局部文件相同的规则,但扩展名为.js.phpfile。 | module.example.something.view.js.php |
请注意,对于视图和局部file名称,'模块'前缀和名称包含是强制要求的,除非您需要覆盖Zabbix核心视图或局部文件。但此规则不适用于操作file名称。
每个模块都应包含一个manifest.json file文件,其中需以JSON格式声明以下字段:
参数 | 必填 | 类型 | 默认值 | 描述 |
---|---|---|---|---|
manifest_version | 是 | Double | - | 模块清单version。当前支持的version为1。 |
id | 是 | String | - | 模块ID。同一时间只能启用一个具有相同ID的模块。 |
name | 是 | String | - | 在管理界面显示的模块名称。 |
version | 是 | String | - | 在管理界面显示的模块version。 |
namespace | 是 | String | - | Module.php及动作类使用的PHP命名空间。 |
author | 否 | String | "" | 在管理界面显示的模块作者。 |
url | 否 | String | "" | 在管理界面显示的模块URL。 |
description | 否 | String | "" | 在管理界面显示的模块描述。 |
actions | 否 | Object | {} | 需通过该模块注册的动作。参见Actions章节。 |
config | 否 | Object | {} | 模块配置项。 |
具体示例可参阅参考章节中的manifest.json范例。
该模块将控制manifest.jsonfile中actionsobject定义的前端操作。通过这种方式定义新操作。同样地,您可以重定义现有操作。actions的每个键应表示操作名称,对应的值应包含class
,并可选择性地包含layout
和view
键。
一个操作由四个部分组成:名称、控制器、视图和布局。数据验证和准备通常在控制器中完成,输出格式化在视图或部分视图中完成,布局负责用菜单、页眉、页脚等元素装饰页面。
模块操作必须在manifest.jsonfile中定义为actionsobject:
参数 | 必填 | 类型 | 默认值 | 描述 |
---|---|---|---|---|
key | 是 | String | - | 操作名称,小写字母[a-z],用点分隔单词。 |
class | 是 | String | - | 操作类名,包括actions 目录内的子目录路径(如果使用)。 |
layout | 否 | String | "layout.htmlpage" | 操作布局。 |
view | 否 | String | null | 操作视图。 |
有几种预定义的布局,如layout.json
或layout.xml
。这些适用于产生不同于HTML结果的操作。您可以在app/views/目录中探索预定义的布局,甚至可以create自己的布局。
有时只需要重定义某些操作的视图部分,而保持控制器不变。在这种情况下,只需将必要的视图和/或部分文件放在模块的views
目录中。
作为参考,请参阅参考部分中的示例操作控制器file。请不要犹豫探索Zabbix源代码中位于app/目录下的当前操作。
Module.php
这个可选的PHPfile负责模块初始化以及事件处理。类'模块'应在此file中定义,扩展基类\Core\CModule
。Module类必须在manifest.jsonfile中指定的命名空间中定义。
<?php
namespace Modules\Example;
use Core\CModule as BaseModule;
class Module extends BaseModule {
...
}
作为参考,请参阅参考部分中的Module.php示例。
本节包含前文介绍的不同模块元素的基础版本
manifest.json
{
"manifest_version": 1.0,
"id": "example_module",
"name": "Example module",
"version": "1.0",
"namespace": "Example",
"author": "John Smith",
"url": "http://module.example.com",
"description": "Short description of the module.",
"actions": {
"example.something.view": {
"class": "SomethingView",
"view": "module.example.something.view"
},
"example.something.create": {
"class": "SomethingCreate",
"layout": null
},
"example.something.delete": {
"class": "SomethingDelete",
"layout": null
},
"example.something.export.xml": {
"class": "data_export/ExportAsXml",
"layout": null
},
"example.something.export.excel": {
"class": "data_export/ExportAsExcel",
"layout": null
}
},
"config": {
"username": "john_smith"
}
}
Module.php
<?php declare(strict_types = 1);
namespace Modules\Example;
use APP;
use CController as CAction;
/**
* Please see Core\CModule class for additional reference.
*/
class Module extends \Core\CModule {
/**
* Initialize module.
*/
public function init(): void {
// Initialize main menu (CMenu class instance).
APP::Component()->get('menu.main')
->findOrAdd(_('Reports'))
->getSubmenu()
->add((new \CMenuItem(_('Example wide report')))
->setAction('example.report.wide.php')
)
->add((new \CMenuItem(_('Example narrow report')))
->setAction('example.report.narrow.php')
);
}
/**
* Event handler, triggered before executing the action.
*
* @param CAction $action Action instance responsible for current request.
*/
public function onBeforeAction(CAction $action): void {
}
/**
* Event handler, triggered on application exit.
*
* @param CAction $action Action instance responsible for current request.
*/
public function onTerminate(CAction $action): void {
}
}
动作控制器
<?php declare(strict_types = 1);
namespace Modules\Example\Actions;
use CControllerResponseData;
use CControllerResponseFatal;
use CController as CAction;
/**
* Example module action.
*/
class SomethingView extends CAction {
/**
* Initialize action. Method called by Zabbix core.
*
* @return void
*/
public function init(): void {
/**
* Disable SID (Session ID) validation. Session ID validation should only be used for actions which involve data
* modification, such as update or delete actions. In such case Session ID must be presented in the URL, so that
* the URL would expire as soon as the session expired.
*/
$this->disableSIDvalidation();
}
/**
* Check and sanitize user input parameters. Method called by Zabbix core. Execution stops if false is returned.
*
* @return bool true on success, false on error.
*/
protected function checkInput(): bool {
$fields = [
'name' => 'required|string',
'email' => 'required|string',
'phone' => 'string'
];
// Only validated data will further be available using $this->hasInput() and $this->getInput().
$ret = $this->validateInput($fields);
if (!$ret) {
$this->setResponse(new CControllerResponseFatal());
}
return $ret;
}
/**
* Check if the user has permission to execute this action. Method called by Zabbix core.
* Execution stops if false is returned.
*
* @return bool
*/
protected function checkPermissions(): bool {
$permit_user_types = [USER_TYPE_ZABBIX_ADMIN, USER_TYPE_SUPER_ADMIN];
return in_array($this->getUserType(), $permit_user_types);
}
/**
* Prepare the response object for the view. Method called by Zabbix core.
*
* @return void
*/
protected function doAction(): void {
$contacts = $this->getInput('email');
if ($this->hasInput('phone')) {
$contacts .= ', '.$this->getInput('phone');
}
$data = [
'name' => $this->getInput('name'),
'contacts' => $contacts
];
$response = new CControllerResponseData($data);
$this->setResponse($response);
}
}
动作视图
<?php declare(strict_types = 1);
/**
* @var CView $this
*/
$this->includeJsFile('example.something.view.js.php');
(new CWidget())
->setTitle(_('Something view'))
->addItem(new CDiv($data['name']))
->addItem(new CPartial('module.example.something.reusable', [
'contacts' => $data['contacts']
])
->show();