19 Browser监控项
概述
浏览器监控项允许使用浏览器监控复杂的网站和 Web 应用程序。
目前对浏览器监控项的支持仍处于实验阶段。
浏览器监控项通过执行用户定义的 JavaScript 代码并通过 HTTP/HTTPS 获取数据来收集数据。 此监控项可以模拟与浏览器相关的操作,例如点击、输入文本、浏览网页以及与网站或 Web 应用程序的其他用户交互。
除脚本外,还可以指定可选的参数列表(名称和值的配对)以及超时时间。
该监控项部分实现了 W3C WebDriver 标准,并使用 Selenium Server 或纯 WebDriver(例如 ChromeDriver)作为 Web 测试端点。
要使该监控项正常工作,请在 Zabbix 服务器/proxy 配置文件中设置 WebDriverURL 参数中的端点(如果使用 ChromeDriver,请参见 安全注意事项)。
为获得更好的性能,建议为 Web 测试环境使用专用服务器。
浏览器监控项检查由 Zabbix 服务器或 proxy 浏览器轮询器执行和处理。
如有必要,可以在 Zabbix 服务器/proxy 配置文件的 StartBrowserPollers 参数中调整预派生的浏览器轮询器实例数量。
对于监控复杂的网站和 Web 应用程序,可使用 Website by Browser 模板,它是一个开箱即用模板。
配置
在监控项配置表单的 Type 字段中,选择 Browser,然后填写必填字段。

所有必填输入字段都以红色星号标记。
Browser 监控项需要填写特定信息的字段如下:
| 字段 | 描述 |
|---|---|
| Key | 输入一个唯一的键值,用于标识该监控项。 |
| Parameters | 指定要作为属性和值对传递给脚本的变量。 支持用户宏。要查看支持哪些内置宏,请在支持的宏表中搜索“Browser-type item”。 |
| Script | 在参数字段中单击或单击其旁边的铅笔图标时,会打开模态编辑器,在其中输入 JavaScript 代码。该代码必须提供返回指标值的逻辑。 该代码可以访问所有参数、Zabbix 添加的所有附加 JavaScript 对象以及Browser 监控项 JavaScript 对象。 另请参见:JavaScript 指南。 |
| Timeout | JavaScript 执行超时(1-600 秒;超过该时间将返回错误)。 请注意,根据脚本的不同,触发超时可能需要更长时间。 有关 Timeout 参数的更多信息,请参见监控项通用属性。 |
示例
有关如何使用 Website by Browser 模板设置 Zabbix 来监控网站的示例,请参见使用 Browser 监控项监控网站。
默认脚本
以下脚本:
- 初始化一个浏览器会话。
- 导航到指定的 URL。
- 收集性能条目和会话统计数据,并以 JSON 字符串的形式返回它们。
在脚本字段中,输入以下内容:
var browser = new Browser(Browser.chromeOptions());
try {
browser.navigate("http://example.com");
browser.collectPerfEntries();
}
finally {
return JSON.stringify(browser.getResult());
}
使用自定义 capabilities 初始化浏览器
以下脚本:
- 根据脚本中指定的顺序,基于第一个匹配的可用浏览器初始化浏览器会话。
- 定义浏览器 capabilities,包括页面加载策略以及各浏览器特有的选项,例如 Chrome、Firefox 和 Microsoft Edge 浏览器的无头模式。
在 Script 字段中,输入:
var browser = new Browser({
"capabilities":{
"firstMatch":[
{
"browserName":"chrome",
"pageLoadStrategy":"normal",
"goog:chromeOptions":{
"args":[
"--headless=new"
]
}
},
{
"browserName":"firefox",
"pageLoadStrategy":"normal",
"moz:firefoxOptions":{
"args":[
"--headless"
]
}
},
{
"browserName":"MicrosoftEdge",
"pageLoadStrategy":"normal",
"ms:edgeOptions":{
"args":[
"--headless=new"
]
}
},
{
"browserName":"safari",
"pageLoadStrategy":"normal"
}
]
}
});
使用 GUI 初始化浏览器
默认情况下,浏览器会话(Safari 除外)以无头模式初始化,这意味着不会显示浏览器的图形用户界面(GUI)。
以下脚本会初始化一个启用了 GUI 的浏览器会话。
请注意,如果 WebDriver 无法定位浏览器二进制文件,您可以手动指定其路径。
var opts = Browser.chromeOptions();
opts.capabilities.alwaysMatch['goog:chromeOptions'].args = [];
// To initialize a Firefox session with GUI, uncomment the following lines:
// var opts = Browser.firefoxOptions();
// opts.capabilities.alwaysMatch['moz:firefoxOptions'].binary = 'usr/bin/firefox';
// opts.capabilities.alwaysMatch['moz:firefoxOptions'].args = [];
// To initialize a Microsoft Edge session with GUI, uncomment the following lines:
// var opts = Browser.edgeOptions();
// opts.capabilities.alwaysMatch['ms:edgeOptions'].binary = 'usr/bin/microsoft-edge';
// opts.capabilities.alwaysMatch['ms:edgeOptions'].args = [];
var browser = new Browser(opts);
如果您的测试在远程服务器上运行或在容器中运行,您可以使用虚拟网络计算(VNC)客户端连接到该机器的 VNC 服务器。
这样您就可以远程查看并与浏览器的 GUI 进行交互。
截取屏幕截图
以下脚本:
- 初始化浏览器会话。
- 设置浏览器视口大小以确定屏幕截图大小(作为参数指定,见下文)。
- 导航到某个 URL(作为参数指定,见下文)。
- 收集会话统计信息,截取屏幕截图,并将其添加到已收集的统计信息中。
- 通过捕获错误消息和屏幕截图来处理错误。
- 以 JSON 字符串形式返回收集到的结果。
该脚本还使用来自监控项配置表单的参数:
- webURL - http://example.com
- width - 1920
- height - 1080
在 Script 字段中,输入:
var browser, result;
var browser = new Browser(Browser.chromeOptions());
try {
var params = JSON.parse(value); // 解析包含从 Zabbix 传递参数的 JSON 字符串。
browser.setScreenSize(Number(params.width), Number(params.height))
browser.navigate(params.webURL);
result = browser.getResult();
result.screenshot = browser.getScreenshot();
}
catch (err) {
if (!(err instanceof BrowserError)) {
browser.setError(err.message);
}
result = browser.getResult();
result.error.screenshot = browser.getScreenshot();
}
finally {
return JSON.stringify(result);
}
检查 Zabbix 登录
以下脚本:
- 初始化浏览器会话。
- 导航到某个页面(作为参数指定,见下文)。
- 输入用户名和密码(作为参数指定,见下文)。
- 查找并点击登录按钮。
- 查找并点击注销按钮。
- 在登录前后以及注销后收集性能数据。
- 通过捕获错误消息和屏幕截图来处理错误。
- 将收集到的结果作为 JSON 字符串返回。
该脚本还使用来自监控项配置表单的参数:
- webURL - http://{HOST.CONN}/index.php
- username - {$USERNAME}
- password - {$PASSWORD}
在 Script 字段中,输入:
var browser, result;
browser = new Browser(Browser.chromeOptions());
try {
var params = JSON.parse(value); // Parse the JSON string containing parameters passed from Zabbix.
browser.navigate(params.webURL);
browser.collectPerfEntries("open page");
var el = browser.findElement("xpath", "//input[@id='name']");
if (el === null) {
throw Error("cannot find name input field");
}
el.sendKeys(params.username);
el = browser.findElement("xpath", "//input[@id='password']");
if (el === null) {
throw Error("cannot find password input field");
}
el.sendKeys(params.password);
el = browser.findElement("xpath", "//button[@id='enter']");
if (el === null) {
throw Error("cannot find login button");
}
el.click();
browser.collectPerfEntries("login");
el = browser.findElement("link text", "Sign out");
if (el === null) {
throw Error("cannot find logout button");
}
el.click();
browser.collectPerfEntries("logout");
result = browser.getResult();
}
catch (err) {
if (!(err instanceof BrowserError)) {
browser.setError(err.message);
}
result = browser.getResult();
result.error.screenshot = browser.getScreenshot();
}
finally {
return JSON.stringify(result);
}
查找链接
以下脚本:
- 初始化浏览器会话。
- 定义一个用于从数组中移除重复元素的函数(见步骤 5)。
- 导航到一个页面(作为参数指定,见下文)。
- 查找页面中的链接。
- 移除重复链接以确保其唯一性。
- 仅提取以
"http"开头的链接。 - 将提取的链接格式化为特定结构。
- 通过捕获错误消息和截图来处理错误。
- 以 JSON 字符串形式返回收集到的结果。
该脚本还使用来自监控项配置表单的参数:
- scheme - {$WEBSITE.SCHEME}
- domain - {$WEBSITE.DOMAIN}
- path - {$WEBSITE.PATH}
在 Script 字段中,输入:
var browser, result;
browser = new Browser(Browser.chromeOptions());
try {
var params = JSON.parse(value); // Parse the JSON string containing parameters passed from Zabbix.
function uniq(a) {
return a.sort().filter(function (item, pos, ary) {
return !pos || item != ary[pos - 1];
});
}
browser.navigate(params.scheme + '://' + params.domain + params.path);
var el = browser.findElements("link text", "");
var links = [];
for (var n = 0; n < el.length; n++) {
links.push(el[n].getAttribute('href'));
}
links = uniq(links);
result = [];
for (i = 0; i < links.length; i++) {
if (links[i].match(/^http.*/)) {
var row = {};
row["{#URL}"] = links[i];
result.push(row);
}
}
}
catch (err) {
if (!(err instanceof BrowserError)) {
browser.setError(err.message);
}
result = browser.getResult();
result.error.screenshot = browser.getScreenshot();
}
finally {
return JSON.stringify(result);
}